refactor(templates): refactor Swap into a member function
This commit is contained in:
parent
5c82ab1e0d
commit
018d3afb73
@ -91,6 +91,15 @@ void AnyMoveAssign(void* Target, void* Source)
|
||||
|
||||
using FAnyMoveAssignFunc = void(*)(void*, void*);
|
||||
|
||||
template <typename T>
|
||||
void AnySwap(void* A, void* B)
|
||||
{
|
||||
if constexpr (TIsSwappable<T>::Value) Swap(*reinterpret_cast<T*>(A), *reinterpret_cast<T*>(B));
|
||||
else check_no_entry();
|
||||
}
|
||||
|
||||
using FAnySwapFunc = void(*)(void*, void*);
|
||||
|
||||
struct FAnyRTTI
|
||||
{
|
||||
bool bIsInline;
|
||||
@ -102,6 +111,7 @@ struct FAnyRTTI
|
||||
FAnyMoveConstructFunc MoveConstruct;
|
||||
FAnyCopyAssignFunc CopyAssign;
|
||||
FAnyMoveAssignFunc MoveAssign;
|
||||
FAnySwapFunc SwapObject;
|
||||
};
|
||||
|
||||
template <typename T, bool bInIsInline>
|
||||
@ -118,6 +128,7 @@ struct TAnyRTTIHelper
|
||||
AnyMoveConstruct<T>,
|
||||
AnyCopyAssign<T>,
|
||||
AnyMoveAssign<T>,
|
||||
AnySwap<T>,
|
||||
};
|
||||
};
|
||||
|
||||
@ -315,6 +326,35 @@ struct TAny
|
||||
ResetImpl();
|
||||
}
|
||||
|
||||
constexpr void Swap(TAny& InValue)
|
||||
{
|
||||
if (!IsValid() && !InValue.IsValid()) return;
|
||||
|
||||
if (IsValid() && !InValue.IsValid())
|
||||
{
|
||||
InValue = MoveTemp(*this);
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (InValue.IsValid() && !IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetTypeInfo() == InValue.GetTypeInfo())
|
||||
{
|
||||
RTTI->SwapObject(GetData(), InValue.GetData());
|
||||
return;
|
||||
}
|
||||
|
||||
TAny Temp = MoveTemp(*this);
|
||||
*this = MoveTemp(InValue);
|
||||
InValue = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
union
|
||||
@ -369,30 +409,6 @@ constexpr bool operator==(const TAny<InlineSize, InlineAlignment>& LHS, FInvalid
|
||||
return !LHS.IsValid();
|
||||
}
|
||||
|
||||
template <size_t InlineSize, size_t InlineAlignment>
|
||||
constexpr void Swap(TAny<InlineSize, InlineAlignment>& A, TAny<InlineSize, InlineAlignment>& B)
|
||||
{
|
||||
if (!A && !B) return;
|
||||
|
||||
if (A && !B)
|
||||
{
|
||||
B = MoveTemp(A);
|
||||
A.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (B && !A)
|
||||
{
|
||||
A = MoveTemp(B);
|
||||
B.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
TAny<InlineSize, InlineAlignment> Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
template <typename T> struct TIsTAny : FFalse { };
|
||||
template <size_t InlineSize, size_t InlineAlignment> struct TIsTAny<TAny<InlineSize, InlineAlignment>> : FTrue { };
|
||||
|
||||
|
@ -292,6 +292,28 @@ public:
|
||||
|
||||
constexpr void Reset() requires (FunctionType != EFunctionType::Reference) { Call = nullptr; }
|
||||
|
||||
constexpr void Swap(TFunctionImpl& InValue) requires (FunctionType != EFunctionType::Reference)
|
||||
{
|
||||
if (!IsValid() && !InValue.IsValid()) return;
|
||||
|
||||
if (IsValid() && !InValue.IsValid())
|
||||
{
|
||||
InValue = MoveTemp(*this);
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (InValue.IsValid() && !IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
NAMESPACE_REDCRAFT::Swap(Call, InValue.Call);
|
||||
NAMESPACE_REDCRAFT::Swap(Storage, InValue.Storage);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
using CallFunc = ResultType(*)(void*, Types&&...);
|
||||
@ -412,54 +434,6 @@ constexpr bool operator==(const TUniqueFunction<F>& LHS, nullptr_t)
|
||||
return !LHS;
|
||||
}
|
||||
|
||||
template <typename F, size_t I, size_t J>
|
||||
constexpr void Swap(TFunction<F, I, J>& A, TFunction<F, I, J>& B)
|
||||
{
|
||||
if (!A && !B) return;
|
||||
|
||||
if (A && !B)
|
||||
{
|
||||
B = MoveTemp(A);
|
||||
A = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (B && !A)
|
||||
{
|
||||
A = MoveTemp(B);
|
||||
B = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
TFunction<F, I, J> Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
template <typename F, size_t I, size_t J>
|
||||
constexpr void Swap(TUniqueFunction<F, I, J>& A, TUniqueFunction<F, I, J>& B)
|
||||
{
|
||||
if (!A && !B) return;
|
||||
|
||||
if (A && !B)
|
||||
{
|
||||
B = MoveTemp(A);
|
||||
A = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (B && !A)
|
||||
{
|
||||
A = MoveTemp(B);
|
||||
B = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
TFunction<F, I, J> Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
static_assert(sizeof(TFunctionRef<void()>) == 16, "The byte size of TFunctionRef 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");
|
||||
|
@ -225,6 +225,28 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> requires TIsMoveConstructible<OptionalType>::Value && TIsSwappable<OptionalType>::Value
|
||||
constexpr void Swap(TOptional& InValue)
|
||||
{
|
||||
if (!IsValid() && !InValue.IsValid()) return;
|
||||
|
||||
if (IsValid() && !InValue.IsValid())
|
||||
{
|
||||
InValue = MoveTemp(*this);
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (InValue.IsValid() && !IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
NAMESPACE_REDCRAFT::Swap(GetValue(), InValue.GetValue());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
TAlignedStorage<sizeof(OptionalType), alignof(OptionalType)>::Type Value;
|
||||
@ -273,28 +295,6 @@ constexpr TOptional<T> MakeOptional(Types&&... Args)
|
||||
return TOptional<T>(InPlace, Forward<T>(Args)...);
|
||||
}
|
||||
|
||||
template <typename T> requires TIsMoveConstructible<T>::Value&& TIsSwappable<T>::Value
|
||||
constexpr void Swap(TOptional<T>& A, TOptional<T>& B)
|
||||
{
|
||||
if (!A && !B) return;
|
||||
|
||||
if (A && !B)
|
||||
{
|
||||
B = MoveTemp(A);
|
||||
A.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (B && !A)
|
||||
{
|
||||
A = MoveTemp(B);
|
||||
B.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
Swap(*A, *B);
|
||||
}
|
||||
|
||||
template <typename T> struct TIsTOptional : FFalse { };
|
||||
template <typename T> struct TIsTOptional<TOptional<T>> : FTrue { };
|
||||
|
||||
|
@ -207,6 +207,11 @@ protected:
|
||||
return T(Forward<TTupleType>(Arg).template GetValue<Indices>()...);
|
||||
}
|
||||
|
||||
template <typename TTupleType>
|
||||
static constexpr void Swap(TTupleType& A, TTupleType& B)
|
||||
{
|
||||
((NAMESPACE_REDCRAFT::Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...);
|
||||
}
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
@ -371,6 +376,11 @@ public:
|
||||
|
||||
constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Types>);
|
||||
|
||||
constexpr void Swap(TTuple& InValue) requires (true && ... && (TIsMoveConstructible<Types>::Value&& TIsSwappable<Types>::Value))
|
||||
{
|
||||
Super::Swap(*this, InValue);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <typename... Types>
|
||||
@ -517,19 +527,6 @@ struct TTupleThreeWay<R, TIndexSequence<>>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indices>
|
||||
struct TTupleSwapImpl;
|
||||
|
||||
template <size_t... Indices>
|
||||
struct TTupleSwapImpl<TIndexSequence<Indices...>>
|
||||
{
|
||||
template <typename TTupleType>
|
||||
static constexpr void F(TTupleType& A, TTupleType& B)
|
||||
{
|
||||
((Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indices>
|
||||
struct TTupleVisitImpl;
|
||||
|
||||
@ -578,12 +575,6 @@ constexpr typename TCommonComparisonCategory<typename TSynthThreeWayResult<LHSTy
|
||||
return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(LHSTypes)>>::F(LHS, RHS);
|
||||
}
|
||||
|
||||
template <typename... Types> requires (true && ... && (TIsMoveConstructible<Types>::Value && TIsSwappable<Types>::Value))
|
||||
constexpr void Swap(TTuple<Types...>& A, TTuple<Types...>& B)
|
||||
{
|
||||
NAMESPACE_PRIVATE::TTupleSwapImpl<TIndexSequenceFor<Types...>>::F(A, B);
|
||||
}
|
||||
|
||||
template <typename F> requires TIsInvocable<F>::Value
|
||||
constexpr void VisitTuple(F&& Func) { }
|
||||
|
||||
|
@ -61,12 +61,20 @@ constexpr T&& Forward(typename TRemoveReference<T>::Type&& Obj)
|
||||
return (T&&)Obj;
|
||||
}
|
||||
|
||||
template <typename T> requires TIsMoveConstructible<T>::Value && TIsMoveAssignable<T>::Value
|
||||
template <typename T> requires requires(T& A, T& B) { A.Swap(B); }
|
||||
|| (TIsMoveConstructible<T>::Value && TIsMoveAssignable<T>::Value)
|
||||
constexpr void Swap(T& A, T& B)
|
||||
{
|
||||
T Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
if constexpr (requires(T& A, T& B) { A.Swap(B); })
|
||||
{
|
||||
A.Swap(B);
|
||||
}
|
||||
else
|
||||
{
|
||||
T Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename U = T> requires TIsMoveConstructible<T>::Value && TIsAssignable<T&, U>::Value
|
||||
|
@ -132,6 +132,15 @@ constexpr bool VariantEqualityOperator(const void* LHS, const void* RHS)
|
||||
|
||||
using FVariantEqualityOperatorFunc = bool(*)(const void*, const void*);
|
||||
|
||||
template <typename T>
|
||||
constexpr void VariantSwap(void* A, void* B)
|
||||
{
|
||||
if constexpr (TIsSwappable<T>::Value) Swap(*reinterpret_cast<T*>(A), *reinterpret_cast<T*>(B));
|
||||
else check_no_entry();
|
||||
}
|
||||
|
||||
using FVariantSwapFunc = void(*)(void*, void*);
|
||||
|
||||
template <typename... Types>
|
||||
struct TVariantHelper
|
||||
{
|
||||
@ -141,6 +150,7 @@ struct TVariantHelper
|
||||
static constexpr FVariantCopyAssignFunc CopyAssignFuncs[] = { VariantCopyAssign<Types>... };
|
||||
static constexpr FVariantMoveAssignFunc MoveAssignFuncs[] = { VariantMoveAssign<Types>... };
|
||||
static constexpr FVariantEqualityOperatorFunc EqualityOperatorFuncs[] = { VariantEqualityOperator<Types>... };
|
||||
static constexpr FVariantSwapFunc SwapFuncs[] = { VariantSwap<Types>... };
|
||||
};
|
||||
|
||||
template <typename R, typename F, typename T>
|
||||
@ -425,6 +435,35 @@ struct TVariant
|
||||
|
||||
TypeIndex = INDEX_NONE;
|
||||
}
|
||||
|
||||
constexpr void Swap(TVariant& InValue) requires (true && ... && (TIsMoveConstructible<Types>::Value && TIsSwappable<Types>::Value))
|
||||
{
|
||||
if (!IsValid() && !InValue.IsValid()) return;
|
||||
|
||||
if (IsValid() && !InValue.IsValid())
|
||||
{
|
||||
InValue = MoveTemp(*this);
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (InValue.IsValid() && !IsValid())
|
||||
{
|
||||
*this = MoveTemp(InValue);
|
||||
InValue.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetIndex() == InValue.GetIndex())
|
||||
{
|
||||
FHelper::SwapFuncs[GetIndex()](GetData(), InValue.GetData());
|
||||
return;
|
||||
}
|
||||
|
||||
TVariant Temp = MoveTemp(*this);
|
||||
*this = MoveTemp(InValue);
|
||||
InValue = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -454,30 +493,6 @@ constexpr bool operator==(const TVariant<Types...>& LHS, FInvalid)
|
||||
return !LHS.IsValid();
|
||||
}
|
||||
|
||||
template <typename... Types> requires (true && ... && (TIsMoveConstructible<Types>::Value && TIsSwappable<Types>::Value))
|
||||
constexpr void Swap(TVariant<Types...>& A, TVariant<Types...>& B)
|
||||
{
|
||||
if (!A && !B) return;
|
||||
|
||||
if (A && !B)
|
||||
{
|
||||
B = MoveTemp(A);
|
||||
A.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (B && !A)
|
||||
{
|
||||
A = MoveTemp(B);
|
||||
B.Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
TVariant<Types...> Temp = MoveTemp(A);
|
||||
A = MoveTemp(B);
|
||||
B = MoveTemp(Temp);
|
||||
}
|
||||
|
||||
template <typename T > struct TIsTVariant : FFalse { };
|
||||
template <typename... Types> struct TIsTVariant<TVariant<Types...>> : FTrue { };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user