From af07b1a134c6891a267ad398952be520b734a041 Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Tue, 15 Nov 2022 19:28:43 +0800 Subject: [PATCH] refactor(templates): enhance encapsulation by changing part of the struct to a class --- .../Private/Testing/TemplatesTesting.cpp | 6 +- .../Source/Public/Templates/Any.h | 4 +- .../Source/Public/Templates/Function.h | 160 +++++++++--------- .../Source/Public/Templates/Optional.h | 2 +- .../Public/Templates/ReferenceWrapper.h | 10 +- .../Source/Public/Templates/Tuple.h | 14 +- .../Source/Public/Templates/Variant.h | 6 +- 7 files changed, 104 insertions(+), 98 deletions(-) diff --git a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp index eaa3138..cc7aea0 100644 --- a/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp +++ b/Redcraft.Utility/Source/Private/Testing/TemplatesTesting.cpp @@ -784,10 +784,10 @@ void TestTuple() { int8 Flag; FTracker(int8 InFlag) : Flag(InFlag) { } - FTracker(const FTracker& InValue) { Flag = InValue.Flag - 1; always_check(!Flag); } - FTracker(FTracker&& InValue) { Flag = InValue.Flag + 1; always_check(!Flag); } + FTracker(const FTracker& InValue) { Flag = InValue.Flag - 1; always_check(!Flag); } + FTracker(FTracker&& InValue) { Flag = InValue.Flag + 1; always_check(!Flag); } FTracker& operator=(const FTracker& InValue) { Flag = InValue.Flag - 1; always_check(!Flag); return *this; } - FTracker& operator=(FTracker&& InValue) { Flag = InValue.Flag + 1; always_check(!Flag); return *this; } + FTracker& operator=(FTracker&& InValue) { Flag = InValue.Flag + 1; always_check(!Flag); return *this; } }; { diff --git a/Redcraft.Utility/Source/Public/Templates/Any.h b/Redcraft.Utility/Source/Public/Templates/Any.h index fdaf876..b32cf9a 100644 --- a/Redcraft.Utility/Source/Public/Templates/Any.h +++ b/Redcraft.Utility/Source/Public/Templates/Any.h @@ -72,8 +72,10 @@ static_assert(CAnyCustomStorage); // You can add custom storage area through CustomStorage, such as TFunction. // It is not recommended to use this, FAny is recommended. template -struct TAny +class TAny { +public: + inline static constexpr size_t InlineSize = CustomStorage::InlineSize; inline static constexpr size_t InlineAlignment = CustomStorage::InlineAlignment; diff --git a/Redcraft.Utility/Source/Public/Templates/Function.h b/Redcraft.Utility/Source/Public/Templates/Function.h index 5a8ede5..576776a 100644 --- a/Redcraft.Utility/Source/Public/Templates/Function.h +++ b/Redcraft.Utility/Source/Public/Templates/Function.h @@ -13,14 +13,14 @@ NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) -template requires CFunction -struct TFunctionRef; +template +class TFunctionRef; -template requires CFunction -struct TFunction; +template +class TFunction; -template requires CFunction -struct TUniqueFunction; +template +class TUniqueFunction; NAMESPACE_PRIVATE_BEGIN @@ -80,38 +80,10 @@ template struct TFunctionInfo struct TFunctionInfo { using Fn = Ret(Types...); using CVRef = const int&; }; template struct TFunctionInfo { using Fn = Ret(Types...); using CVRef = const int&&; }; -template -struct alignas(16) FFunctionStorage -{ - //~ Begin CAnyCustomStorage Interface - inline static constexpr size_t InlineSize = 64 - sizeof(uintptr) - sizeof(CallableType); - inline static constexpr size_t InlineAlignment = 16; - constexpr void* InlineAllocation() { return &InlineAllocationImpl; } - constexpr const void* InlineAllocation() const { return &InlineAllocationImpl; } - constexpr void*& HeapAllocation() { return HeapAllocationImpl; } - constexpr void* HeapAllocation() const { return HeapAllocationImpl; } - constexpr uintptr& TypeInfo() { return TypeInfoImpl; } - constexpr uintptr TypeInfo() const { return TypeInfoImpl; } - constexpr void CopyCustom(const FFunctionStorage& InValue) { Callable = InValue.Callable; } - constexpr void MoveCustom( FFunctionStorage&& InValue) { Callable = InValue.Callable; } - //~ End CAnyCustomStorage Interface - - union - { - uint8 InlineAllocationImpl[InlineSize]; - void* HeapAllocationImpl; - }; - - uintptr TypeInfoImpl; - - CallableType Callable; - -}; - -template struct TFunctionImpl; +template class TFunctionImpl; template -struct TFunctionImpl +class TFunctionImpl { public: @@ -175,6 +147,34 @@ private: StoragePtrType Ptr; CallableType Callable; }; + + template + struct alignas(16) FFunctionStorage + { + //~ Begin CAnyCustomStorage Interface + inline static constexpr size_t InlineSize = 64 - sizeof(uintptr) - sizeof(CallableType); + inline static constexpr size_t InlineAlignment = 16; + constexpr void* InlineAllocation() { return &InlineAllocationImpl; } + constexpr const void* InlineAllocation() const { return &InlineAllocationImpl; } + constexpr void*& HeapAllocation() { return HeapAllocationImpl; } + constexpr void* HeapAllocation() const { return HeapAllocationImpl; } + constexpr uintptr& TypeInfo() { return TypeInfoImpl; } + constexpr uintptr TypeInfo() const { return TypeInfoImpl; } + constexpr void CopyCustom(const FFunctionStorage& InValue) { Callable = InValue.Callable; } + constexpr void MoveCustom( FFunctionStorage&& InValue) { Callable = InValue.Callable; } + //~ End CAnyCustomStorage Interface + + union + { + uint8 InlineAllocationImpl[InlineSize]; + void* HeapAllocationImpl; + }; + + uintptr TypeInfoImpl; + + CallableType Callable; + + }; using FunctionStorage = TAny>; using StorageType = TConditional; @@ -207,7 +207,7 @@ private: else return GetCallableImpl()(&Storage, Forward(Args)...); } -protected: +protected: // These functions should not be used by user-defined class. template FORCEINLINE void EmplaceImpl(ArgTypes&&... Args) @@ -257,8 +257,8 @@ protected: NAMESPACE_PRIVATE_END -template requires CFunction -struct TFunctionRef +template +class TFunctionRef : public NAMESPACE_PRIVATE::TFunctionImpl< typename NAMESPACE_PRIVATE::TFunctionInfo::Fn, typename NAMESPACE_PRIVATE::TFunctionInfo::CVRef, @@ -266,7 +266,7 @@ struct TFunctionRef { private: - using Super = NAMESPACE_PRIVATE::TFunctionImpl< + using Impl = NAMESPACE_PRIVATE::TFunctionImpl< typename NAMESPACE_PRIVATE::TFunctionInfo::Fn, typename NAMESPACE_PRIVATE::TFunctionInfo::CVRef, true>; @@ -287,7 +287,7 @@ public: { using DecayedType = TDecay; checkf(NAMESPACE_PRIVATE::FunctionIsBound(InValue), TEXT("Cannot bind a null/unbound callable to a TFunctionRef")); - Super::template EmplaceImpl(Forward(InValue)); + Impl::template EmplaceImpl(Forward(InValue)); } template @@ -295,8 +295,8 @@ public: }; -template requires CFunction -struct TFunction +template +class TFunction : public NAMESPACE_PRIVATE::TFunctionImpl< typename NAMESPACE_PRIVATE::TFunctionInfo::Fn, typename NAMESPACE_PRIVATE::TFunctionInfo::CVRef, @@ -304,28 +304,28 @@ struct TFunction { private: - using Super = NAMESPACE_PRIVATE::TFunctionImpl< + using Impl = NAMESPACE_PRIVATE::TFunctionImpl< typename NAMESPACE_PRIVATE::TFunctionInfo::Fn, typename NAMESPACE_PRIVATE::TFunctionInfo::CVRef, false>; public: - constexpr TFunction(nullptr_t = nullptr) { Super::ResetImpl(); } + constexpr TFunction(nullptr_t = nullptr) { Impl::ResetImpl(); } FORCEINLINE TFunction(const TFunction& InValue) = default; - FORCEINLINE TFunction(TFunction&& InValue) : Super(MoveTemp(InValue)) { InValue.ResetImpl(); } + FORCEINLINE TFunction(TFunction&& InValue) : Impl(MoveTemp(InValue)) { InValue.ResetImpl(); } FORCEINLINE TFunction& operator=(const TFunction& InValue) { - Super::AssignImpl(InValue); + Impl::AssignImpl(InValue); return *this; } FORCEINLINE TFunction& operator=(TFunction&& InValue) { if (&InValue == this) return *this; - Super::AssignImpl(MoveTemp(InValue)); + Impl::AssignImpl(MoveTemp(InValue)); return *this; } @@ -336,8 +336,8 @@ public: FORCEINLINE TFunction(T&& InValue) { using DecayedType = TDecay; - if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Super::ResetImpl(); - else Super::template EmplaceImpl(Forward(InValue)); + if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Impl::ResetImpl(); + else Impl::template EmplaceImpl(Forward(InValue)); } template requires NAMESPACE_PRIVATE::TIsInvocableSignature>::Value @@ -345,10 +345,10 @@ public: FORCEINLINE TFunction(TInPlaceType, ArgTypes&&... Args) { using DecayedType = TDecay; - Super::template EmplaceImpl(Forward(Args)...); + Impl::template EmplaceImpl(Forward(Args)...); } - constexpr TFunction& operator=(nullptr_t) { Super::ResetImpl(); return *this; } + constexpr TFunction& operator=(nullptr_t) { Impl::ResetImpl(); return *this; } template requires NAMESPACE_PRIVATE::TIsInvocableSignature>::Value && (!CTFunctionRef>) && (!CTFunction>) && (!CTUniqueFunction>) @@ -357,8 +357,8 @@ public: { using DecayedType = TDecay; - if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Super::ResetImpl(); - else Super::template EmplaceImpl(Forward(InValue)); + if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Impl::ResetImpl(); + else Impl::template EmplaceImpl(Forward(InValue)); return *this; } @@ -368,62 +368,62 @@ public: FORCEINLINE TDecay& Emplace(ArgTypes&&... Args) { using DecayedType = TDecay; - Super::template EmplaceImpl(Forward(Args)...); - return Super::template Target(); + Impl::template EmplaceImpl(Forward(Args)...); + return Impl::template Target(); } - constexpr void Reset() { Super::ResetImpl(); } + constexpr void Reset() { Impl::ResetImpl(); } }; -template requires CFunction -struct TUniqueFunction +template +class TUniqueFunction : public NAMESPACE_PRIVATE::TFunctionImpl< typename NAMESPACE_PRIVATE::TFunctionInfo::Fn, typename NAMESPACE_PRIVATE::TFunctionInfo::CVRef, - false> + false> { private: - using Super = NAMESPACE_PRIVATE::TFunctionImpl< + using Impl = NAMESPACE_PRIVATE::TFunctionImpl< typename NAMESPACE_PRIVATE::TFunctionInfo::Fn, typename NAMESPACE_PRIVATE::TFunctionInfo::CVRef, false>; public: - constexpr TUniqueFunction(nullptr_t = nullptr) { Super::ResetImpl(); } + constexpr TUniqueFunction(nullptr_t = nullptr) { Impl::ResetImpl(); } FORCEINLINE TUniqueFunction(const TUniqueFunction& InValue) = delete; - TUniqueFunction(TUniqueFunction&& InValue) : Super(MoveTemp(InValue)) { InValue.ResetImpl(); } + TUniqueFunction(TUniqueFunction&& InValue) : Impl(MoveTemp(InValue)) { InValue.ResetImpl(); } FORCEINLINE TUniqueFunction& operator=(const TUniqueFunction& InValue) = delete; FORCEINLINE TUniqueFunction& operator=(TUniqueFunction&& InValue) { if (&InValue == this) return *this; - Super::AssignImpl(MoveTemp(InValue)); + Impl::AssignImpl(MoveTemp(InValue)); return *this; } FORCEINLINE TUniqueFunction(const TFunction& InValue) - : Super(*reinterpret_cast(&InValue)) + : Impl(*reinterpret_cast(&InValue)) { } FORCEINLINE TUniqueFunction(TFunction&& InValue) - : Super(MoveTemp(*reinterpret_cast(&InValue))) + : Impl(MoveTemp(*reinterpret_cast(&InValue))) { InValue.Reset(); } FORCEINLINE TUniqueFunction& operator=(const TFunction& InValue) { - Super::AssignImpl(*reinterpret_cast(&InValue)); + Impl::AssignImpl(*reinterpret_cast(&InValue)); return *this; } FORCEINLINE TUniqueFunction& operator=(TFunction&& InValue) { - Super::AssignImpl(MoveTemp(*reinterpret_cast(&InValue))); + Impl::AssignImpl(MoveTemp(*reinterpret_cast(&InValue))); return *this; } @@ -434,8 +434,8 @@ public: FORCEINLINE TUniqueFunction(T&& InValue) { using DecayedType = TDecay; - if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Super::ResetImpl(); - else Super::template EmplaceImpl(Forward(InValue)); + if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Impl::ResetImpl(); + else Impl::template EmplaceImpl(Forward(InValue)); } template requires NAMESPACE_PRIVATE::TIsInvocableSignature>::Value @@ -443,10 +443,10 @@ public: FORCEINLINE TUniqueFunction(TInPlaceType, ArgTypes&&... Args) { using DecayedType = TDecay; - Super::template EmplaceImpl(Forward(Args)...); + Impl::template EmplaceImpl(Forward(Args)...); } - constexpr TUniqueFunction& operator=(nullptr_t) { Super::ResetImpl(); return *this; } + constexpr TUniqueFunction& operator=(nullptr_t) { Impl::ResetImpl(); return *this; } template requires NAMESPACE_PRIVATE::TIsInvocableSignature>::Value && (!CTFunctionRef>) && (!CTFunction>) && (!CTUniqueFunction>) @@ -455,8 +455,8 @@ public: { using DecayedType = TDecay; - if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Super::ResetImpl(); - else Super::template EmplaceImpl(Forward(InValue)); + if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Impl::ResetImpl(); + else Impl::template EmplaceImpl(Forward(InValue)); return *this; } @@ -466,27 +466,27 @@ public: FORCEINLINE TDecay& Emplace(ArgTypes&&... Args) { using DecayedType = TDecay; - Super::template EmplaceImpl(Forward(Args)...); - return Super::template Target(); + Impl::template EmplaceImpl(Forward(Args)...); + return Impl::template Target(); } - constexpr void Reset() { Super::ResetImpl(); } + constexpr void Reset() { Impl::ResetImpl(); } }; -template +template constexpr bool operator==(const TFunctionRef& LHS, nullptr_t) { return !LHS; } -template +template constexpr bool operator==(const TFunction& LHS, nullptr_t) { return !LHS; } -template +template constexpr bool operator==(const TUniqueFunction& LHS, nullptr_t) { return !LHS; diff --git a/Redcraft.Utility/Source/Public/Templates/Optional.h b/Redcraft.Utility/Source/Public/Templates/Optional.h index 54ebd3d..a794cdd 100644 --- a/Redcraft.Utility/Source/Public/Templates/Optional.h +++ b/Redcraft.Utility/Source/Public/Templates/Optional.h @@ -12,7 +12,7 @@ NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) template requires CDestructible -struct TOptional +class TOptional { private: diff --git a/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h b/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h index 719f97e..54b7b0c 100644 --- a/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h +++ b/Redcraft.Utility/Source/Public/Templates/ReferenceWrapper.h @@ -11,7 +11,7 @@ NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) template requires (CObject || CFunction) -struct TReferenceWrapper +class TReferenceWrapper { public: @@ -61,11 +61,11 @@ private: ReferencedType* Pointer; - template requires (CObject || CFunction) friend struct TReferenceWrapper; + template requires (CObject || CFunction) friend class TReferenceWrapper; // Optimize TOptional with these hacking constexpr TReferenceWrapper(FInvalid) : Pointer(nullptr) { }; - template requires CDestructible friend struct TOptional; + template requires CDestructible friend class TOptional; }; @@ -121,7 +121,7 @@ template using TUnwrapRefDecay = typename NAMESPACE_PRIVATE::TUnwrapRefDecayImpl::Type; template -struct TOptional> +class TOptional> { private: @@ -235,7 +235,7 @@ public: private: TReferenceWrapper Reference; - template requires CDestructible friend struct TOptional; + template requires CDestructible friend class TOptional; }; diff --git a/Redcraft.Utility/Source/Public/Templates/Tuple.h b/Redcraft.Utility/Source/Public/Templates/Tuple.h index 976fe3c..49db784 100644 --- a/Redcraft.Utility/Source/Public/Templates/Tuple.h +++ b/Redcraft.Utility/Source/Public/Templates/Tuple.h @@ -17,7 +17,7 @@ NAMESPACE_MODULE_BEGIN(Utility) #define RS_TUPLE_ELEMENT_STATIC_ALIAS 1 template -struct TTuple; +class TTuple; NAMESPACE_PRIVATE_BEGIN @@ -209,10 +209,10 @@ constexpr TTuple...> MakeTupleImpl(Types&&... Args) } template -struct TTupleImpl; +class TTupleImpl; template -struct TTupleImpl, Types...> : TTupleBasicElement... +class TTupleImpl, Types...> : public TTupleBasicElement... { protected: @@ -237,11 +237,13 @@ protected: }; template -struct TTupleHelper; +class TTupleHelper; template -struct TTupleHelper> +class TTupleHelper> { +public: + template static constexpr void Assign(LHSTupleType& LHS, RHSTupleType&& RHS) { @@ -299,7 +301,7 @@ template using TTupleElement = typename NAMESPACE_PRIVATE::TTupleElementImpl::Type; template -struct TTuple : NAMESPACE_PRIVATE::TTupleImpl, Types...> +class TTuple : public NAMESPACE_PRIVATE::TTupleImpl, Types...> { private: diff --git a/Redcraft.Utility/Source/Public/Templates/Variant.h b/Redcraft.Utility/Source/Public/Templates/Variant.h index b175e93..7b07d63 100644 --- a/Redcraft.Utility/Source/Public/Templates/Variant.h +++ b/Redcraft.Utility/Source/Public/Templates/Variant.h @@ -14,7 +14,7 @@ NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) template requires (true && ... && CDestructible) -struct TVariant; +class TVariant; NAMESPACE_PRIVATE_BEGIN @@ -139,8 +139,10 @@ template using TVariantAlternative = typename NAMESPACE_PRIVATE::TVariantAlternativeImpl::Type; template requires (true && ... && CDestructible) -struct TVariant +class TVariant { +public: + constexpr TVariant() : TypeIndex(0xFF) { }; constexpr TVariant(FInvalid) : TVariant() { };