refactor(templates): optimize TOptional and TVariant, add necessary constraints

This commit is contained in:
_Redstone_c_ 2022-03-31 12:07:15 +08:00
parent d8a4908a88
commit c4c205e35b
2 changed files with 23 additions and 23 deletions

View File

@ -34,13 +34,13 @@ public:
: TOptional(InPlace, Forward<T>(InValue)) : TOptional(InPlace, Forward<T>(InValue))
{ } { }
constexpr TOptional(const TOptional& InValue) constexpr TOptional(const TOptional& InValue) requires TIsCopyConstructible<OptionalType>::Value
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
if (InValue.IsValid()) new(&Value) OptionalType(InValue.GetValue()); if (InValue.IsValid()) new(&Value) OptionalType(InValue.GetValue());
} }
constexpr TOptional(TOptional&& InValue) constexpr TOptional(TOptional&& InValue) requires TIsMoveConstructible<OptionalType>::Value
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
if (InValue.IsValid()) new(&Value) OptionalType(MoveTemp(InValue.GetValue())); if (InValue.IsValid()) new(&Value) OptionalType(MoveTemp(InValue.GetValue()));
@ -65,7 +65,7 @@ public:
if constexpr (!TIsTriviallyDestructible<OptionalType>::Value) Reset(); if constexpr (!TIsTriviallyDestructible<OptionalType>::Value) Reset();
} }
constexpr TOptional& operator=(const TOptional& InValue) constexpr TOptional& operator=(const TOptional& InValue) requires TIsCopyConstructible<OptionalType>::Value && TIsCopyAssignable<OptionalType>::Value
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -85,7 +85,7 @@ public:
return *this; return *this;
} }
constexpr TOptional& operator=(TOptional&& InValue) constexpr TOptional& operator=(TOptional&& InValue) requires TIsMoveConstructible<OptionalType>::Value && TIsMoveAssignable<OptionalType>::Value
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -210,7 +210,7 @@ private:
template <typename T> template <typename T>
TOptional(T) ->TOptional<T>; TOptional(T) ->TOptional<T>;
template <typename T, typename U> template <typename T, typename U> requires CWeaklyEqualityComparableWith<T, U>
constexpr bool operator==(const TOptional<T>& LHS, const TOptional<U>& RHS) constexpr bool operator==(const TOptional<T>& LHS, const TOptional<U>& RHS)
{ {
if (LHS.IsValid() != RHS.IsValid()) return false; if (LHS.IsValid() != RHS.IsValid()) return false;
@ -218,7 +218,7 @@ constexpr bool operator==(const TOptional<T>& LHS, const TOptional<U>& RHS)
return *LHS == *RHS; return *LHS == *RHS;
} }
template <typename T, typename U> template <typename T, typename U> requires CWeaklyEqualityComparableWith<T, U>
constexpr bool operator!=(const TOptional<T>& LHS, const TOptional<U>& RHS) constexpr bool operator!=(const TOptional<T>& LHS, const TOptional<U>& RHS)
{ {
if (LHS.IsValid() != RHS.IsValid()) return true; if (LHS.IsValid() != RHS.IsValid()) return true;
@ -226,25 +226,25 @@ constexpr bool operator!=(const TOptional<T>& LHS, const TOptional<U>& RHS)
return *LHS != *RHS; return *LHS != *RHS;
} }
template <typename T, typename U> template <typename T, typename U> requires CWeaklyEqualityComparableWith<T, U>
constexpr bool operator==(const TOptional<T>& LHS, const U& RHS) constexpr bool operator==(const TOptional<T>& LHS, const U& RHS)
{ {
return LHS.IsValid() ? *LHS == RHS : false; return LHS.IsValid() ? *LHS == RHS : false;
} }
template <typename T, typename U> template <typename T, typename U> requires CWeaklyEqualityComparableWith<T, U>
constexpr bool operator!=(const TOptional<T>& LHS, const U& RHS) constexpr bool operator!=(const TOptional<T>& LHS, const U& RHS)
{ {
return LHS.IsValid() ? *LHS != RHS : true; return LHS.IsValid() ? *LHS != RHS : true;
} }
template <typename T, typename U> template <typename T, typename U> requires CWeaklyEqualityComparableWith<T, U>
constexpr bool operator==(const T& LHS, const TOptional<U>& RHS) constexpr bool operator==(const T& LHS, const TOptional<U>& RHS)
{ {
return RHS.IsValid() ? LHS == *RHS : false; return RHS.IsValid() ? LHS == *RHS : false;
} }
template <typename T, typename U> template <typename T, typename U> requires CWeaklyEqualityComparableWith<T, U>
constexpr bool operator!=(const T& LHS, const TOptional<U>& RHS) constexpr bool operator!=(const T& LHS, const TOptional<U>& RHS)
{ {
return RHS.IsValid() ? LHS != *RHS : true; return RHS.IsValid() ? LHS != *RHS : true;
@ -274,19 +274,19 @@ constexpr bool operator!=(FInvalid, const TOptional<T>& RHS)
return RHS.IsValid(); return RHS.IsValid();
} }
template <typename T> template <typename T> requires (TIsObject<T>::Value && !TIsArray<T>::Value && TIsDestructible<T>::Value)
constexpr TOptional<typename TDecay<T>::Type> MakeOptional(FInvalid) constexpr TOptional<typename TDecay<T>::Type> MakeOptional(FInvalid)
{ {
return TOptional<typename TDecay<T>::Type>(Invalid); return TOptional<typename TDecay<T>::Type>(Invalid);
} }
template <typename T> template <typename T> requires (TIsObject<T>::Value && !TIsArray<T>::Value && TIsDestructible<T>::Value)
constexpr TOptional<typename TDecay<T>::Type> MakeOptional(T&& InValue) constexpr TOptional<typename TDecay<T>::Type> MakeOptional(T&& InValue)
{ {
return TOptional<typename TDecay<T>::Type>(Forward<T>(InValue)); return TOptional<typename TDecay<T>::Type>(Forward<T>(InValue));
} }
template <typename T, typename... Types> template <typename T, typename... Types> requires (TIsObject<T>::Value && !TIsArray<T>::Value && TIsDestructible<T>::Value)
constexpr TOptional<T> MakeOptional(Types&&... Args) constexpr TOptional<T> MakeOptional(Types&&... Args)
{ {
return TOptional<T>(InPlace, Forward<T>(Args)...); return TOptional<T>(InPlace, Forward<T>(Args)...);

View File

@ -216,13 +216,13 @@ struct TVariant
constexpr TVariant(FInvalid) : TVariant() { }; constexpr TVariant(FInvalid) : TVariant() { };
constexpr TVariant(const TVariant& InValue) constexpr TVariant(const TVariant& InValue) requires (true && ... && TIsCopyConstructible<Types>::Value)
: TypeIndex(InValue.GetIndex()) : TypeIndex(InValue.GetIndex())
{ {
if (GetIndex() != INDEX_NONE) FHelper::CopyConstructFuncs[InValue.GetIndex()](&Value, &InValue.Value); if (GetIndex() != INDEX_NONE) FHelper::CopyConstructFuncs[InValue.GetIndex()](&Value, &InValue.Value);
} }
constexpr TVariant(TVariant&& InValue) constexpr TVariant(TVariant&& InValue) requires (true && ... && TIsMoveConstructible<Types>::Value)
: TypeIndex(InValue.GetIndex()) : TypeIndex(InValue.GetIndex())
{ {
if (GetIndex() != INDEX_NONE) FHelper::MoveConstructFuncs[InValue.GetIndex()](&Value, &InValue.Value); if (GetIndex() != INDEX_NONE) FHelper::MoveConstructFuncs[InValue.GetIndex()](&Value, &InValue.Value);
@ -254,7 +254,7 @@ struct TVariant
if constexpr (!(true && ... && TIsTriviallyDestructible<Types>::Value)) Reset(); if constexpr (!(true && ... && TIsTriviallyDestructible<Types>::Value)) Reset();
} }
constexpr TVariant& operator=(const TVariant& InValue) constexpr TVariant& operator=(const TVariant& InValue) requires (true && ... && (TIsCopyConstructible<Types>::Value && TIsCopyAssignable<Types>::Value))
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -275,7 +275,7 @@ struct TVariant
return *this; return *this;
} }
constexpr TVariant& operator=(TVariant&& InValue) constexpr TVariant& operator=(TVariant&& InValue) requires (true && ... && (TIsMoveConstructible<Types>::Value && TIsMoveAssignable<Types>::Value))
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -437,14 +437,14 @@ private:
TAlignedUnion<1, Types...>::Type Value; TAlignedUnion<1, Types...>::Type Value;
size_t TypeIndex; size_t TypeIndex;
friend constexpr bool operator==(const TVariant& LHS, const TVariant& RHS) friend constexpr bool operator==(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CEqualityComparable<Types>)
{ {
if (LHS.GetIndex() != RHS.GetIndex()) return false; if (LHS.GetIndex() != RHS.GetIndex()) return false;
if (LHS.IsValid() == false) return true; if (LHS.IsValid() == false) return true;
return FHelper::EqualityOperatorFuncs[LHS.GetIndex()](&LHS.Value, &RHS.Value); return FHelper::EqualityOperatorFuncs[LHS.GetIndex()](&LHS.Value, &RHS.Value);
} }
friend constexpr bool operator!=(const TVariant& LHS, const TVariant& RHS) friend constexpr bool operator!=(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CEqualityComparable<Types>)
{ {
if (LHS.GetIndex() != RHS.GetIndex()) return true; if (LHS.GetIndex() != RHS.GetIndex()) return true;
if (LHS.IsValid() == false) return false; if (LHS.IsValid() == false) return false;
@ -453,25 +453,25 @@ private:
}; };
template <typename T, typename... Types> template <typename T, typename... Types> requires (!TIsSame<T, TVariant<Types...>>::Value) && CEqualityComparable<T>
constexpr bool operator==(const TVariant<Types...>& LHS, const T& RHS) constexpr bool operator==(const TVariant<Types...>& LHS, const T& RHS)
{ {
return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() == RHS : false; return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() == RHS : false;
} }
template <typename T, typename... Types> template <typename T, typename... Types> requires (!TIsSame<T, TVariant<Types...>>::Value) && CEqualityComparable<T>
constexpr bool operator!=(const TVariant<Types...>& LHS, const T& RHS) constexpr bool operator!=(const TVariant<Types...>& LHS, const T& RHS)
{ {
return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() != RHS : true; return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() != RHS : true;
} }
template <typename T, typename... Types> template <typename T, typename... Types> requires (!TIsSame<T, TVariant<Types...>>::Value) && CEqualityComparable<T>
constexpr bool operator==(const T& LHS, const TVariant<Types...>& RHS) constexpr bool operator==(const T& LHS, const TVariant<Types...>& RHS)
{ {
return RHS.template HoldsAlternative<T>() ? LHS == RHS.template GetValue<T>() : false; return RHS.template HoldsAlternative<T>() ? LHS == RHS.template GetValue<T>() : false;
} }
template <typename T, typename... Types> template <typename T, typename... Types> requires (!TIsSame<T, TVariant<Types...>>::Value) && CEqualityComparable<T>
constexpr bool operator!=(const T& LHS, const TVariant<Types...>& RHS) constexpr bool operator!=(const T& LHS, const TVariant<Types...>& RHS)
{ {
return RHS.template HoldsAlternative<T>() ? LHS != RHS.template GetValue<T>() : true; return RHS.template HoldsAlternative<T>() ? LHS != RHS.template GetValue<T>() : true;