refactor(templates): refactor GetTypeHash and Swap to friend
This commit is contained in:
parent
de059cb980
commit
b75cb30f4f
@ -91,7 +91,7 @@ public:
|
|||||||
EmplaceImpl<T>(Forward<Ts>(Args)...);
|
EmplaceImpl<T>(Forward<Ts>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (!CBaseOf<FAny, TDecay<T>> && !CTInPlaceType<TDecay<T>>
|
template <typename T> requires (!CSameAs<FAny, TDecay<T>> && !CTInPlaceType<TDecay<T>>
|
||||||
&& NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, T&&>)
|
&& NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, T&&>)
|
||||||
FORCEINLINE FAny(T&& InValue) : FAny(InPlaceType<TDecay<T>>, Forward<T>(InValue))
|
FORCEINLINE FAny(T&& InValue) : FAny(InPlaceType<TDecay<T>>, Forward<T>(InValue))
|
||||||
{ }
|
{ }
|
||||||
@ -217,7 +217,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (!CBaseOf<FAny, TDecay<T>> && !CTInPlaceType<TDecay<T>>
|
template <typename T> requires (!CSameAs<FAny, TDecay<T>> && !CTInPlaceType<TDecay<T>>
|
||||||
&& NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, T&&>)
|
&& NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, T&&>)
|
||||||
FORCEINLINE FAny& operator=(T&& InValue)
|
FORCEINLINE FAny& operator=(T&& InValue)
|
||||||
{
|
{
|
||||||
@ -236,13 +236,13 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (!CBaseOf<FAny, TRemoveCVRef<T>> && NAMESPACE_PRIVATE::CFAnyPlaceable<T>)
|
template <typename T> requires (!CSameAs<FAny, TRemoveCVRef<T>> && NAMESPACE_PRIVATE::CFAnyPlaceable<T>)
|
||||||
FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
||||||
{
|
{
|
||||||
return HoldsAlternative<T>() ? GetValue<T>() == InValue : false;
|
return HoldsAlternative<T>() ? GetValue<T>() == InValue : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (!CBaseOf<FAny, TRemoveCVRef<T>> && NAMESPACE_PRIVATE::CFAnyPlaceable<T>)
|
template <typename T> requires (!CSameAs<FAny, TRemoveCVRef<T>> && NAMESPACE_PRIVATE::CFAnyPlaceable<T>)
|
||||||
FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
||||||
{
|
{
|
||||||
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
||||||
@ -289,51 +289,26 @@ public:
|
|||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swap(FAny& InValue)
|
friend void Swap(FAny& A, FAny& B)
|
||||||
{
|
{
|
||||||
if (!IsValid() && !InValue.IsValid()) return;
|
if (!A.IsValid() && !B.IsValid()) return;
|
||||||
|
|
||||||
if (IsValid() && !InValue.IsValid())
|
if (A.IsValid() && !B.IsValid())
|
||||||
{
|
{
|
||||||
InValue = MoveTemp(*this);
|
B = MoveTemp(A);
|
||||||
Reset();
|
A.Reset();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (!A.IsValid() && B.IsValid())
|
||||||
if (InValue.IsValid() && !IsValid())
|
|
||||||
{
|
{
|
||||||
*this = MoveTemp(InValue);
|
A = MoveTemp(B);
|
||||||
InValue.Reset();
|
B.Reset();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (GetTypeInfo() == InValue.GetTypeInfo())
|
|
||||||
{
|
{
|
||||||
switch (GetRepresentation())
|
FAny Temp = MoveTemp(A);
|
||||||
{
|
A = MoveTemp(B);
|
||||||
case ERepresentation::Empty:
|
B = MoveTemp(Temp);
|
||||||
break;
|
|
||||||
case ERepresentation::Trivial:
|
|
||||||
uint8 TempBuffer[sizeof(TrivialStorage.Internal)];
|
|
||||||
Memory::Memmove(TempBuffer, TrivialStorage.Internal);
|
|
||||||
Memory::Memmove(TrivialStorage.Internal, InValue.TrivialStorage.Internal);
|
|
||||||
Memory::Memmove(InValue.TrivialStorage.Internal, TempBuffer);
|
|
||||||
break;
|
|
||||||
case ERepresentation::Small:
|
|
||||||
SmallStorage.RTTI->SwapObject(&SmallStorage.Internal, &InValue.SmallStorage.Internal);
|
|
||||||
break;
|
|
||||||
case ERepresentation::Big:
|
|
||||||
NAMESPACE_REDCRAFT::Swap(BigStorage.External, InValue.BigStorage.External);
|
|
||||||
break;
|
|
||||||
default: check_no_entry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FAny Temp = MoveTemp(*this);
|
|
||||||
*this = MoveTemp(InValue);
|
|
||||||
InValue = MoveTemp(Temp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -411,7 +386,7 @@ private:
|
|||||||
{
|
{
|
||||||
if constexpr (CSwappable<T>)
|
if constexpr (CSwappable<T>)
|
||||||
{
|
{
|
||||||
NAMESPACE_REDCRAFT::Swap(*reinterpret_cast<T*>(A), *reinterpret_cast<T*>(B));
|
Swap(*reinterpret_cast<T*>(A), *reinterpret_cast<T*>(B));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -81,12 +81,6 @@ public:
|
|||||||
Callable = InCallable;
|
Callable = InCallable;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE constexpr void Swap(TFunctionStorage& InValue)
|
|
||||||
{
|
|
||||||
NAMESPACE_REDCRAFT::Swap(ValuePtr, InValue.ValuePtr);
|
|
||||||
NAMESPACE_REDCRAFT::Swap(Callable, InValue.Callable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uintptr ValuePtr;
|
uintptr ValuePtr;
|
||||||
@ -295,27 +289,27 @@ public:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swap(TFunctionStorage& InValue)
|
friend void Swap(TFunctionStorage& A, TFunctionStorage& B)
|
||||||
{
|
{
|
||||||
if (!IsValid() && !InValue.IsValid()) return;
|
if (!A.IsValid() && !B.IsValid()) return;
|
||||||
|
|
||||||
if (IsValid() && !InValue.IsValid())
|
if (A.IsValid() && !B.IsValid())
|
||||||
{
|
{
|
||||||
InValue = MoveTemp(*this);
|
B = MoveTemp(A);
|
||||||
Destroy();
|
A.Destroy();
|
||||||
Invalidate();
|
A.Invalidate();
|
||||||
}
|
}
|
||||||
else if (InValue.IsValid() && !IsValid())
|
else if (!A.IsValid() && B.IsValid())
|
||||||
{
|
{
|
||||||
*this = MoveTemp(InValue);
|
A = MoveTemp(B);
|
||||||
InValue.Destroy();
|
B.Destroy();
|
||||||
InValue.Invalidate();
|
B.Invalidate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TFunctionStorage Temp = MoveTemp(*this);
|
TFunctionStorage Temp = MoveTemp(A);
|
||||||
*this = MoveTemp(InValue);
|
A = MoveTemp(B);
|
||||||
InValue = MoveTemp(Temp);
|
B = MoveTemp(Temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,8 +481,6 @@ public:
|
|||||||
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(); }
|
||||||
|
|
||||||
FORCEINLINE constexpr void Swap(TFunctionImpl& InValue) { Storage.Swap(InValue.Storage); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
using CallableType = ResultType(*)(uintptr, Ts&&...);
|
using CallableType = ResultType(*)(uintptr, Ts&&...);
|
||||||
@ -536,6 +528,8 @@ protected: // These functions should not be used by user-defined class
|
|||||||
return *reinterpret_cast<DecayedType*>(Storage.GetValuePtr());
|
return *reinterpret_cast<DecayedType*>(Storage.GetValuePtr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend FORCEINLINE constexpr void Swap(TFunctionImpl& A, TFunctionImpl& B) requires (!bIsRef) { Swap(A.Storage, B.Storage); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
@ -647,6 +641,8 @@ public:
|
|||||||
|
|
||||||
FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
|
FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
|
||||||
|
|
||||||
|
friend FORCEINLINE constexpr void Swap(TFunction& A, TFunction& B) { Swap(static_cast<Impl&>(A), static_cast<Impl&>(B)); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <CFunction F>
|
template <CFunction F>
|
||||||
@ -735,6 +731,8 @@ public:
|
|||||||
|
|
||||||
FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
|
FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
|
||||||
|
|
||||||
|
friend FORCEINLINE constexpr void Swap(TUniqueFunction& A, TUniqueFunction& B) { Swap(static_cast<Impl&>(A), static_cast<Impl&>(B)); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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");
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&>)
|
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&>)
|
||||||
&& (!CSameAs<TRemoveCVRef<T>, FInPlace>) && (!CBaseOf<TOptional, TRemoveCVRef<T>>)
|
&& (!CSameAs<TRemoveCVRef<T>, FInPlace>) && (!CSameAs<TOptional, TRemoveCVRef<T>>)
|
||||||
FORCEINLINE constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(T&& InValue)
|
FORCEINLINE constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(T&& InValue)
|
||||||
: TOptional(InPlace, Forward<T>(InValue))
|
: TOptional(InPlace, Forward<T>(InValue))
|
||||||
{ }
|
{ }
|
||||||
@ -269,32 +269,31 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable<OptionalType>)
|
friend FORCEINLINE constexpr size_t GetTypeHash(const TOptional& A) requires (CHashable<OptionalType>)
|
||||||
{
|
{
|
||||||
if (!IsValid()) return 2824517378;
|
if (!A.IsValid()) return 2824517378;
|
||||||
return NAMESPACE_REDCRAFT::GetTypeHash(GetValue());
|
return GetTypeHash(A.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (CMoveConstructible<OptionalType> && CSwappable<OptionalType>)
|
template <typename T> requires (CMoveConstructible<OptionalType> && CSwappable<OptionalType>)
|
||||||
constexpr void Swap(TOptional& InValue)
|
friend constexpr void Swap(TOptional& A, TOptional& B)
|
||||||
{
|
{
|
||||||
if (!IsValid() && !InValue.IsValid()) return;
|
if (!A.IsValid() && !B.IsValid()) return;
|
||||||
|
|
||||||
if (IsValid() && !InValue.IsValid())
|
if (A.IsValid() && !B.IsValid())
|
||||||
{
|
{
|
||||||
InValue = MoveTemp(*this);
|
B = MoveTemp(A);
|
||||||
Reset();
|
A.Reset();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (!A.IsValid() && B.IsValid())
|
||||||
if (InValue.IsValid() && !IsValid())
|
|
||||||
{
|
{
|
||||||
*this = MoveTemp(InValue);
|
A = MoveTemp(B);
|
||||||
InValue.Reset();
|
B.Reset();
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Swap(A.GetValue(), B.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT::Swap(GetValue(), InValue.GetValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -47,9 +47,9 @@ public:
|
|||||||
return Invoke(Get(), Forward<Ts>(Args)...);
|
return Invoke(Get(), Forward<Ts>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable<ReferencedType>)
|
friend FORCEINLINE constexpr size_t GetTypeHash(TReferenceWrapper A) requires (CHashable<ReferencedType>)
|
||||||
{
|
{
|
||||||
return NAMESPACE_REDCRAFT::GetTypeHash(Get());
|
return GetTypeHash(A.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -409,20 +409,20 @@ public:
|
|||||||
template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() volatile&& { return Helper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); }
|
template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() volatile&& { return Helper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); }
|
||||||
template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() const volatile&& { return Helper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); }
|
template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() const volatile&& { return Helper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); }
|
||||||
|
|
||||||
FORCEINLINE constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Ts>)
|
friend FORCEINLINE constexpr size_t GetTypeHash(const TTuple& A) requires (true && ... && CHashable<Ts>)
|
||||||
{
|
{
|
||||||
return [this]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t
|
return [&A]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t
|
||||||
{
|
{
|
||||||
return HashCombine(NAMESPACE_REDCRAFT::GetTypeHash(GetValue<Indices>())...);
|
return HashCombine(GetTypeHash(A.template GetValue<Indices>())...);
|
||||||
}
|
}
|
||||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible<Ts> && CSwappable<Ts>))
|
friend FORCEINLINE constexpr void Swap(TTuple& A, TTuple& B) requires (true && ... && (CMoveConstructible<Ts> && CSwappable<Ts>))
|
||||||
{
|
{
|
||||||
[&A = *this, &B = InValue]<size_t... Indices>(TIndexSequence<Indices...>)
|
[&A, &B]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||||
{
|
{
|
||||||
((NAMESPACE_REDCRAFT::Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...);
|
((Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...);
|
||||||
}
|
}
|
||||||
(TMakeIndexSequence<sizeof...(Ts)>());
|
(TMakeIndexSequence<sizeof...(Ts)>());
|
||||||
}
|
}
|
||||||
|
@ -86,12 +86,6 @@ FORCEINLINE constexpr size_t GetTypeHash(T A)
|
|||||||
return GetTypeHash(reinterpret_cast<intptr>(A));
|
return GetTypeHash(reinterpret_cast<intptr>(A));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (requires(const T& A) { { GetTypeHash(A.GetTypeHash()) } -> CSameAs<size_t>; })
|
|
||||||
FORCEINLINE constexpr size_t GetTypeHash(const T& A)
|
|
||||||
{
|
|
||||||
return GetTypeHash(A.GetTypeHash());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> requires (requires(const T& A) { { GetTypeHash(A.hash_code()) } -> CSameAs<size_t>; })
|
template <typename T> requires (requires(const T& A) { { GetTypeHash(A.hash_code()) } -> CSameAs<size_t>; })
|
||||||
FORCEINLINE constexpr size_t GetTypeHash(const T& A)
|
FORCEINLINE constexpr size_t GetTypeHash(const T& A)
|
||||||
{
|
{
|
||||||
|
@ -55,21 +55,13 @@ FORCEINLINE constexpr T&& Forward(TRemoveReference<T>&& Obj)
|
|||||||
return static_cast<T&&>(Obj);
|
return static_cast<T&&>(Obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (requires(T& A, T& B) { A.Swap(B); }
|
template <typename T> requires (CMoveConstructible<T> && CMoveAssignable<T>)
|
||||||
|| (CMoveConstructible<T> && CMoveAssignable<T>))
|
|
||||||
FORCEINLINE constexpr void Swap(T& A, T& B)
|
FORCEINLINE constexpr void Swap(T& A, T& B)
|
||||||
{
|
|
||||||
if constexpr (requires(T& A, T& B) { A.Swap(B); })
|
|
||||||
{
|
|
||||||
A.Swap(B);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
T Temp = MoveTemp(A);
|
T Temp = MoveTemp(A);
|
||||||
A = MoveTemp(B);
|
A = MoveTemp(B);
|
||||||
B = MoveTemp(Temp);
|
B = MoveTemp(Temp);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>)
|
template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>)
|
||||||
FORCEINLINE constexpr T Exchange(T& A, U&& B)
|
FORCEINLINE constexpr T Exchange(T& A, U&& B)
|
||||||
|
@ -120,7 +120,7 @@ public:
|
|||||||
|
|
||||||
template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; }
|
template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; }
|
||||||
&& !CTInPlaceType<TRemoveCVRef<T>> && !CTInPlaceIndex<TRemoveCVRef<T>>
|
&& !CTInPlaceType<TRemoveCVRef<T>> && !CTInPlaceIndex<TRemoveCVRef<T>>
|
||||||
&& !CBaseOf<TVariant, TRemoveCVRef<T>>)
|
&& !CSameAs<TVariant, TRemoveCVRef<T>>)
|
||||||
FORCEINLINE constexpr TVariant(T&& InValue) : TVariant(InPlaceType<NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>>, Forward<T>(InValue))
|
FORCEINLINE constexpr TVariant(T&& InValue) : TVariant(InPlaceType<NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>>, Forward<T>(InValue))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@ -217,13 +217,13 @@ public:
|
|||||||
return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value);
|
return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (!CBaseOf<TVariant, T> && CEqualityComparable<T>)
|
template <typename T> requires (!CSameAs<TVariant, T> && CEqualityComparable<T>)
|
||||||
FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
FORCEINLINE constexpr bool operator==(const T& InValue) const&
|
||||||
{
|
{
|
||||||
return HoldsAlternative<T>() ? GetValue<T>() == InValue : false;
|
return HoldsAlternative<T>() ? GetValue<T>() == InValue : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (!CBaseOf<TVariant, T> && CEqualityComparable<T>)
|
template <typename T> requires (!CSameAs<TVariant, T> && CEqualityComparable<T>)
|
||||||
FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
FORCEINLINE constexpr partial_ordering operator<=>(const T& InValue) const&
|
||||||
{
|
{
|
||||||
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
||||||
@ -287,51 +287,43 @@ public:
|
|||||||
TypeIndex = static_cast<uint8>(INDEX_NONE);
|
TypeIndex = static_cast<uint8>(INDEX_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Ts>)
|
friend FORCEINLINE constexpr size_t GetTypeHash(const TVariant& A) requires (true && ... && CHashable<Ts>)
|
||||||
{
|
{
|
||||||
if (!IsValid()) return 114514;
|
if (!A.IsValid()) return 114514;
|
||||||
|
|
||||||
using NAMESPACE_REDCRAFT::GetTypeHash;
|
|
||||||
|
|
||||||
using FHashImpl = size_t(*)(const void*);
|
using FHashImpl = size_t(*)(const void*);
|
||||||
constexpr FHashImpl HashImpl[] = { [](const void* This) -> size_t { return GetTypeHash(*reinterpret_cast<const Ts*>(This)); }... };
|
constexpr FHashImpl HashImpl[] = { [](const void* This) -> size_t { return GetTypeHash(*reinterpret_cast<const Ts*>(This)); }... };
|
||||||
|
|
||||||
return HashCombine(GetTypeHash(GetIndex()), HashImpl[GetIndex()](&Value));
|
return HashCombine(GetTypeHash(A.GetIndex()), HashImpl[A.GetIndex()](&A.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void Swap(TVariant& InValue) requires (true && ... && (CMoveConstructible<Ts> && CSwappable<Ts>))
|
friend constexpr void Swap(TVariant& A, TVariant& B) requires (true && ... && (CMoveConstructible<Ts> && CSwappable<Ts>))
|
||||||
{
|
{
|
||||||
if (!IsValid() && !InValue.IsValid()) return;
|
if (!A.IsValid() && !B.IsValid()) return;
|
||||||
|
|
||||||
if (IsValid() && !InValue.IsValid())
|
if (A.IsValid() && !B.IsValid())
|
||||||
{
|
{
|
||||||
InValue = MoveTemp(*this);
|
B = MoveTemp(A);
|
||||||
Reset();
|
A.Reset();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (!A.IsValid() && B.IsValid())
|
||||||
if (InValue.IsValid() && !IsValid())
|
|
||||||
{
|
{
|
||||||
*this = MoveTemp(InValue);
|
A = MoveTemp(B);
|
||||||
InValue.Reset();
|
B.Reset();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (A.GetIndex() == B.GetIndex())
|
||||||
if (GetIndex() == InValue.GetIndex())
|
|
||||||
{
|
{
|
||||||
using NAMESPACE_REDCRAFT::Swap;
|
|
||||||
|
|
||||||
using FSwapImpl = void(*)(void*, void*);
|
using FSwapImpl = void(*)(void*, void*);
|
||||||
constexpr FSwapImpl SwapImpl[] = { [](void* A, void* B) { Swap(*reinterpret_cast<Ts*>(A), *reinterpret_cast<Ts*>(B)); }... };
|
constexpr FSwapImpl SwapImpl[] = { [](void* A, void* B) { Swap(*reinterpret_cast<Ts*>(A), *reinterpret_cast<Ts*>(B)); }... };
|
||||||
|
|
||||||
SwapImpl[GetIndex()](&Value, &InValue.Value);
|
SwapImpl[A.GetIndex()](&A.Value, &B.Value);
|
||||||
|
}
|
||||||
return;
|
else
|
||||||
|
{
|
||||||
|
TVariant Temp = MoveTemp(A);
|
||||||
|
A = MoveTemp(B);
|
||||||
|
B = MoveTemp(Temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
TVariant Temp = MoveTemp(*this);
|
|
||||||
*this = MoveTemp(InValue);
|
|
||||||
InValue = MoveTemp(Temp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user