refactor(templates): refactor operator== and operator<=> to member or friend
This commit is contained in:
parent
6cee8a1185
commit
d87d292691
@ -130,6 +130,8 @@ void TestOptional()
|
|||||||
always_check(TempO == TempO);
|
always_check(TempO == TempO);
|
||||||
always_check(TempO == 300);
|
always_check(TempO == 300);
|
||||||
always_check(300 == TempO);
|
always_check(300 == TempO);
|
||||||
|
always_check(TempO >= 200);
|
||||||
|
always_check(400 >= TempO);
|
||||||
|
|
||||||
int16 TempQ = 1024;
|
int16 TempQ = 1024;
|
||||||
TOptional<int16> TempR = TempQ;
|
TOptional<int16> TempR = TempQ;
|
||||||
@ -221,6 +223,8 @@ void TestVariant()
|
|||||||
always_check(TempO == TempO);
|
always_check(TempO == TempO);
|
||||||
always_check(TempO == 300);
|
always_check(TempO == 300);
|
||||||
always_check(300 == TempO);
|
always_check(300 == TempO);
|
||||||
|
always_check(TempO >= 200);
|
||||||
|
always_check(400 >= TempO);
|
||||||
|
|
||||||
Swap(TempD, TempA);
|
Swap(TempD, TempA);
|
||||||
|
|
||||||
@ -428,7 +432,7 @@ void TestAny()
|
|||||||
int32 A;
|
int32 A;
|
||||||
FIntegral() { }
|
FIntegral() { }
|
||||||
FIntegral(int32 InA) : A(InA) { }
|
FIntegral(int32 InA) : A(InA) { }
|
||||||
bool operator==(FIntegral RHS) const { return A == RHS.A; }
|
bool operator==(FIntegral RHS) const& { return A == RHS.A; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FFloating
|
struct FFloating
|
||||||
@ -437,7 +441,7 @@ void TestAny()
|
|||||||
uint8 Pad[64];
|
uint8 Pad[64];
|
||||||
FFloating() { }
|
FFloating() { }
|
||||||
FFloating(double InA) : A(InA) { }
|
FFloating(double InA) : A(InA) { }
|
||||||
bool operator==(FFloating RHS) const { return A == RHS.A; }
|
bool operator==(FFloating RHS) const& { return A == RHS.A; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FTracker
|
struct FTracker
|
||||||
@ -474,6 +478,8 @@ void TestAny()
|
|||||||
always_check(TempO.IsValid());
|
always_check(TempO.IsValid());
|
||||||
|
|
||||||
always_check(TempO == 404);
|
always_check(TempO == 404);
|
||||||
|
always_check(TempO >= 400);
|
||||||
|
always_check(500 >= TempO);
|
||||||
always_check(TempO.GetValue<int32>() == 404);
|
always_check(TempO.GetValue<int32>() == 404);
|
||||||
always_check(TempO.Get<int32>(500) == 404);
|
always_check(TempO.Get<int32>(500) == 404);
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "Memory/Alignment.h"
|
#include "Memory/Alignment.h"
|
||||||
#include "Templates/Utility.h"
|
#include "Templates/Utility.h"
|
||||||
#include "Templates/TypeHash.h"
|
#include "Templates/TypeHash.h"
|
||||||
#include "Memory/MemoryOperator.h"
|
|
||||||
#include "TypeTraits/TypeTraits.h"
|
#include "TypeTraits/TypeTraits.h"
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
|
|
||||||
@ -236,6 +235,20 @@ public:
|
|||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> requires (!CBaseOf<FAny, TRemoveCVRef<T>> && NAMESPACE_PRIVATE::CFAnyPlaceable<T>)
|
||||||
|
FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
||||||
|
{
|
||||||
|
return HoldsAlternative<T>() ? GetValue<T>() == InValue : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> requires (!CBaseOf<FAny, TRemoveCVRef<T>> && NAMESPACE_PRIVATE::CFAnyPlaceable<T>)
|
||||||
|
FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
||||||
|
{
|
||||||
|
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE constexpr bool operator==(FInvalid) const& { return !IsValid(); }
|
||||||
|
|
||||||
template <typename T, typename... Ts> requires (NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, Ts&&...>)
|
template <typename T, typename... Ts> requires (NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, Ts&&...>)
|
||||||
FORCEINLINE TDecay<T>& Emplace(Ts&&... Args)
|
FORCEINLINE TDecay<T>& Emplace(Ts&&... Args)
|
||||||
@ -527,17 +540,6 @@ private:
|
|||||||
|
|
||||||
FORCEINLINE constexpr void Invalidate() { TypeInfo = 0; }
|
FORCEINLINE constexpr void Invalidate() { TypeInfo = 0; }
|
||||||
|
|
||||||
template <typename T> requires (!CBaseOf<FAny, TRemoveCVRef<T>>)
|
|
||||||
friend FORCEINLINE constexpr bool operator==(const FAny& LHS, const T& RHS)
|
|
||||||
{
|
|
||||||
return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() == RHS : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend FORCEINLINE constexpr bool operator==(const FAny& LHS, FInvalid)
|
|
||||||
{
|
|
||||||
return !LHS.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(FAny) == 64, "The byte size of FAny is unexpected");
|
static_assert(sizeof(FAny) == 64, "The byte size of FAny is unexpected");
|
||||||
|
@ -482,6 +482,8 @@ public:
|
|||||||
FORCEINLINE ResultType operator()(Ts... Args) const& requires (CSameAs<CVRef, const int& >) { return CallImpl(Forward<Ts>(Args)...); }
|
FORCEINLINE ResultType operator()(Ts... Args) const& requires (CSameAs<CVRef, const int& >) { return CallImpl(Forward<Ts>(Args)...); }
|
||||||
FORCEINLINE ResultType operator()(Ts... Args) const&& requires (CSameAs<CVRef, const int&&>) { return CallImpl(Forward<Ts>(Args)...); }
|
FORCEINLINE ResultType operator()(Ts... Args) const&& requires (CSameAs<CVRef, const int&&>) { return CallImpl(Forward<Ts>(Args)...); }
|
||||||
|
|
||||||
|
FORCEINLINE constexpr bool operator==(nullptr_t) const& { return !IsValid(); }
|
||||||
|
|
||||||
FORCEINLINE constexpr bool IsValid() const { return Storage.IsValid(); }
|
FORCEINLINE constexpr bool IsValid() const { return Storage.IsValid(); }
|
||||||
FORCEINLINE constexpr explicit operator bool() const { return Storage.IsValid(); }
|
FORCEINLINE constexpr explicit operator bool() const { return Storage.IsValid(); }
|
||||||
|
|
||||||
@ -573,6 +575,9 @@ public:
|
|||||||
Impl::template Emplace<T>(Forward<T>(InValue));
|
Impl::template Emplace<T>(Forward<T>(InValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
TFunctionRef(const T&& InValue) = delete;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <CFunction F>
|
template <CFunction F>
|
||||||
@ -718,7 +723,7 @@ public:
|
|||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... ArgTypes> requires (NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value
|
template <typename T, typename... ArgTypes> requires (NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value
|
||||||
&& CConstructibleFrom<TDecay<T>, ArgTypes...> && CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
|
&& CConstructibleFrom<TDecay<T>, ArgTypes...> && CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
|
||||||
FORCEINLINE TDecay<T>& Emplace(ArgTypes&&... Args)
|
FORCEINLINE TDecay<T>& Emplace(ArgTypes&&... Args)
|
||||||
@ -732,24 +737,6 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <CFunction F>
|
|
||||||
FORCEINLINE constexpr bool operator==(const TFunctionRef<F>& LHS, nullptr_t)
|
|
||||||
{
|
|
||||||
return !LHS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <CFunction F>
|
|
||||||
FORCEINLINE constexpr bool operator==(const TFunction<F>& LHS, nullptr_t)
|
|
||||||
{
|
|
||||||
return !LHS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <CFunction F>
|
|
||||||
FORCEINLINE constexpr bool operator==(const TUniqueFunction<F>& LHS, nullptr_t)
|
|
||||||
{
|
|
||||||
return !LHS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static_assert(sizeof(TFunction<void()>) == 64, "The byte size of TFunction is unexpected");
|
static_assert(sizeof(TFunction<void()>) == 64, "The byte size of TFunction is unexpected");
|
||||||
static_assert(sizeof(TUniqueFunction<void()>) == 64, "The byte size of TUniqueFunction is unexpected");
|
static_assert(sizeof(TUniqueFunction<void()>) == 64, "The byte size of TUniqueFunction is unexpected");
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ class TOptional;
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
|
template <typename T> struct TIsTOptional : FFalse { };
|
||||||
|
template <typename T> struct TIsTOptional<TOptional<T>> : FTrue { };
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
concept CTOptionalAllowUnwrappable =
|
concept CTOptionalAllowUnwrappable =
|
||||||
!(CConstructibleFrom<U, TOptional<T>& >
|
!(CConstructibleFrom<U, TOptional<T>& >
|
||||||
@ -33,6 +36,8 @@ concept CTOptionalAllowUnwrappable =
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
|
template <typename T> concept CTOptional = NAMESPACE_PRIVATE::TIsTOptional<TRemoveCV<T>>::Value;
|
||||||
|
|
||||||
template <typename OptionalType> requires (CDestructible<OptionalType>)
|
template <typename OptionalType> requires (CDestructible<OptionalType>)
|
||||||
class TOptional
|
class TOptional
|
||||||
{
|
{
|
||||||
@ -192,6 +197,36 @@ public:
|
|||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T = OptionalType> requires (CWeaklyEqualityComparable<OptionalType, T>)
|
||||||
|
friend FORCEINLINE constexpr bool operator==(const TOptional& LHS, const TOptional<T>& RHS)
|
||||||
|
{
|
||||||
|
if (LHS.IsValid() != RHS.IsValid()) return false;
|
||||||
|
if (LHS.IsValid() == false) return true;
|
||||||
|
return *LHS == *RHS;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T = OptionalType> requires (CSynthThreeWayComparable<OptionalType, T>)
|
||||||
|
friend FORCEINLINE constexpr partial_ordering operator<=>(const TOptional& LHS, const TOptional<T>& RHS)
|
||||||
|
{
|
||||||
|
if (LHS.IsValid() != RHS.IsValid()) return partial_ordering::unordered;
|
||||||
|
if (LHS.IsValid() == false) return partial_ordering::equivalent;
|
||||||
|
return SynthThreeWayCompare(*LHS, *RHS);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T = OptionalType> requires (!CTOptional<T>&& CWeaklyEqualityComparable<OptionalType, T>)
|
||||||
|
FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
||||||
|
{
|
||||||
|
return IsValid() ? GetValue() == InValue : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T = OptionalType> requires (!CTOptional<T>&& CSynthThreeWayComparable<OptionalType, T>)
|
||||||
|
FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
||||||
|
{
|
||||||
|
return IsValid() ? SynthThreeWayCompare(GetValue(), InValue) : partial_ordering::unordered;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE constexpr bool operator==(FInvalid) const& { return !IsValid(); }
|
||||||
|
|
||||||
template <typename... ArgTypes> requires (CConstructibleFrom<OptionalType, ArgTypes...>)
|
template <typename... ArgTypes> requires (CConstructibleFrom<OptionalType, ArgTypes...>)
|
||||||
FORCEINLINE constexpr OptionalType& Emplace(ArgTypes&&... Args)
|
FORCEINLINE constexpr OptionalType& Emplace(ArgTypes&&... Args)
|
||||||
@ -272,34 +307,6 @@ private:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
TOptional(T) -> TOptional<T>;
|
TOptional(T) -> TOptional<T>;
|
||||||
|
|
||||||
template <typename T, typename U> requires (CWeaklyEqualityComparable<T, U>)
|
|
||||||
FORCEINLINE constexpr bool operator==(const TOptional<T>& LHS, const TOptional<U>& RHS)
|
|
||||||
{
|
|
||||||
if (LHS.IsValid() != RHS.IsValid()) return false;
|
|
||||||
if (LHS.IsValid() == false) return true;
|
|
||||||
return *LHS == *RHS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename U> requires (CSynthThreeWayComparable<T, U>)
|
|
||||||
FORCEINLINE constexpr partial_ordering operator<=>(const TOptional<T>& LHS, const TOptional<U>& RHS)
|
|
||||||
{
|
|
||||||
if (LHS.IsValid() != RHS.IsValid()) return partial_ordering::unordered;
|
|
||||||
if (LHS.IsValid() == false) return partial_ordering::equivalent;
|
|
||||||
return SynthThreeWayCompare(*LHS, *RHS);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename U> requires (CWeaklyEqualityComparable<T, U>)
|
|
||||||
FORCEINLINE constexpr bool operator==(const TOptional<T>& LHS, const U& RHS)
|
|
||||||
{
|
|
||||||
return LHS.IsValid() ? *LHS == RHS : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
FORCEINLINE constexpr bool operator==(const TOptional<T>& LHS, FInvalid)
|
|
||||||
{
|
|
||||||
return !LHS.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> requires (CDestructible<T>)
|
template <typename T> requires (CDestructible<T>)
|
||||||
FORCEINLINE constexpr TOptional<TDecay<T>> MakeOptional(FInvalid)
|
FORCEINLINE constexpr TOptional<TDecay<T>> MakeOptional(FInvalid)
|
||||||
{
|
{
|
||||||
@ -318,15 +325,6 @@ FORCEINLINE constexpr TOptional<T> MakeOptional(Ts&&... Args)
|
|||||||
return TOptional<T>(InPlace, Forward<T>(Args)...);
|
return TOptional<T>(InPlace, Forward<T>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
|
||||||
|
|
||||||
template <typename T> struct TIsTOptional : FFalse { };
|
|
||||||
template <typename T> struct TIsTOptional<TOptional<T>> : FTrue { };
|
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
|
||||||
|
|
||||||
template <typename T> concept CTOptional = NAMESPACE_PRIVATE::TIsTOptional<TRemoveCV<T>>::Value;
|
|
||||||
|
|
||||||
NAMESPACE_MODULE_END(Utility)
|
NAMESPACE_MODULE_END(Utility)
|
||||||
NAMESPACE_MODULE_END(Redcraft)
|
NAMESPACE_MODULE_END(Redcraft)
|
||||||
NAMESPACE_REDCRAFT_END
|
NAMESPACE_REDCRAFT_END
|
||||||
|
@ -226,6 +226,57 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename R, typename Indices>
|
||||||
|
struct TTupleThreeWay;
|
||||||
|
|
||||||
|
template <typename R, size_t I, size_t... Indices>
|
||||||
|
struct TTupleThreeWay<R, TIndexSequence<I, Indices...>>
|
||||||
|
{
|
||||||
|
template <typename LHSTupleType, typename RHSTupleType>
|
||||||
|
FORCEINLINE static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS)
|
||||||
|
{
|
||||||
|
auto Result = SynthThreeWayCompare(LHS.template GetValue<I>(), RHS.template GetValue<I>());
|
||||||
|
if (Result != 0) return Result;
|
||||||
|
return TTupleThreeWay<R, TIndexSequence<Indices...>>::Do(LHS, RHS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename R>
|
||||||
|
struct TTupleThreeWay<R, TIndexSequence<>>
|
||||||
|
{
|
||||||
|
template <typename LHSTupleType, typename RHSTupleType>
|
||||||
|
FORCEINLINE static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS)
|
||||||
|
{
|
||||||
|
return R::equivalent;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename, typename> struct TTTupleWeaklyEqualityComparable;
|
||||||
|
|
||||||
|
template <typename T, typename U, typename... Ts, typename... Us>
|
||||||
|
struct TTTupleWeaklyEqualityComparable<TTypeSequence<T, Ts...>, TTypeSequence<U, Us...>>
|
||||||
|
: TBoolConstant<CWeaklyEqualityComparable<T, U> && TTTupleWeaklyEqualityComparable<TTypeSequence<Ts...>, TTypeSequence<Us...>>::Value>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct TTTupleWeaklyEqualityComparable<TTypeSequence<>, TTypeSequence<>> : FTrue { };
|
||||||
|
|
||||||
|
template <typename TSequence, typename USequence>
|
||||||
|
concept CTTupleWeaklyEqualityComparable = TTTupleWeaklyEqualityComparable<TSequence, USequence>::Value;
|
||||||
|
|
||||||
|
template <typename, typename> struct TTTupleSynthThreeWayComparable;
|
||||||
|
|
||||||
|
template <typename T, typename U, typename... Ts, typename... Us>
|
||||||
|
struct TTTupleSynthThreeWayComparable<TTypeSequence<T, Ts...>, TTypeSequence<U, Us...>>
|
||||||
|
: TBoolConstant<CSynthThreeWayComparable<T, U> && TTTupleSynthThreeWayComparable<TTypeSequence<Ts...>, TTypeSequence<Us...>>::Value>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct TTTupleSynthThreeWayComparable<TTypeSequence<>, TTypeSequence<>> : FTrue { };
|
||||||
|
|
||||||
|
template <typename TSequence, typename USequence>
|
||||||
|
concept CTTupleSynthThreeWayComparable = TTTupleSynthThreeWayComparable<TSequence, USequence>::Value;
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -258,34 +309,34 @@ public:
|
|||||||
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
|
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||||
&& (true && ... && CConstructibleFrom<Ts, const OtherTypes&>)
|
&& (true && ... && CConstructibleFrom<Ts, const Us&>)
|
||||||
&& NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value)
|
&& NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Ts) != 1, Ts..., Us...>::Value)
|
||||||
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(const TTuple<OtherTypes...>& InValue)
|
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<Us&&, Ts>)) TTuple(const TTuple<Us...>& InValue)
|
||||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
|
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||||
&& (true && ... && CConstructibleFrom<Ts, OtherTypes&&>)
|
&& (true && ... && CConstructibleFrom<Ts, Us&&>)
|
||||||
&& NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value)
|
&& NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Ts) != 1, Ts..., Us...>::Value)
|
||||||
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(TTuple<OtherTypes...>&& InValue)
|
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<Us&&, Ts>)) TTuple(TTuple<Us...>&& InValue)
|
||||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
|
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
FORCEINLINE constexpr TTuple(const TTuple&) = default;
|
FORCEINLINE constexpr TTuple(const TTuple&) = default;
|
||||||
FORCEINLINE constexpr TTuple(TTuple&&) = default;
|
FORCEINLINE constexpr TTuple(TTuple&&) = default;
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||||
&& (true && ... && CAssignableFrom<Ts&, const OtherTypes&>))
|
&& (true && ... && CAssignableFrom<Ts&, const Us&>))
|
||||||
FORCEINLINE constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue)
|
FORCEINLINE constexpr TTuple& operator=(const TTuple<Us...>& InValue)
|
||||||
{
|
{
|
||||||
Helper::Assign(*this, InValue);
|
Helper::Assign(*this, InValue);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||||
&& (true && ... && CAssignableFrom<Ts&, OtherTypes&&>))
|
&& (true && ... && CAssignableFrom<Ts&, Us&&>))
|
||||||
FORCEINLINE constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue)
|
FORCEINLINE constexpr TTuple& operator=(TTuple<Us...>&& InValue)
|
||||||
{
|
{
|
||||||
Helper::Assign(*this, MoveTemp(InValue));
|
Helper::Assign(*this, MoveTemp(InValue));
|
||||||
return *this;
|
return *this;
|
||||||
@ -293,6 +344,25 @@ public:
|
|||||||
|
|
||||||
FORCEINLINE constexpr TTuple& operator=(const TTuple&) = default;
|
FORCEINLINE constexpr TTuple& operator=(const TTuple&) = default;
|
||||||
FORCEINLINE constexpr TTuple& operator=(TTuple&&) = default;
|
FORCEINLINE constexpr TTuple& operator=(TTuple&&) = default;
|
||||||
|
|
||||||
|
template <typename... Us> requires (sizeof...(Ts) == sizeof...(Us) && NAMESPACE_PRIVATE::CTTupleWeaklyEqualityComparable<TTypeSequence<Ts...>, TTypeSequence<Us...>>)
|
||||||
|
friend FORCEINLINE constexpr bool operator==(const TTuple& LHS, const TTuple<Us...>& RHS)
|
||||||
|
{
|
||||||
|
if constexpr (sizeof...(Ts) != sizeof...(Us)) return false;
|
||||||
|
|
||||||
|
return [&LHS, &RHS]<size_t... Indices>(TIndexSequence<Indices...>) -> bool
|
||||||
|
{
|
||||||
|
return (true && ... && (LHS.template GetValue<Indices>() == RHS.template GetValue<Indices>()));
|
||||||
|
}
|
||||||
|
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Us> requires (sizeof...(Ts) == sizeof...(Us) && NAMESPACE_PRIVATE::CTTupleSynthThreeWayComparable<TTypeSequence<Ts...>, TTypeSequence<Us...>>)
|
||||||
|
friend FORCEINLINE constexpr TCommonComparisonCategory<TSynthThreeWayResult<Ts, Us>...> operator<=>(const TTuple& LHS, const TTuple<Us...>& RHS)
|
||||||
|
{
|
||||||
|
using R = TCommonComparisonCategory<TSynthThreeWayResult<Ts, Us>...>;
|
||||||
|
return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(Ts)>>::Do(LHS, RHS);
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() & { return static_cast< NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>& >(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() & { return static_cast< NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>& >(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() const & { return static_cast<const NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>& >(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() const & { return static_cast<const NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>& >(*this).GetValue(); }
|
||||||
@ -456,31 +526,6 @@ struct TTupleCatImpl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename R, typename Indices>
|
|
||||||
struct TTupleThreeWay;
|
|
||||||
|
|
||||||
template <typename R, size_t I, size_t... Indices>
|
|
||||||
struct TTupleThreeWay<R, TIndexSequence<I, Indices...>>
|
|
||||||
{
|
|
||||||
template <typename LHSTupleType, typename RHSTupleType>
|
|
||||||
FORCEINLINE static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS)
|
|
||||||
{
|
|
||||||
auto Result = SynthThreeWayCompare(LHS.template GetValue<I>(), RHS.template GetValue<I>());
|
|
||||||
if (Result != 0) return Result;
|
|
||||||
return TTupleThreeWay<R, TIndexSequence<Indices...>>::Do(LHS, RHS);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename R>
|
|
||||||
struct TTupleThreeWay<R, TIndexSequence<>>
|
|
||||||
{
|
|
||||||
template <typename LHSTupleType, typename RHSTupleType>
|
|
||||||
FORCEINLINE static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS)
|
|
||||||
{
|
|
||||||
return R::equivalent;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Indices>
|
template <typename Indices>
|
||||||
struct TTupleVisitImpl;
|
struct TTupleVisitImpl;
|
||||||
|
|
||||||
@ -515,20 +560,6 @@ FORCEINLINE constexpr decltype(auto) TupleCat(TTupleTypes&&... Args)
|
|||||||
else return NAMESPACE_PRIVATE::TTupleCatImpl<R>::Do(Forward<TTupleTypes>(Args)...);
|
else return NAMESPACE_PRIVATE::TTupleCatImpl<R>::Do(Forward<TTupleTypes>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... LHSTypes, typename... RHSTypes> requires (sizeof...(LHSTypes) != sizeof...(RHSTypes) || (true && ... && CWeaklyEqualityComparable<LHSTypes, RHSTypes>))
|
|
||||||
FORCEINLINE constexpr bool operator==(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS)
|
|
||||||
{
|
|
||||||
if constexpr (sizeof...(LHSTypes) != sizeof...(RHSTypes)) return false;
|
|
||||||
return [&LHS, &RHS]<size_t... Indices>(TIndexSequence<Indices...>) -> bool { return (true && ... && (LHS.template GetValue<Indices>() == RHS.template GetValue<Indices>())); } (TMakeIndexSequence<sizeof...(LHSTypes)>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... LHSTypes, typename... RHSTypes> requires (sizeof...(LHSTypes) == sizeof...(RHSTypes) && (true && ... && (CSynthThreeWayComparable<LHSTypes, RHSTypes>)))
|
|
||||||
FORCEINLINE constexpr TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...> operator<=>(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS)
|
|
||||||
{
|
|
||||||
using R = TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...>;
|
|
||||||
return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(LHSTypes)>>::Do(LHS, RHS);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename F, typename FirstTupleType, typename... TupleTypes>
|
template <typename F, typename FirstTupleType, typename... TupleTypes>
|
||||||
requires (CTTuple<TRemoveReference<FirstTupleType>> && (true && ... && CTTuple<TRemoveReference<TupleTypes>>))
|
requires (CTTuple<TRemoveReference<FirstTupleType>> && (true && ... && CTTuple<TRemoveReference<TupleTypes>>))
|
||||||
FORCEINLINE constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples)
|
FORCEINLINE constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples)
|
||||||
|
@ -194,6 +194,42 @@ public:
|
|||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend constexpr bool operator==(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CEqualityComparable<Ts>)
|
||||||
|
{
|
||||||
|
if (LHS.GetIndex() != RHS.GetIndex()) return false;
|
||||||
|
if (LHS.IsValid() == false) return true;
|
||||||
|
|
||||||
|
using FCompareImpl = bool(*)(const void*, const void*);
|
||||||
|
constexpr FCompareImpl CompareImpl[] = { [](const void* LHS, const void* RHS) -> bool { return *reinterpret_cast<const Ts*>(LHS) == *reinterpret_cast<const Ts*>(RHS); }... };
|
||||||
|
|
||||||
|
return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend constexpr partial_ordering operator<=>(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CSynthThreeWayComparable<Ts>)
|
||||||
|
{
|
||||||
|
if (LHS.GetIndex() != RHS.GetIndex()) return partial_ordering::unordered;
|
||||||
|
if (LHS.IsValid() == false) return partial_ordering::equivalent;
|
||||||
|
|
||||||
|
using FCompareImpl = partial_ordering(*)(const void*, const void*);
|
||||||
|
constexpr FCompareImpl CompareImpl[] = { [](const void* LHS, const void* RHS) -> partial_ordering { return SynthThreeWayCompare(*reinterpret_cast<const Ts*>(LHS), *reinterpret_cast<const Ts*>(RHS)); }...};
|
||||||
|
|
||||||
|
return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> requires (!CBaseOf<TVariant, T> && CEqualityComparable<T>)
|
||||||
|
FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
||||||
|
{
|
||||||
|
return HoldsAlternative<T>() ? GetValue<T>() == InValue : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> requires (!CBaseOf<TVariant, T> && CEqualityComparable<T>)
|
||||||
|
FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
||||||
|
{
|
||||||
|
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE constexpr bool operator==(FInvalid) const& { return !IsValid(); }
|
||||||
|
|
||||||
template <size_t I, typename... ArgTypes> requires (I < sizeof...(Ts)
|
template <size_t I, typename... ArgTypes> requires (I < sizeof...(Ts)
|
||||||
&& CConstructibleFrom<TVariantAlternative<I, TVariant<Ts...>>, ArgTypes...>)
|
&& CConstructibleFrom<TVariantAlternative<I, TVariant<Ts...>>, ArgTypes...>)
|
||||||
@ -317,42 +353,8 @@ private:
|
|||||||
TAlignedUnion<1, Ts...> Value;
|
TAlignedUnion<1, Ts...> Value;
|
||||||
uint8 TypeIndex;
|
uint8 TypeIndex;
|
||||||
|
|
||||||
friend constexpr bool operator==(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CEqualityComparable<Ts>)
|
|
||||||
{
|
|
||||||
if (LHS.GetIndex() != RHS.GetIndex()) return false;
|
|
||||||
if (LHS.IsValid() == false) return true;
|
|
||||||
|
|
||||||
using FCompareImpl = bool(*)(const void*, const void*);
|
|
||||||
constexpr FCompareImpl CompareImpl[] = { [](const void* LHS, const void* RHS) -> bool { return *reinterpret_cast<const Ts*>(LHS) == *reinterpret_cast<const Ts*>(RHS); }... };
|
|
||||||
|
|
||||||
return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend constexpr partial_ordering operator<=>(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CSynthThreeWayComparable<Ts>)
|
|
||||||
{
|
|
||||||
if (LHS.GetIndex() != RHS.GetIndex()) return partial_ordering::unordered;
|
|
||||||
if (LHS.IsValid() == false) return partial_ordering::equivalent;
|
|
||||||
|
|
||||||
using FCompareImpl = partial_ordering(*)(const void*, const void*);
|
|
||||||
constexpr FCompareImpl CompareImpl[] = { [](const void* LHS, const void* RHS) -> partial_ordering { return SynthThreeWayCompare(*reinterpret_cast<const Ts*>(LHS), *reinterpret_cast<const Ts*>(RHS)); }...};
|
|
||||||
|
|
||||||
return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Ts> requires (!CBaseOf<TVariant<Ts...>, T> && CEqualityComparable<T>)
|
|
||||||
FORCEINLINE constexpr bool operator==(const TVariant<Ts...>& LHS, const T& RHS)
|
|
||||||
{
|
|
||||||
return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() == RHS : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Ts>
|
|
||||||
FORCEINLINE constexpr bool operator==(const TVariant<Ts...>& LHS, FInvalid)
|
|
||||||
{
|
|
||||||
return !LHS.IsValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
template <typename F, typename... VariantTypes>
|
template <typename F, typename... VariantTypes>
|
||||||
|
Loading…
Reference in New Issue
Block a user