From 943c7c59911027aee86a1b2756c6b42c547606da Mon Sep 17 00:00:00 2001 From: _Redstone_c_ Date: Sun, 3 Apr 2022 22:55:17 +0800 Subject: [PATCH] refactor(templates): add constraints to reduce duplicate code on TAny etc --- .../Public/Miscellaneous/CoreMiscDefines.h | 2 +- .../Source/Public/Templates/Any.h | 131 +++++------------- .../Source/Public/Templates/Optional.h | 60 ++------ .../Source/Public/Templates/Variant.h | 54 -------- 4 files changed, 46 insertions(+), 201 deletions(-) diff --git a/Redcraft.Utility/Source/Public/Miscellaneous/CoreMiscDefines.h b/Redcraft.Utility/Source/Public/Miscellaneous/CoreMiscDefines.h index 199f74e..154e7d2 100644 --- a/Redcraft.Utility/Source/Public/Miscellaneous/CoreMiscDefines.h +++ b/Redcraft.Utility/Source/Public/Miscellaneous/CoreMiscDefines.h @@ -10,7 +10,7 @@ NAMESPACE_MODULE_BEGIN(Utility) #define CARRIES_DEPENDENCY [[carries_dependency]] #define DEPRECATED(Message) [[deprecated(Message)]] #define FALLTHROUGH [[fallthrough]] -#define NODISCARD(Message) [[nodiscard(Message)]] +#define NODISCARD [[nodiscard]] #define MAYBE_UNUSED [[maybe_unused]] #define LIKELY [[likely]] #define UNLIKELY [[unlikely]] diff --git a/Redcraft.Utility/Source/Public/Templates/Any.h b/Redcraft.Utility/Source/Public/Templates/Any.h index 49fc0f4..3e94ddc 100644 --- a/Redcraft.Utility/Source/Public/Templates/Any.h +++ b/Redcraft.Utility/Source/Public/Templates/Any.h @@ -135,7 +135,7 @@ struct TAny constexpr TAny() : TypeInfo(Typeid(void)), RTTI(nullptr) { } - TAny(FInvalid) : TAny() { } + constexpr TAny(FInvalid) : TAny() { } TAny(const TAny& InValue) : TypeInfo(InValue.TypeInfo), RTTI(InValue.RTTI) @@ -165,25 +165,9 @@ struct TAny && (!TIsArray::Type>::Value) && TIsDestructible::Type>::Value && TIsConstructible::Type, Types...>::Value explicit TAny(TInPlaceType, Types&&... Args) - : TypeInfo(Typeid(typename TDecay::Type)) { using SelectedType = typename TDecay::Type; - - if constexpr (TIsTriviallyStorable::Value) - { - new(&InlineValue) SelectedType(Forward(Args)...); - RTTI = nullptr; - } - else if constexpr (TIsInlineStorable::Value) - { - new(&InlineValue) SelectedType(Forward(Args)...); - RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; - } - else - { - DynamicValue = new SelectedType(Forward(Args)...); - RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; - } + EmplaceImpl(Forward(Args)...); } template requires (!TIsSame::Type, TAny>::Value) && (!TIsTInPlaceType::Type>::Value) @@ -199,6 +183,8 @@ struct TAny TAny& operator=(const TAny& InValue) { + if (&InValue == this) return *this; + if (!InValue.IsValid()) { Reset(); @@ -225,6 +211,8 @@ struct TAny TAny& operator=(TAny&& InValue) { + if (&InValue == this) return *this; + if (!InValue.IsValid()) { Reset(); @@ -271,24 +259,7 @@ struct TAny else { Reset(); - - TypeInfo = Typeid(SelectedType); - - if constexpr (TIsTriviallyStorable::Value) - { - new(&InlineValue) SelectedType(Forward(InValue)); - RTTI = nullptr; - } - else if constexpr (TIsInlineStorable::Value) - { - new(&InlineValue) SelectedType(Forward(InValue)); - RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; - } - else - { - DynamicValue = new SelectedType(Forward(InValue)); - RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; - } + EmplaceImpl(Forward(InValue)); } return *this; @@ -302,33 +273,15 @@ struct TAny Reset(); using SelectedType = typename TDecay::Type; - - TypeInfo = Typeid(SelectedType); - - if constexpr (TIsTriviallyStorable::Value) - { - new(&InlineValue) SelectedType(Forward(Args)...); - RTTI = nullptr; - } - else if constexpr (TIsInlineStorable::Value) - { - new(&InlineValue) SelectedType(Forward(Args)...); - RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; - } - else - { - DynamicValue = new SelectedType(Forward(Args)...); - RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; - } - + EmplaceImpl(Forward(Args)...); return GetValue(); } - constexpr FTypeInfo GetTypeInfo() const { return TypeInfo; } - constexpr bool IsValid() const { return TypeInfo != Typeid(void); } - constexpr explicit operator bool() const { return TypeInfo != Typeid(void); } - constexpr bool IsInline() const { return RTTI != nullptr ? RTTI->bIsInline : true; } - constexpr bool IsTrivial() const { return RTTI == nullptr; } + constexpr FTypeInfo GetTypeInfo() const { return TypeInfo; } + constexpr bool IsValid() const { return TypeInfo != Typeid(void); } + constexpr explicit operator bool() const { return TypeInfo != Typeid(void); } + constexpr bool IsInline() const { return RTTI != nullptr ? RTTI->bIsInline : true; } + constexpr bool IsTrivial() const { return RTTI == nullptr; } template constexpr bool HoldsAlternative() const { return IsValid() ? TypeInfo == Typeid(T) : false; } @@ -377,6 +330,28 @@ private: FTypeInfo TypeInfo; const NAMESPACE_PRIVATE::FAnyRTTI* RTTI; + template + void EmplaceImpl(Types&&... Args) + { + TypeInfo = Typeid(SelectedType); + + if constexpr (TIsTriviallyStorable::Value) + { + new(&InlineValue) SelectedType(Forward(Args)...); + RTTI = nullptr; + } + else if constexpr (TIsInlineStorable::Value) + { + new(&InlineValue) SelectedType(Forward(Args)...); + RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; + } + else + { + DynamicValue = new SelectedType(Forward(Args)...); + RTTI = &NAMESPACE_PRIVATE::TAnyRTTIHelper::RTTI; + } + } + }; template @@ -385,48 +360,12 @@ constexpr bool operator==(const TAny& LHS, const T& return LHS.template HoldsAlternative() ? LHS.template GetValue() == RHS : false; } -template -constexpr bool operator!=(const TAny& LHS, const T& RHS) -{ - return LHS.template HoldsAlternative() ? LHS.template GetValue() != RHS : true; -} - -template -constexpr bool operator==(const T& LHS, const TAny& RHS) -{ - return RHS.template HoldsAlternative() ? LHS == RHS.template GetValue() : false; -} - -template -constexpr bool operator!=(const T& LHS, const TAny& RHS) -{ - return RHS.template HoldsAlternative() ? LHS != RHS.template GetValue() : true; -} - template constexpr bool operator==(const TAny& LHS, FInvalid) { return !LHS.IsValid(); } -template -constexpr bool operator!=(const TAny& LHS, FInvalid) -{ - return LHS.IsValid(); -} - -template -constexpr bool operator==(FInvalid, const TAny& RHS) -{ - return !RHS.IsValid(); -} - -template -constexpr bool operator!=(FInvalid, const TAny& RHS) -{ - return RHS.IsValid(); -} - template constexpr void Swap(TAny& A, TAny& B) { diff --git a/Redcraft.Utility/Source/Public/Templates/Optional.h b/Redcraft.Utility/Source/Public/Templates/Optional.h index 67252a1..4349a20 100644 --- a/Redcraft.Utility/Source/Public/Templates/Optional.h +++ b/Redcraft.Utility/Source/Public/Templates/Optional.h @@ -106,9 +106,11 @@ public: return *this; } - template requires TIsConstructible::Value + template requires TIsConstructible::Value && TIsAssignable::Value constexpr TOptional& operator=(const TOptional& InValue) { + if (&InValue == this) return *this; + if (!InValue.IsValid()) { Reset(); @@ -125,9 +127,11 @@ public: return *this; } - template requires TIsConstructible::Value + template requires TIsConstructible::Value && TIsAssignable::Value constexpr TOptional& operator=(TOptional&& InValue) { + if (&InValue == this) return *this; + if (!InValue.IsValid()) { Reset(); @@ -144,7 +148,7 @@ public: return *this; } - template requires TIsConstructible::Value + template requires TIsConstructible::Value && TIsAssignable::Value constexpr TOptional& operator=(T&& InValue) { if (IsValid()) GetValue() = Forward(InValue); @@ -157,12 +161,12 @@ public: return *this; } - template - constexpr OptionalType& Emplace(ArgsType&&... Args) + template requires TIsConstructible::Value + constexpr OptionalType& Emplace(ArgTypes&&... Args) { Reset(); - OptionalType* Result = new(&Value) OptionalType(Forward(Args)...); + OptionalType* Result = new(&Value) OptionalType(Forward(Args)...); bIsValid = true; return *Result; @@ -225,62 +229,18 @@ constexpr bool operator==(const TOptional& LHS, const TOptional& RHS) return *LHS == *RHS; } -template requires CWeaklyEqualityComparableWith -constexpr bool operator!=(const TOptional& LHS, const TOptional& RHS) -{ - if (LHS.IsValid() != RHS.IsValid()) return true; - if (LHS.IsValid() == false) return false; - return *LHS != *RHS; -} - template requires CWeaklyEqualityComparableWith constexpr bool operator==(const TOptional& LHS, const U& RHS) { return LHS.IsValid() ? *LHS == RHS : false; } -template requires CWeaklyEqualityComparableWith -constexpr bool operator!=(const TOptional& LHS, const U& RHS) -{ - return LHS.IsValid() ? *LHS != RHS : true; -} - -template requires CWeaklyEqualityComparableWith -constexpr bool operator==(const T& LHS, const TOptional& RHS) -{ - return RHS.IsValid() ? LHS == *RHS : false; -} - -template requires CWeaklyEqualityComparableWith -constexpr bool operator!=(const T& LHS, const TOptional& RHS) -{ - return RHS.IsValid() ? LHS != *RHS : true; -} - template constexpr bool operator==(const TOptional& LHS, FInvalid) { return !LHS.IsValid(); } -template -constexpr bool operator!=(const TOptional& LHS, FInvalid) -{ - return LHS.IsValid(); -} - -template -constexpr bool operator==(FInvalid, const TOptional& RHS) -{ - return !RHS.IsValid(); -} - -template -constexpr bool operator!=(FInvalid, const TOptional& RHS) -{ - return RHS.IsValid(); -} - template requires (TIsObject::Value && !TIsArray::Value && TIsDestructible::Value) constexpr TOptional::Type> MakeOptional(FInvalid) { diff --git a/Redcraft.Utility/Source/Public/Templates/Variant.h b/Redcraft.Utility/Source/Public/Templates/Variant.h index a42d5f2..08f8b2c 100644 --- a/Redcraft.Utility/Source/Public/Templates/Variant.h +++ b/Redcraft.Utility/Source/Public/Templates/Variant.h @@ -132,16 +132,6 @@ constexpr bool VariantEqualityOperator(const void* LHS, const void* RHS) using FVariantEqualityOperatorFunc = bool(*)(const void*, const void*); -template -constexpr bool VariantInequalityOperator(const void* LHS, const void* RHS) -{ - if constexpr (!CEqualityComparable) check_no_entry(); - else return *reinterpret_cast(LHS) != *reinterpret_cast(RHS); - return false; -} - -using FVariantInequalityOperatorFunc = bool(*)(const void*, const void*); - template struct TVariantHelper { @@ -151,7 +141,6 @@ struct TVariantHelper static constexpr FVariantCopyAssignFunc CopyAssignFuncs[] = { VariantCopyAssign... }; static constexpr FVariantMoveAssignFunc MoveAssignFuncs[] = { VariantMoveAssign... }; static constexpr FVariantEqualityOperatorFunc EqualityOperatorFuncs[] = { VariantEqualityOperator... }; - static constexpr FVariantInequalityOperatorFunc InequalityOperatorFuncs[] = { VariantInequalityOperator... }; }; template @@ -451,13 +440,6 @@ private: return FHelper::EqualityOperatorFuncs[LHS.GetIndex()](&LHS.Value, &RHS.Value); } - friend constexpr bool operator!=(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CEqualityComparable) - { - if (LHS.GetIndex() != RHS.GetIndex()) return true; - if (LHS.IsValid() == false) return false; - return FHelper::InequalityOperatorFuncs[LHS.GetIndex()](&LHS.Value, &RHS.Value); - } - }; template requires (!TIsSame>::Value) && CEqualityComparable @@ -466,48 +448,12 @@ constexpr bool operator==(const TVariant& LHS, const T& RHS) return LHS.template HoldsAlternative() ? LHS.template GetValue() == RHS : false; } -template requires (!TIsSame>::Value) && CEqualityComparable -constexpr bool operator!=(const TVariant& LHS, const T& RHS) -{ - return LHS.template HoldsAlternative() ? LHS.template GetValue() != RHS : true; -} - -template requires (!TIsSame>::Value) && CEqualityComparable -constexpr bool operator==(const T& LHS, const TVariant& RHS) -{ - return RHS.template HoldsAlternative() ? LHS == RHS.template GetValue() : false; -} - -template requires (!TIsSame>::Value) && CEqualityComparable -constexpr bool operator!=(const T& LHS, const TVariant& RHS) -{ - return RHS.template HoldsAlternative() ? LHS != RHS.template GetValue() : true; -} - template constexpr bool operator==(const TVariant& LHS, FInvalid) { return !LHS.IsValid(); } -template -constexpr bool operator!=(const TVariant& LHS, FInvalid) -{ - return LHS.IsValid(); -} - -template -constexpr bool operator==(FInvalid, const TVariant& RHS) -{ - return !RHS.IsValid(); -} - -template -constexpr bool operator!=(FInvalid, const TVariant& RHS) -{ - return RHS.IsValid(); -} - template requires (true && ... && (TIsMoveConstructible::Value && TIsSwappable::Value)) constexpr void Swap(TVariant& A, TVariant& B) {