diff --git a/Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp b/Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp index 5eecc02..3f8ce40 100644 --- a/Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/ConceptsTesting.cpp @@ -179,7 +179,7 @@ void TestConcepts() always_check(CSwappable); always_check(CSwappable); always_check(CSwappable); -// always_check(!CSwappable); + always_check(!CSwappable); always_check((CSwappableWith)); diff --git a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp index 5cd928b..06dac7f 100644 --- a/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TypeTraitsTesting.cpp @@ -1,6 +1,7 @@ #include "Testing/TypeTraitsTesting.h" #include "Misc/AssertionMacros.h" #include "TypeTraits/TypeTraits.h" +#include "Templates/Templates.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) @@ -435,6 +436,15 @@ void TestTypeTraits() always_check((TIsSame::Type>::Value)); always_check((TIsSame::Type>::Value)); + // Swappable.h + + always_check(TIsSwappable::Value); + always_check(TIsSwappable::Value); + always_check(TIsSwappable::Value); + always_check(!TIsSwappable::Value); + + always_check((TIsSwappableWith::Value)); + } NAMESPACE_MODULE_END(Utility) diff --git a/Redcraft.Utility/Source/Public/Templates/Utility.h b/Redcraft.Utility/Source/Public/Templates/Utility.h index d3f79a1..24234a7 100644 --- a/Redcraft.Utility/Source/Public/Templates/Utility.h +++ b/Redcraft.Utility/Source/Public/Templates/Utility.h @@ -63,18 +63,20 @@ FORCEINLINE T&& Forward(typename TRemoveReference::Type&& Obj) return (T&&)Obj; } -template -FORCEINLINE void Swap(T& A, T& B) +template requires TIsMoveConstructible::Value && TIsMoveAssignable::Value +constexpr void Swap(T& A, T& B) { T Temp = MoveTemp(A); A = MoveTemp(B); B = MoveTemp(Temp); } -template -FORCEINLINE void Exchange(T& A, T& B) +template requires TIsMoveConstructible::Value && TIsAssignable::Value +constexpr T Exchange(T& A, U&& B) { - Swap(A, B); + T Temp = MoveTemp(A); + A = Forward(B); + return Temp; } template diff --git a/Redcraft.Utility/Source/Public/TypeTraits/SupportedOperations.h b/Redcraft.Utility/Source/Public/TypeTraits/SupportedOperations.h index b7461dd..66459a0 100644 --- a/Redcraft.Utility/Source/Public/TypeTraits/SupportedOperations.h +++ b/Redcraft.Utility/Source/Public/TypeTraits/SupportedOperations.h @@ -23,21 +23,17 @@ template struct TIsTriviallyMoveAssignable : TBoolConstant struct TIsTriviallyDestructible : TBoolConstant> { }; template struct THasVirtualDestructor : TBoolConstant> { }; -//template struct TIsSwappable; //template struct TIsNothrowDefaultConstructible; //template struct TIsNothrowCopyConstructible; //template struct TIsNothrowMoveConstructible; //template struct TIsNothrowCopyAssignable; //template struct TIsNothrowMoveAssignable; -//template struct TIsNothrowSwappable; //template struct TIsNothrowDestructible; template struct TIsAssignable : TBoolConstant> { }; template struct TIsTriviallyAssignable : TBoolConstant> { }; -//template struct TIsSwappableWith; //template struct TIsNothrowAssignable; -//template struct TIsNothrowSwappableWith; template struct TIsConstructible : TBoolConstant> { }; template struct TIsTriviallyConstructible : TBoolConstant> { }; diff --git a/Redcraft.Utility/Source/Public/TypeTraits/Swappable.h b/Redcraft.Utility/Source/Public/TypeTraits/Swappable.h new file mode 100644 index 0000000..d5287d6 --- /dev/null +++ b/Redcraft.Utility/Source/Public/TypeTraits/Swappable.h @@ -0,0 +1,35 @@ +#pragma once + +#include "CoreTypes.h" +#include "Templates/Utility.h" +#include "TypeTraits/HelperClasses.h" + +NAMESPACE_REDCRAFT_BEGIN +NAMESPACE_MODULE_BEGIN(Redcraft) +NAMESPACE_MODULE_BEGIN(Utility) + +NAMESPACE_PRIVATE_BEGIN + +// This is a copy of a declaration to prevent circular references, originally defined in Templates/Utility.h +template requires TIsMoveConstructible::Value&& TIsMoveAssignable::Value +constexpr void Swap(T& A, T& B); + +template +concept CSwappableWith = + requires(T&& A, U&& B) + { + Swap(A, B); + Swap(B, A); + }; + +NAMESPACE_PRIVATE_END + +template struct TIsSwappable : TBoolConstant> { }; +template struct TIsSwappableWith : TBoolConstant> { }; + +//template struct TIsNothrowSwappable; +//template struct TIsNothrowSwappableWith; + +NAMESPACE_MODULE_END(Utility) +NAMESPACE_MODULE_END(Redcraft) +NAMESPACE_REDCRAFT_END diff --git a/Redcraft.Utility/Source/Public/TypeTraits/TypeTraits.h b/Redcraft.Utility/Source/Public/TypeTraits/TypeTraits.h index 7831cde..0c02e41 100644 --- a/Redcraft.Utility/Source/Public/TypeTraits/TypeTraits.h +++ b/Redcraft.Utility/Source/Public/TypeTraits/TypeTraits.h @@ -7,4 +7,5 @@ #include "TypeTraits/TypeProperties.h" #include "TypeTraits/SupportedOperations.h" #include "TypeTraits/Miscellaneous.h" +#include "TypeTraits/Swappable.h" #include "TypeTraits/Common.h"