From b75cb30f4f2f1fb9040e352fff39dfd1cb0967cf Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Mon, 19 Dec 2022 18:00:52 +0800 Subject: [PATCH] refactor(templates): refactor GetTypeHash and Swap to friend --- .../Source/Public/Templates/Any.h | 59 ++++++------------- .../Source/Public/Templates/Function.h | 40 ++++++------- .../Source/Public/Templates/Optional.h | 33 +++++------ .../Public/Templates/ReferenceWrapper.h | 4 +- .../Source/Public/Templates/Tuple.h | 12 ++-- .../Source/Public/Templates/TypeHash.h | 6 -- .../Source/Public/Templates/Utility.h | 16 ++--- .../Source/Public/Templates/Variant.h | 52 +++++++--------- 8 files changed, 86 insertions(+), 136 deletions(-) diff --git a/Redcraft.Utility/Source/Public/Templates/Any.h b/Redcraft.Utility/Source/Public/Templates/Any.h index dfeb5ff..69303ae 100644 --- a/Redcraft.Utility/Source/Public/Templates/Any.h +++ b/Redcraft.Utility/Source/Public/Templates/Any.h @@ -91,7 +91,7 @@ public: EmplaceImpl(Forward(Args)...); } - template requires (!CBaseOf> && !CTInPlaceType> + template requires (!CSameAs> && !CTInPlaceType> && NAMESPACE_PRIVATE::CFAnyPlaceable && CConstructibleFrom, T&&>) FORCEINLINE FAny(T&& InValue) : FAny(InPlaceType>, Forward(InValue)) { } @@ -217,7 +217,7 @@ public: return *this; } - template requires (!CBaseOf> && !CTInPlaceType> + template requires (!CSameAs> && !CTInPlaceType> && NAMESPACE_PRIVATE::CFAnyPlaceable && CConstructibleFrom, T&&>) FORCEINLINE FAny& operator=(T&& InValue) { @@ -236,13 +236,13 @@ public: return *this; } - template requires (!CBaseOf> && NAMESPACE_PRIVATE::CFAnyPlaceable) + template requires (!CSameAs> && NAMESPACE_PRIVATE::CFAnyPlaceable) FORCEINLINE constexpr bool operator==(const T& InValue) const& { return HoldsAlternative() ? GetValue() == InValue : false; } - template requires (!CBaseOf> && NAMESPACE_PRIVATE::CFAnyPlaceable) + template requires (!CSameAs> && NAMESPACE_PRIVATE::CFAnyPlaceable) FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const& { return HoldsAlternative() ? SynthThreeWayCompare(GetValue(), InValue) : partial_ordering::unordered; @@ -289,51 +289,26 @@ public: Invalidate(); } - void Swap(FAny& InValue) + friend void Swap(FAny& A, FAny& B) { - if (!IsValid() && !InValue.IsValid()) return; + if (!A.IsValid() && !B.IsValid()) return; - if (IsValid() && !InValue.IsValid()) + if (A.IsValid() && !B.IsValid()) { - InValue = MoveTemp(*this); - Reset(); - return; + B = MoveTemp(A); + A.Reset(); } - - if (InValue.IsValid() && !IsValid()) + else if (!A.IsValid() && B.IsValid()) { - *this = MoveTemp(InValue); - InValue.Reset(); - return; + A = MoveTemp(B); + B.Reset(); } - - if (GetTypeInfo() == InValue.GetTypeInfo()) + else { - switch (GetRepresentation()) - { - case ERepresentation::Empty: - break; - case ERepresentation::Trivial: - uint8 TempBuffer[sizeof(TrivialStorage.Internal)]; - Memory::Memmove(TempBuffer, TrivialStorage.Internal); - Memory::Memmove(TrivialStorage.Internal, InValue.TrivialStorage.Internal); - Memory::Memmove(InValue.TrivialStorage.Internal, TempBuffer); - break; - case ERepresentation::Small: - SmallStorage.RTTI->SwapObject(&SmallStorage.Internal, &InValue.SmallStorage.Internal); - break; - case ERepresentation::Big: - NAMESPACE_REDCRAFT::Swap(BigStorage.External, InValue.BigStorage.External); - break; - default: check_no_entry(); - } - - return; + FAny Temp = MoveTemp(A); + A = MoveTemp(B); + B = MoveTemp(Temp); } - - FAny Temp = MoveTemp(*this); - *this = MoveTemp(InValue); - InValue = MoveTemp(Temp); } private: @@ -411,7 +386,7 @@ private: { if constexpr (CSwappable) { - NAMESPACE_REDCRAFT::Swap(*reinterpret_cast(A), *reinterpret_cast(B)); + Swap(*reinterpret_cast(A), *reinterpret_cast(B)); } else { diff --git a/Redcraft.Utility/Source/Public/Templates/Function.h b/Redcraft.Utility/Source/Public/Templates/Function.h index 5dfc674..318d4fa 100644 --- a/Redcraft.Utility/Source/Public/Templates/Function.h +++ b/Redcraft.Utility/Source/Public/Templates/Function.h @@ -80,12 +80,6 @@ public: ValuePtr = reinterpret_cast(AddressOf(Args)); Callable = InCallable; } - - FORCEINLINE constexpr void Swap(TFunctionStorage& InValue) - { - NAMESPACE_REDCRAFT::Swap(ValuePtr, InValue.ValuePtr); - NAMESPACE_REDCRAFT::Swap(Callable, InValue.Callable); - } private: @@ -295,27 +289,27 @@ public: } - void Swap(TFunctionStorage& InValue) + friend void Swap(TFunctionStorage& A, TFunctionStorage& B) { - if (!IsValid() && !InValue.IsValid()) return; + if (!A.IsValid() && !B.IsValid()) return; - if (IsValid() && !InValue.IsValid()) + if (A.IsValid() && !B.IsValid()) { - InValue = MoveTemp(*this); - Destroy(); - Invalidate(); + B = MoveTemp(A); + A.Destroy(); + A.Invalidate(); } - else if (InValue.IsValid() && !IsValid()) + else if (!A.IsValid() && B.IsValid()) { - *this = MoveTemp(InValue); - InValue.Destroy(); - InValue.Invalidate(); + A = MoveTemp(B); + B.Destroy(); + B.Invalidate(); } else { - TFunctionStorage Temp = MoveTemp(*this); - *this = MoveTemp(InValue); - InValue = MoveTemp(Temp); + TFunctionStorage Temp = MoveTemp(A); + A = MoveTemp(B); + B = MoveTemp(Temp); } } @@ -487,8 +481,6 @@ public: FORCEINLINE constexpr bool IsValid() const { return Storage.IsValid(); } FORCEINLINE constexpr explicit operator bool() const { return Storage.IsValid(); } - FORCEINLINE constexpr void Swap(TFunctionImpl& InValue) { Storage.Swap(InValue.Storage); } - private: using CallableType = ResultType(*)(uintptr, Ts&&...); @@ -536,6 +528,8 @@ protected: // These functions should not be used by user-defined class return *reinterpret_cast(Storage.GetValuePtr()); } + friend FORCEINLINE constexpr void Swap(TFunctionImpl& A, TFunctionImpl& B) requires (!bIsRef) { Swap(A.Storage, B.Storage); } + }; NAMESPACE_PRIVATE_END @@ -647,6 +641,8 @@ public: FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); } + friend FORCEINLINE constexpr void Swap(TFunction& A, TFunction& B) { Swap(static_cast(A), static_cast(B)); } + }; template @@ -735,6 +731,8 @@ public: FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); } + friend FORCEINLINE constexpr void Swap(TUniqueFunction& A, TUniqueFunction& B) { Swap(static_cast(A), static_cast(B)); } + }; static_assert(sizeof(TFunction) == 64, "The byte size of TFunction is unexpected"); diff --git a/Redcraft.Utility/Source/Public/Templates/Optional.h b/Redcraft.Utility/Source/Public/Templates/Optional.h index f622a80..3217030 100644 --- a/Redcraft.Utility/Source/Public/Templates/Optional.h +++ b/Redcraft.Utility/Source/Public/Templates/Optional.h @@ -57,7 +57,7 @@ public: } template requires (CConstructibleFrom) - && (!CSameAs, FInPlace>) && (!CBaseOf>) + && (!CSameAs, FInPlace>) && (!CSameAs>) FORCEINLINE constexpr explicit (!CConvertibleTo) TOptional(T&& InValue) : TOptional(InPlace, Forward(InValue)) { } @@ -269,32 +269,31 @@ public: } } - FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable) + friend FORCEINLINE constexpr size_t GetTypeHash(const TOptional& A) requires (CHashable) { - if (!IsValid()) return 2824517378; - return NAMESPACE_REDCRAFT::GetTypeHash(GetValue()); + if (!A.IsValid()) return 2824517378; + return GetTypeHash(A.GetValue()); } template requires (CMoveConstructible && CSwappable) - constexpr void Swap(TOptional& InValue) + friend constexpr void Swap(TOptional& A, TOptional& B) { - if (!IsValid() && !InValue.IsValid()) return; + if (!A.IsValid() && !B.IsValid()) return; - if (IsValid() && !InValue.IsValid()) + if (A.IsValid() && !B.IsValid()) { - InValue = MoveTemp(*this); - Reset(); - return; + B = MoveTemp(A); + A.Reset(); } - - if (InValue.IsValid() && !IsValid()) + else if (!A.IsValid() && B.IsValid()) { - *this = MoveTemp(InValue); - InValue.Reset(); - return; + A = MoveTemp(B); + B.Reset(); + } + else + { + Swap(A.GetValue(), B.GetValue()); } - - NAMESPACE_REDCRAFT::Swap(GetValue(), InValue.GetValue()); } private: diff --git a/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h b/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h index 79f155e..59bf693 100644 --- a/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h +++ b/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h @@ -47,9 +47,9 @@ public: return Invoke(Get(), Forward(Args)...); } - FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable) + friend FORCEINLINE constexpr size_t GetTypeHash(TReferenceWrapper A) requires (CHashable) { - return NAMESPACE_REDCRAFT::GetTypeHash(Get()); + return GetTypeHash(A.Get()); } private: diff --git a/Redcraft.Utility/Source/Public/Templates/Tuple.h b/Redcraft.Utility/Source/Public/Templates/Tuple.h index 325a45f..8f97565 100644 --- a/Redcraft.Utility/Source/Public/Templates/Tuple.h +++ b/Redcraft.Utility/Source/Public/Templates/Tuple.h @@ -409,20 +409,20 @@ public: template requires (CConstructibleFrom) FORCEINLINE constexpr T Construct() volatile&& { return Helper::template Construct(static_cast< volatile TTuple&&>(*this)); } template requires (CConstructibleFrom) FORCEINLINE constexpr T Construct() const volatile&& { return Helper::template Construct(static_cast(*this)); } - FORCEINLINE constexpr size_t GetTypeHash() const requires (true && ... && CHashable) + friend FORCEINLINE constexpr size_t GetTypeHash(const TTuple& A) requires (true && ... && CHashable) { - return [this](TIndexSequence) -> size_t + return [&A](TIndexSequence) -> size_t { - return HashCombine(NAMESPACE_REDCRAFT::GetTypeHash(GetValue())...); + return HashCombine(GetTypeHash(A.template GetValue())...); } (TMakeIndexSequence()); } - FORCEINLINE constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible && CSwappable)) + friend FORCEINLINE constexpr void Swap(TTuple& A, TTuple& B) requires (true && ... && (CMoveConstructible && CSwappable)) { - [&A = *this, &B = InValue](TIndexSequence) + [&A, &B](TIndexSequence) { - ((NAMESPACE_REDCRAFT::Swap(A.template GetValue(), B.template GetValue())), ...); + ((Swap(A.template GetValue(), B.template GetValue())), ...); } (TMakeIndexSequence()); } diff --git a/Redcraft.Utility/Source/Public/Templates/TypeHash.h b/Redcraft.Utility/Source/Public/Templates/TypeHash.h index 0f1b8b6..58ce976 100644 --- a/Redcraft.Utility/Source/Public/Templates/TypeHash.h +++ b/Redcraft.Utility/Source/Public/Templates/TypeHash.h @@ -86,12 +86,6 @@ FORCEINLINE constexpr size_t GetTypeHash(T A) return GetTypeHash(reinterpret_cast(A)); } -template requires (requires(const T& A) { { GetTypeHash(A.GetTypeHash()) } -> CSameAs; }) -FORCEINLINE constexpr size_t GetTypeHash(const T& A) -{ - return GetTypeHash(A.GetTypeHash()); -} - template requires (requires(const T& A) { { GetTypeHash(A.hash_code()) } -> CSameAs; }) FORCEINLINE constexpr size_t GetTypeHash(const T& A) { diff --git a/Redcraft.Utility/Source/Public/Templates/Utility.h b/Redcraft.Utility/Source/Public/Templates/Utility.h index 1f6814d..ac63632 100644 --- a/Redcraft.Utility/Source/Public/Templates/Utility.h +++ b/Redcraft.Utility/Source/Public/Templates/Utility.h @@ -55,20 +55,12 @@ FORCEINLINE constexpr T&& Forward(TRemoveReference&& Obj) return static_cast(Obj); } -template requires (requires(T& A, T& B) { A.Swap(B); } - || (CMoveConstructible && CMoveAssignable)) +template requires (CMoveConstructible && CMoveAssignable) FORCEINLINE constexpr void Swap(T& A, T& B) { - if constexpr (requires(T& A, T& B) { A.Swap(B); }) - { - A.Swap(B); - } - else - { - T Temp = MoveTemp(A); - A = MoveTemp(B); - B = MoveTemp(Temp); - } + T Temp = MoveTemp(A); + A = MoveTemp(B); + B = MoveTemp(Temp); } template requires (CMoveConstructible && CAssignableFrom) diff --git a/Redcraft.Utility/Source/Public/Templates/Variant.h b/Redcraft.Utility/Source/Public/Templates/Variant.h index b02a669..5ad8ef3 100644 --- a/Redcraft.Utility/Source/Public/Templates/Variant.h +++ b/Redcraft.Utility/Source/Public/Templates/Variant.h @@ -120,7 +120,7 @@ public: template requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType; } && !CTInPlaceType> && !CTInPlaceIndex> - && !CBaseOf>) + && !CSameAs>) FORCEINLINE constexpr TVariant(T&& InValue) : TVariant(InPlaceType>, Forward(InValue)) { } @@ -217,13 +217,13 @@ public: return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value); } - template requires (!CBaseOf && CEqualityComparable) + template requires (!CSameAs && CEqualityComparable) FORCEINLINE constexpr bool operator==(const T& InValue) const& { return HoldsAlternative() ? GetValue() == InValue : false; } - template requires (!CBaseOf && CEqualityComparable) + template requires (!CSameAs && CEqualityComparable) FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const& { return HoldsAlternative() ? SynthThreeWayCompare(GetValue(), InValue) : partial_ordering::unordered; @@ -287,51 +287,43 @@ public: TypeIndex = static_cast(INDEX_NONE); } - FORCEINLINE constexpr size_t GetTypeHash() const requires (true && ... && CHashable) + friend FORCEINLINE constexpr size_t GetTypeHash(const TVariant& A) requires (true && ... && CHashable) { - if (!IsValid()) return 114514; - - using NAMESPACE_REDCRAFT::GetTypeHash; + if (!A.IsValid()) return 114514; using FHashImpl = size_t(*)(const void*); constexpr FHashImpl HashImpl[] = { [](const void* This) -> size_t { return GetTypeHash(*reinterpret_cast(This)); }... }; - return HashCombine(GetTypeHash(GetIndex()), HashImpl[GetIndex()](&Value)); + return HashCombine(GetTypeHash(A.GetIndex()), HashImpl[A.GetIndex()](&A.Value)); } - constexpr void Swap(TVariant& InValue) requires (true && ... && (CMoveConstructible && CSwappable)) + friend constexpr void Swap(TVariant& A, TVariant& B) requires (true && ... && (CMoveConstructible && CSwappable)) { - if (!IsValid() && !InValue.IsValid()) return; + if (!A.IsValid() && !B.IsValid()) return; - if (IsValid() && !InValue.IsValid()) + if (A.IsValid() && !B.IsValid()) { - InValue = MoveTemp(*this); - Reset(); - return; + B = MoveTemp(A); + A.Reset(); } - - if (InValue.IsValid() && !IsValid()) + else if (!A.IsValid() && B.IsValid()) { - *this = MoveTemp(InValue); - InValue.Reset(); - return; + A = MoveTemp(B); + B.Reset(); } - - if (GetIndex() == InValue.GetIndex()) + else if (A.GetIndex() == B.GetIndex()) { - using NAMESPACE_REDCRAFT::Swap; - using FSwapImpl = void(*)(void*, void*); constexpr FSwapImpl SwapImpl[] = { [](void* A, void* B) { Swap(*reinterpret_cast(A), *reinterpret_cast(B)); }... }; - SwapImpl[GetIndex()](&Value, &InValue.Value); - - return; + SwapImpl[A.GetIndex()](&A.Value, &B.Value); + } + else + { + TVariant Temp = MoveTemp(A); + A = MoveTemp(B); + B = MoveTemp(Temp); } - - TVariant Temp = MoveTemp(*this); - *this = MoveTemp(InValue); - InValue = MoveTemp(Temp); } private: