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)...);
|
||||
}
|
||||
|
||||
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&&>)
|
||||
FORCEINLINE FAny(T&& InValue) : FAny(InPlaceType<TDecay<T>>, Forward<T>(InValue))
|
||||
{ }
|
||||
@ -217,7 +217,7 @@ public:
|
||||
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&&>)
|
||||
FORCEINLINE FAny& operator=(T&& InValue)
|
||||
{
|
||||
@ -236,13 +236,13 @@ public:
|
||||
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&
|
||||
{
|
||||
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&
|
||||
{
|
||||
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
||||
@ -289,51 +289,26 @@ public:
|
||||
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);
|
||||
Reset();
|
||||
return;
|
||||
B = MoveTemp(A);
|
||||
A.Reset();
|
||||
}
|
||||
|
||||
if (InValue.IsValid() && !IsValid())
|
||||
else if (!A.IsValid() && B.IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Reset();
|
||||
return;
|
||||
A = MoveTemp(B);
|
||||
B.Reset();
|
||||
}
|
||||
|
||||
if (GetTypeInfo() == InValue.GetTypeInfo())
|
||||
else
|
||||
{
|
||||
switch (GetRepresentation())
|
||||
{
|
||||
case ERepresentation::Empty:
|
||||
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(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
FAny Temp = MoveTemp(*this);
|
||||
*this = MoveTemp(InValue);
|
||||
InValue = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -411,7 +386,7 @@ private:
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -80,12 +80,6 @@ public:
|
||||
ValuePtr = reinterpret_cast<uintptr>(AddressOf(Args));
|
||||
Callable = InCallable;
|
||||
}
|
||||
|
||||
FORCEINLINE constexpr void Swap(TFunctionStorage& InValue)
|
||||
{
|
||||
NAMESPACE_REDCRAFT::Swap(ValuePtr, InValue.ValuePtr);
|
||||
NAMESPACE_REDCRAFT::Swap(Callable, InValue.Callable);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -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);
|
||||
Destroy();
|
||||
Invalidate();
|
||||
B = MoveTemp(A);
|
||||
A.Destroy();
|
||||
A.Invalidate();
|
||||
}
|
||||
else if (InValue.IsValid() && !IsValid())
|
||||
else if (!A.IsValid() && B.IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Destroy();
|
||||
InValue.Invalidate();
|
||||
A = MoveTemp(B);
|
||||
B.Destroy();
|
||||
B.Invalidate();
|
||||
}
|
||||
else
|
||||
{
|
||||
TFunctionStorage Temp = MoveTemp(*this);
|
||||
*this = MoveTemp(InValue);
|
||||
InValue = MoveTemp(Temp);
|
||||
TFunctionStorage Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,8 +481,6 @@ public:
|
||||
FORCEINLINE constexpr bool IsValid() const { return Storage.IsValid(); }
|
||||
FORCEINLINE constexpr explicit operator bool() const { return Storage.IsValid(); }
|
||||
|
||||
FORCEINLINE constexpr void Swap(TFunctionImpl& InValue) { Storage.Swap(InValue.Storage); }
|
||||
|
||||
private:
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
friend FORCEINLINE constexpr void Swap(TFunctionImpl& A, TFunctionImpl& B) requires (!bIsRef) { Swap(A.Storage, B.Storage); }
|
||||
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
@ -647,6 +641,8 @@ public:
|
||||
|
||||
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>
|
||||
@ -735,6 +731,8 @@ public:
|
||||
|
||||
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");
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
}
|
||||
|
||||
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)
|
||||
: 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;
|
||||
return NAMESPACE_REDCRAFT::GetTypeHash(GetValue());
|
||||
if (!A.IsValid()) return 2824517378;
|
||||
return GetTypeHash(A.GetValue());
|
||||
}
|
||||
|
||||
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);
|
||||
Reset();
|
||||
return;
|
||||
B = MoveTemp(A);
|
||||
A.Reset();
|
||||
}
|
||||
|
||||
if (InValue.IsValid() && !IsValid())
|
||||
else if (!A.IsValid() && B.IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Reset();
|
||||
return;
|
||||
A = MoveTemp(B);
|
||||
B.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
Swap(A.GetValue(), B.GetValue());
|
||||
}
|
||||
|
||||
NAMESPACE_REDCRAFT::Swap(GetValue(), InValue.GetValue());
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -47,9 +47,9 @@ public:
|
||||
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:
|
||||
|
@ -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() 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)>());
|
||||
}
|
||||
|
||||
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)>());
|
||||
}
|
||||
|
@ -86,12 +86,6 @@ FORCEINLINE constexpr size_t GetTypeHash(T 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>; })
|
||||
FORCEINLINE constexpr size_t GetTypeHash(const T& A)
|
||||
{
|
||||
|
@ -55,20 +55,12 @@ FORCEINLINE constexpr T&& Forward(TRemoveReference<T>&& Obj)
|
||||
return static_cast<T&&>(Obj);
|
||||
}
|
||||
|
||||
template <typename T> requires (requires(T& A, T& B) { A.Swap(B); }
|
||||
|| (CMoveConstructible<T> && CMoveAssignable<T>))
|
||||
template <typename T> requires (CMoveConstructible<T> && CMoveAssignable<T>)
|
||||
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);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
T Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>)
|
||||
|
@ -120,7 +120,7 @@ public:
|
||||
|
||||
template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; }
|
||||
&& !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))
|
||||
{ }
|
||||
|
||||
@ -217,13 +217,13 @@ public:
|
||||
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&
|
||||
{
|
||||
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&
|
||||
{
|
||||
return HoldsAlternative<T>() ? SynthThreeWayCompare(GetValue<T>(), InValue) : partial_ordering::unordered;
|
||||
@ -287,51 +287,43 @@ public:
|
||||
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;
|
||||
|
||||
using NAMESPACE_REDCRAFT::GetTypeHash;
|
||||
if (!A.IsValid()) return 114514;
|
||||
|
||||
using FHashImpl = size_t(*)(const void*);
|
||||
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);
|
||||
Reset();
|
||||
return;
|
||||
B = MoveTemp(A);
|
||||
A.Reset();
|
||||
}
|
||||
|
||||
if (InValue.IsValid() && !IsValid())
|
||||
else if (!A.IsValid() && B.IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Reset();
|
||||
return;
|
||||
A = MoveTemp(B);
|
||||
B.Reset();
|
||||
}
|
||||
|
||||
if (GetIndex() == InValue.GetIndex())
|
||||
else if (A.GetIndex() == B.GetIndex())
|
||||
{
|
||||
using NAMESPACE_REDCRAFT::Swap;
|
||||
|
||||
using FSwapImpl = void(*)(void*, void*);
|
||||
constexpr FSwapImpl SwapImpl[] = { [](void* A, void* B) { Swap(*reinterpret_cast<Ts*>(A), *reinterpret_cast<Ts*>(B)); }... };
|
||||
|
||||
SwapImpl[GetIndex()](&Value, &InValue.Value);
|
||||
|
||||
return;
|
||||
SwapImpl[A.GetIndex()](&A.Value, &B.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
TVariant Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
TVariant Temp = MoveTemp(*this);
|
||||
*this = MoveTemp(InValue);
|
||||
InValue = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user