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 == 300);
|
||||
always_check(300 == TempO);
|
||||
always_check(TempO >= 200);
|
||||
always_check(400 >= TempO);
|
||||
|
||||
int16 TempQ = 1024;
|
||||
TOptional<int16> TempR = TempQ;
|
||||
@ -221,6 +223,8 @@ void TestVariant()
|
||||
always_check(TempO == TempO);
|
||||
always_check(TempO == 300);
|
||||
always_check(300 == TempO);
|
||||
always_check(TempO >= 200);
|
||||
always_check(400 >= TempO);
|
||||
|
||||
Swap(TempD, TempA);
|
||||
|
||||
@ -428,7 +432,7 @@ void TestAny()
|
||||
int32 A;
|
||||
FIntegral() { }
|
||||
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
|
||||
@ -437,7 +441,7 @@ void TestAny()
|
||||
uint8 Pad[64];
|
||||
FFloating() { }
|
||||
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
|
||||
@ -474,6 +478,8 @@ void TestAny()
|
||||
always_check(TempO.IsValid());
|
||||
|
||||
always_check(TempO == 404);
|
||||
always_check(TempO >= 400);
|
||||
always_check(500 >= TempO);
|
||||
always_check(TempO.GetValue<int32>() == 404);
|
||||
always_check(TempO.Get<int32>(500) == 404);
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "Memory/Alignment.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
|
||||
@ -237,6 +236,20 @@ public:
|
||||
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&&...>)
|
||||
FORCEINLINE TDecay<T>& Emplace(Ts&&... Args)
|
||||
{
|
||||
@ -527,17 +540,6 @@ private:
|
||||
|
||||
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");
|
||||
|
@ -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 constexpr bool operator==(nullptr_t) const& { return !IsValid(); }
|
||||
|
||||
FORCEINLINE constexpr bool IsValid() 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));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TFunctionRef(const T&& InValue) = delete;
|
||||
|
||||
};
|
||||
|
||||
template <CFunction F>
|
||||
@ -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(TUniqueFunction<void()>) == 64, "The byte size of TUniqueFunction is unexpected");
|
||||
|
||||
|
@ -16,6 +16,9 @@ class TOptional;
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename T> struct TIsTOptional : FFalse { };
|
||||
template <typename T> struct TIsTOptional<TOptional<T>> : FTrue { };
|
||||
|
||||
template <typename T, typename U>
|
||||
concept CTOptionalAllowUnwrappable =
|
||||
!(CConstructibleFrom<U, TOptional<T>& >
|
||||
@ -33,6 +36,8 @@ concept CTOptionalAllowUnwrappable =
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <typename T> concept CTOptional = NAMESPACE_PRIVATE::TIsTOptional<TRemoveCV<T>>::Value;
|
||||
|
||||
template <typename OptionalType> requires (CDestructible<OptionalType>)
|
||||
class TOptional
|
||||
{
|
||||
@ -193,6 +198,36 @@ public:
|
||||
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...>)
|
||||
FORCEINLINE constexpr OptionalType& Emplace(ArgTypes&&... Args)
|
||||
{
|
||||
@ -272,34 +307,6 @@ private:
|
||||
template <typename 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>)
|
||||
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)...);
|
||||
}
|
||||
|
||||
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(Redcraft)
|
||||
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
|
||||
|
||||
template <typename T>
|
||||
@ -258,34 +309,34 @@ public:
|
||||
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
|
||||
{ }
|
||||
|
||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
||||
&& (true && ... && CConstructibleFrom<Ts, const OtherTypes&>)
|
||||
&& NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value)
|
||||
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(const TTuple<OtherTypes...>& InValue)
|
||||
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||
&& (true && ... && CConstructibleFrom<Ts, const Us&>)
|
||||
&& NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Ts) != 1, Ts..., Us...>::Value)
|
||||
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<Us&&, Ts>)) TTuple(const TTuple<Us...>& InValue)
|
||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
|
||||
{ }
|
||||
|
||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
||||
&& (true && ... && CConstructibleFrom<Ts, OtherTypes&&>)
|
||||
&& NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value)
|
||||
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(TTuple<OtherTypes...>&& InValue)
|
||||
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||
&& (true && ... && CConstructibleFrom<Ts, Us&&>)
|
||||
&& NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Ts) != 1, Ts..., Us...>::Value)
|
||||
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<Us&&, Ts>)) TTuple(TTuple<Us...>&& InValue)
|
||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
|
||||
{ }
|
||||
|
||||
FORCEINLINE constexpr TTuple(const TTuple&) = default;
|
||||
FORCEINLINE constexpr TTuple(TTuple&&) = default;
|
||||
|
||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
||||
&& (true && ... && CAssignableFrom<Ts&, const OtherTypes&>))
|
||||
FORCEINLINE constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue)
|
||||
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||
&& (true && ... && CAssignableFrom<Ts&, const Us&>))
|
||||
FORCEINLINE constexpr TTuple& operator=(const TTuple<Us...>& InValue)
|
||||
{
|
||||
Helper::Assign(*this, InValue);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
|
||||
&& (true && ... && CAssignableFrom<Ts&, OtherTypes&&>))
|
||||
FORCEINLINE constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue)
|
||||
template <typename... Us> requires (sizeof...(Us) == sizeof...(Ts)
|
||||
&& (true && ... && CAssignableFrom<Ts&, Us&&>))
|
||||
FORCEINLINE constexpr TTuple& operator=(TTuple<Us...>&& InValue)
|
||||
{
|
||||
Helper::Assign(*this, MoveTemp(InValue));
|
||||
return *this;
|
||||
@ -294,6 +345,25 @@ public:
|
||||
FORCEINLINE constexpr TTuple& operator=(const 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() 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() volatile& { return static_cast< volatile 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>
|
||||
struct TTupleVisitImpl;
|
||||
|
||||
@ -515,20 +560,6 @@ FORCEINLINE constexpr decltype(auto) TupleCat(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>
|
||||
requires (CTTuple<TRemoveReference<FirstTupleType>> && (true && ... && CTTuple<TRemoveReference<TupleTypes>>))
|
||||
FORCEINLINE constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples)
|
||||
|
@ -195,6 +195,42 @@ public:
|
||||
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)
|
||||
&& CConstructibleFrom<TVariantAlternative<I, TVariant<Ts...>>, ArgTypes...>)
|
||||
FORCEINLINE constexpr TVariantAlternative<I, TVariant<Ts...>>& Emplace(ArgTypes&&... Args)
|
||||
@ -317,42 +353,8 @@ private:
|
||||
TAlignedUnion<1, Ts...> Value;
|
||||
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
|
||||
|
||||
template <typename F, typename... VariantTypes>
|
||||
|
Loading…
Reference in New Issue
Block a user