refactor(templates): add FORCEINLINE to the constexpr function

This commit is contained in:
_Redstone_c_ 2022-12-13 22:02:39 +08:00
parent 89c173897e
commit ac9e0d38a6
14 changed files with 381 additions and 386 deletions

View File

@ -10,7 +10,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_BEGIN(Memory) NAMESPACE_BEGIN(Memory)
constexpr bool IsValidAlignment(size_t Alignment) { return !(Alignment & (Alignment - 1)); } FORCEINLINE constexpr bool IsValidAlignment(size_t Alignment) { return !(Alignment & (Alignment - 1)); }
template <typename T> requires (CIntegral<T> || CPointer<T>) template <typename T> requires (CIntegral<T> || CPointer<T>)
FORCEINLINE constexpr T Align(T InValue, size_t Alignment) FORCEINLINE constexpr T Align(T InValue, size_t Alignment)

View File

@ -63,7 +63,7 @@ template <typename T, typename U = T, typename OrderingType = partial_ordering>
concept CSynthThreeWayComparable = CThreeWayComparable<T, U> || CTotallyOrdered<T, U>; concept CSynthThreeWayComparable = CThreeWayComparable<T, U> || CTotallyOrdered<T, U>;
template <typename T, typename U = T> requires (CSynthThreeWayComparable<T, U>) template <typename T, typename U = T> requires (CSynthThreeWayComparable<T, U>)
constexpr decltype(auto) SynthThreeWayCompare(T&& LHS, U&& RHS) FORCEINLINE constexpr decltype(auto) SynthThreeWayCompare(T&& LHS, U&& RHS)
{ {
if constexpr (CThreeWayComparable<T, U>) if constexpr (CThreeWayComparable<T, U>)
{ {

View File

@ -68,8 +68,8 @@ public:
static constexpr size_t RequiredAlignment = NAMESPACE_STD::atomic_ref<T>::required_alignment; static constexpr size_t RequiredAlignment = NAMESPACE_STD::atomic_ref<T>::required_alignment;
constexpr TAtomicImpl() requires (!bIsRef) : NativeAtomic() { }; FORCEINLINE constexpr TAtomicImpl() requires (!bIsRef) : NativeAtomic() { };
constexpr TAtomicImpl(ValueType Desired) requires (!bIsRef) : NativeAtomic(Desired) { }; FORCEINLINE constexpr TAtomicImpl(ValueType Desired) requires (!bIsRef) : NativeAtomic(Desired) { };
FORCEINLINE explicit TAtomicImpl(ValueType& Desired) requires (bIsRef) : NativeAtomic(Desired) { check(Memory::IsAligned(&Desired, RequiredAlignment)); }; FORCEINLINE explicit TAtomicImpl(ValueType& Desired) requires (bIsRef) : NativeAtomic(Desired) { check(Memory::IsAligned(&Desired, RequiredAlignment)); };
FORCEINLINE TAtomicImpl(TAtomicImpl& InValue) requires (bIsRef) : NativeAtomic(InValue) { }; FORCEINLINE TAtomicImpl(TAtomicImpl& InValue) requires (bIsRef) : NativeAtomic(InValue) { };
@ -247,7 +247,7 @@ struct FAtomicFlag : FSingleton
{ {
public: public:
constexpr FAtomicFlag() : NativeAtomic() { }; FORCEINLINE constexpr FAtomicFlag() : NativeAtomic() { };
FORCEINLINE void Clear(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.clear(static_cast<NAMESPACE_STD::memory_order>(Order)); } FORCEINLINE void Clear(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.clear(static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Clear(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.clear(static_cast<NAMESPACE_STD::memory_order>(Order)); } FORCEINLINE void Clear(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.clear(static_cast<NAMESPACE_STD::memory_order>(Order)); }

View File

@ -7,47 +7,47 @@ NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
template <typename T> requires (requires(T&& Container) { Container.GetData(); }) template <typename T> requires (requires(T&& Container) { Container.GetData(); })
constexpr decltype(auto) GetData(T&& Container) FORCEINLINE constexpr decltype(auto) GetData(T&& Container)
{ {
return Container.GetData(); return Container.GetData();
} }
template <typename T, size_t N> constexpr T* GetData( T(& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(& Container)[N]) { return Container; }
template <typename T, size_t N> constexpr T* GetData( T(&& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr T* GetData( T(&& Container)[N]) { return Container; }
template <typename T, size_t N> constexpr const T* GetData(const T(& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(& Container)[N]) { return Container; }
template <typename T, size_t N> constexpr const T* GetData(const T(&& Container)[N]) { return Container; } template <typename T, size_t N> FORCEINLINE constexpr const T* GetData(const T(&& Container)[N]) { return Container; }
template <typename T> requires (requires(T&& Container) { Container.data(); }) template <typename T> requires (requires(T&& Container) { Container.data(); })
constexpr decltype(auto) GetData(T&& Container) FORCEINLINE constexpr decltype(auto) GetData(T&& Container)
{ {
return Container.data(); return Container.data();
} }
template <typename T> template <typename T>
constexpr decltype(auto) GetData(initializer_list<T> Container) FORCEINLINE constexpr decltype(auto) GetData(initializer_list<T> Container)
{ {
return Container.begin(); return Container.begin();
} }
template <typename T> requires (requires(T&& Container) { Container.Num(); }) template <typename T> requires (requires(T&& Container) { Container.Num(); })
constexpr decltype(auto) GetNum(T&& Container) FORCEINLINE constexpr decltype(auto) GetNum(T&& Container)
{ {
return Container.Num(); return Container.Num();
} }
template <typename T, size_t N> constexpr size_t GetNum( T(& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(& Container)[N]) { return N; }
template <typename T, size_t N> constexpr size_t GetNum( T(&& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum( T(&& Container)[N]) { return N; }
template <typename T, size_t N> constexpr size_t GetNum(const T(& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(& Container)[N]) { return N; }
template <typename T, size_t N> constexpr size_t GetNum(const T(&& Container)[N]) { return N; } template <typename T, size_t N> FORCEINLINE constexpr size_t GetNum(const T(&& Container)[N]) { return N; }
template <typename T> requires (requires(T&& Container) { Container.size(); }) template <typename T> requires (requires(T&& Container) { Container.size(); })
constexpr decltype(auto) GetNum(T&& Container) FORCEINLINE constexpr decltype(auto) GetNum(T&& Container)
{ {
return Container.size(); return Container.size();
} }
template <typename T> template <typename T>
constexpr decltype(auto) GetNum(initializer_list<T> Container) FORCEINLINE constexpr decltype(auto) GetNum(initializer_list<T> Container)
{ {
return Container.size(); return Container.size();
} }

View File

@ -54,34 +54,34 @@ class TFunctionStorage<true, bIsUnique>
{ {
public: public:
constexpr TFunctionStorage() = default; FORCEINLINE constexpr TFunctionStorage() = default;
constexpr TFunctionStorage(const TFunctionStorage&) = default; FORCEINLINE constexpr TFunctionStorage(const TFunctionStorage&) = default;
constexpr TFunctionStorage(TFunctionStorage&&) = default; FORCEINLINE constexpr TFunctionStorage(TFunctionStorage&&) = default;
constexpr TFunctionStorage& operator=(const TFunctionStorage&) = delete; FORCEINLINE constexpr TFunctionStorage& operator=(const TFunctionStorage&) = delete;
constexpr TFunctionStorage& operator=(TFunctionStorage&&) = delete; FORCEINLINE constexpr TFunctionStorage& operator=(TFunctionStorage&&) = delete;
constexpr ~TFunctionStorage() = default; FORCEINLINE constexpr ~TFunctionStorage() = default;
constexpr uintptr GetValuePtr() const { return ValuePtr; } FORCEINLINE constexpr uintptr GetValuePtr() const { return ValuePtr; }
constexpr uintptr GetCallable() const { return Callable; } FORCEINLINE constexpr uintptr GetCallable() const { return Callable; }
constexpr bool IsValid() const { return ValuePtr != 0; } FORCEINLINE constexpr bool IsValid() const { return ValuePtr != 0; }
// Use Invalidate() to invalidate the storage or use Emplace<T>() to emplace a new object after destruction. // Use Invalidate() to invalidate the storage or use Emplace<T>() to emplace a new object after destruction.
constexpr void Destroy() { } FORCEINLINE constexpr void Destroy() { }
// Make sure you call this function after you have destroyed the held object using Destroy(). // Make sure you call this function after you have destroyed the held object using Destroy().
constexpr void Invalidate() { ValuePtr = 0; } FORCEINLINE constexpr void Invalidate() { ValuePtr = 0; }
// Make sure you call this function after you have destroyed the held object using Destroy(). // Make sure you call this function after you have destroyed the held object using Destroy().
template <typename T, typename U> template <typename T, typename U>
constexpr void Emplace(intptr InCallable, U&& Args) FORCEINLINE constexpr void Emplace(intptr InCallable, U&& Args)
{ {
static_assert(CSameAs<TDecay<T>, TDecay<U>>); static_assert(CSameAs<TDecay<T>, TDecay<U>>);
ValuePtr = reinterpret_cast<uintptr>(AddressOf(Args)); ValuePtr = reinterpret_cast<uintptr>(AddressOf(Args));
Callable = InCallable; Callable = InCallable;
} }
constexpr void Swap(TFunctionStorage& InValue) FORCEINLINE constexpr void Swap(TFunctionStorage& InValue)
{ {
NAMESPACE_REDCRAFT::Swap(ValuePtr, InValue.ValuePtr); NAMESPACE_REDCRAFT::Swap(ValuePtr, InValue.ValuePtr);
NAMESPACE_REDCRAFT::Swap(Callable, InValue.Callable); NAMESPACE_REDCRAFT::Swap(Callable, InValue.Callable);
@ -101,7 +101,7 @@ class alignas(16) TFunctionStorage<false, bIsUnique>
{ {
public: public:
constexpr TFunctionStorage() = default; FORCEINLINE constexpr TFunctionStorage() = default;
FORCEINLINE TFunctionStorage(const TFunctionStorage& InValue) requires (!bIsUnique) FORCEINLINE TFunctionStorage(const TFunctionStorage& InValue) requires (!bIsUnique)
: TypeInfo(InValue.TypeInfo) : TypeInfo(InValue.TypeInfo)
@ -232,10 +232,10 @@ public:
return *this; return *this;
} }
constexpr uintptr GetValuePtr() const { return reinterpret_cast<uintptr>(GetStorage()); } FORCEINLINE constexpr uintptr GetValuePtr() const { return reinterpret_cast<uintptr>(GetStorage()); }
constexpr uintptr GetCallable() const { return Callable; } FORCEINLINE constexpr uintptr GetCallable() const { return Callable; }
constexpr bool IsValid() const { return TypeInfo != 0; } FORCEINLINE constexpr bool IsValid() const { return TypeInfo != 0; }
// Use Invalidate() to invalidate the storage or use Emplace<T>() to emplace a new object after destruction. // Use Invalidate() to invalidate the storage or use Emplace<T>() to emplace a new object after destruction.
FORCEINLINE void Destroy() FORCEINLINE void Destroy()
@ -259,7 +259,7 @@ public:
} }
// Make sure you call this function after you have destroyed the held object using Destroy(). // Make sure you call this function after you have destroyed the held object using Destroy().
constexpr void Invalidate() { TypeInfo = 0; } FORCEINLINE constexpr void Invalidate() { TypeInfo = 0; }
// Make sure you call this function after you have destroyed the held object using Destroy(). // Make sure you call this function after you have destroyed the held object using Destroy().
template <typename T, typename... Ts> template <typename T, typename... Ts>
@ -342,7 +342,7 @@ private:
const FDestruct Destruct; const FDestruct Destruct;
template <typename T> template <typename T>
constexpr FMovableTypeInfo(TInPlaceType<T>) FORCEINLINE constexpr FMovableTypeInfo(TInPlaceType<T>)
: TypeSize(sizeof(T)), TypeAlignment(alignof(T)) : TypeSize(sizeof(T)), TypeAlignment(alignof(T))
, MoveConstruct( , MoveConstruct(
[](void* A, void* B) [](void* A, void* B)
@ -366,7 +366,7 @@ private:
const FCopyConstruct CopyConstruct; const FCopyConstruct CopyConstruct;
template <typename T> template <typename T>
constexpr FCopyableTypeInfo(TInPlaceType<T>) FORCEINLINE constexpr FCopyableTypeInfo(TInPlaceType<T>)
: FMovableTypeInfo(InPlaceType<T>) : FMovableTypeInfo(InPlaceType<T>)
, CopyConstruct( , CopyConstruct(
[](void* A, const void* B) [](void* A, const void* B)
@ -391,16 +391,16 @@ private:
Big = 3, // ExternalStorage Big = 3, // ExternalStorage
}; };
constexpr ERepresentation GetRepresentation() const { return static_cast<ERepresentation>(TypeInfo & RepresentationMask); } FORCEINLINE constexpr ERepresentation GetRepresentation() const { return static_cast<ERepresentation>(TypeInfo & RepresentationMask); }
constexpr const FTypeInfo& GetTypeInfo() const { return *reinterpret_cast<const FTypeInfo*>(TypeInfo & ~RepresentationMask); } FORCEINLINE constexpr const FTypeInfo& GetTypeInfo() const { return *reinterpret_cast<const FTypeInfo*>(TypeInfo & ~RepresentationMask); }
constexpr void* GetStorage() { return GetRepresentation() == ERepresentation::Trivial || GetRepresentation() == ERepresentation::Small ? InternalStorage : ExternalStorage; } FORCEINLINE constexpr void* GetStorage() { return GetRepresentation() == ERepresentation::Trivial || GetRepresentation() == ERepresentation::Small ? InternalStorage : ExternalStorage; }
constexpr const void* GetStorage() const { return GetRepresentation() == ERepresentation::Trivial || GetRepresentation() == ERepresentation::Small ? InternalStorage : ExternalStorage; } FORCEINLINE constexpr const void* GetStorage() const { return GetRepresentation() == ERepresentation::Trivial || GetRepresentation() == ERepresentation::Small ? InternalStorage : ExternalStorage; }
}; };
template <typename T> template <typename T>
constexpr bool FunctionIsBound(const T& Func) FORCEINLINE constexpr bool FunctionIsBound(const T& Func)
{ {
if constexpr (CPointer<T> || CMemberPointer<T> || CTFunctionRef<T> || CTFunction<T> || CTUniqueFunction<T>) if constexpr (CPointer<T> || CMemberPointer<T> || CTFunctionRef<T> || CTFunction<T> || CTUniqueFunction<T>)
{ {
@ -448,12 +448,12 @@ public:
using ResultType = Ret; using ResultType = Ret;
using ArgumentType = TTypeSequence<Ts...>; using ArgumentType = TTypeSequence<Ts...>;
constexpr TFunctionImpl() = default; FORCEINLINE constexpr TFunctionImpl() = default;
constexpr TFunctionImpl(const TFunctionImpl&) = default; FORCEINLINE constexpr TFunctionImpl(const TFunctionImpl&) = default;
constexpr TFunctionImpl(TFunctionImpl&&) = default; FORCEINLINE constexpr TFunctionImpl(TFunctionImpl&&) = default;
constexpr TFunctionImpl& operator=(const TFunctionImpl&) = default; FORCEINLINE constexpr TFunctionImpl& operator=(const TFunctionImpl&) = default;
constexpr TFunctionImpl& operator=(TFunctionImpl&&) = default; FORCEINLINE constexpr TFunctionImpl& operator=(TFunctionImpl&&) = default;
constexpr ~TFunctionImpl() = default; FORCEINLINE constexpr ~TFunctionImpl() = default;
FORCEINLINE ResultType operator()(Ts... Args) requires (CSameAs<CVRef, int >) { return CallImpl(Forward<Ts>(Args)...); } FORCEINLINE ResultType operator()(Ts... Args) requires (CSameAs<CVRef, int >) { return CallImpl(Forward<Ts>(Args)...); }
FORCEINLINE ResultType operator()(Ts... Args) & requires (CSameAs<CVRef, int& >) { return CallImpl(Forward<Ts>(Args)...); } FORCEINLINE ResultType operator()(Ts... Args) & requires (CSameAs<CVRef, int& >) { return CallImpl(Forward<Ts>(Args)...); }
@ -462,10 +462,10 @@ 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)...); }
constexpr bool IsValid() const { return Storage.IsValid(); } FORCEINLINE constexpr bool IsValid() const { return Storage.IsValid(); }
constexpr explicit operator bool() const { return Storage.IsValid(); } FORCEINLINE constexpr explicit operator bool() const { return Storage.IsValid(); }
constexpr void Swap(TFunctionImpl& InValue) { Storage.Swap(InValue.Storage); } FORCEINLINE constexpr void Swap(TFunctionImpl& InValue) { Storage.Swap(InValue.Storage); }
private: private:
@ -483,14 +483,14 @@ private:
protected: // These functions should not be used by user-defined class protected: // These functions should not be used by user-defined class
// Use Invalidate() to invalidate the storage or use Emplace<T>() to emplace a new object after destruction. // Use Invalidate() to invalidate the storage or use Emplace<T>() to emplace a new object after destruction.
FORCEINLINE void Destroy() { Storage.Destroy(); } FORCEINLINE constexpr void Destroy() { Storage.Destroy(); }
// Make sure you call this function after you have destroyed the held object using Destroy(). // Make sure you call this function after you have destroyed the held object using Destroy().
constexpr void Invalidate() { Storage.Invalidate(); } FORCEINLINE constexpr void Invalidate() { Storage.Invalidate(); }
// Make sure you call this function after you have destroyed the held object using Destroy(). // Make sure you call this function after you have destroyed the held object using Destroy().
template <typename T, typename... ArgTypes> template <typename T, typename... ArgTypes>
FORCEINLINE TDecay<T>& Emplace(ArgTypes&&... Args) FORCEINLINE constexpr TDecay<T>& Emplace(ArgTypes&&... Args)
{ {
using DecayedType = TDecay<T>; using DecayedType = TDecay<T>;
@ -534,20 +534,20 @@ private:
public: public:
TFunctionRef() = delete; FORCEINLINE constexpr TFunctionRef() = delete;
TFunctionRef(const TFunctionRef& InValue) = default; FORCEINLINE constexpr TFunctionRef(const TFunctionRef& InValue) = default;
TFunctionRef(TFunctionRef&& InValue) = default; FORCEINLINE constexpr TFunctionRef(TFunctionRef&& InValue) = default;
// We delete the assignment operators because we don't want it to be confused with being related to // We delete the assignment operators because we don't want it to be confused with being related to
// regular C++ reference assignment - i.e. calling the assignment operator of whatever the reference // regular C++ reference assignment - i.e. calling the assignment operator of whatever the reference
// is bound to - because that's not what TFunctionRef does, nor is it even capable of doing that. // is bound to - because that's not what TFunctionRef does, nor is it even capable of doing that.
TFunctionRef& operator=(const TFunctionRef& InValue) = delete; FORCEINLINE constexpr TFunctionRef& operator=(const TFunctionRef& InValue) = delete;
TFunctionRef& operator=(TFunctionRef&& InValue) = delete; FORCEINLINE constexpr TFunctionRef& operator=(TFunctionRef&& InValue) = delete;
template <typename T> requires (!CTFunctionRef<TDecay<T>> template <typename T> requires (!CTFunctionRef<TDecay<T>>
&& NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value) && NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value)
FORCEINLINE TFunctionRef(T&& InValue) FORCEINLINE constexpr TFunctionRef(T&& InValue)
{ {
checkf(NAMESPACE_PRIVATE::FunctionIsBound(InValue), TEXT("Cannot bind a null/unbound callable to a TFunctionRef")); checkf(NAMESPACE_PRIVATE::FunctionIsBound(InValue), TEXT("Cannot bind a null/unbound callable to a TFunctionRef"));
Impl::template Emplace<T>(Forward<T>(InValue)); Impl::template Emplace<T>(Forward<T>(InValue));
@ -571,7 +571,7 @@ private:
public: public:
constexpr TFunction(nullptr_t = nullptr) { Impl::Invalidate(); } FORCEINLINE constexpr TFunction(nullptr_t = nullptr) { Impl::Invalidate(); }
FORCEINLINE TFunction(const TFunction& InValue) = default; FORCEINLINE TFunction(const TFunction& InValue) = default;
FORCEINLINE TFunction(TFunction&& InValue) = default; FORCEINLINE TFunction(TFunction&& InValue) = default;
@ -592,12 +592,12 @@ public:
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...> && CCopyConstructible<TDecay<T>> && CConstructibleFrom<TDecay<T>, ArgTypes...> && CCopyConstructible<TDecay<T>>
&& CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>) && CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE TFunction(TInPlaceType<T>, ArgTypes&&... Args) FORCEINLINE explicit TFunction(TInPlaceType<T>, ArgTypes&&... Args)
{ {
Impl::template Emplace<T>(Forward<ArgTypes>(Args)...); Impl::template Emplace<T>(Forward<ArgTypes>(Args)...);
} }
constexpr TFunction& operator=(nullptr_t) { Reset(); return *this; } FORCEINLINE constexpr TFunction& operator=(nullptr_t) { Reset(); return *this; }
template <typename T> requires (NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value template <typename T> requires (NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value
&& !CTFunctionRef<TDecay<T>> && !CTFunction<TDecay<T>> && !CTUniqueFunction<TDecay<T>> && !CTFunctionRef<TDecay<T>> && !CTFunction<TDecay<T>> && !CTUniqueFunction<TDecay<T>>
@ -620,7 +620,7 @@ public:
return Impl::template Emplace<T>(Forward<ArgTypes>(Args)...); return Impl::template Emplace<T>(Forward<ArgTypes>(Args)...);
} }
constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); } FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
}; };
@ -640,7 +640,7 @@ private:
public: public:
constexpr TUniqueFunction(nullptr_t = nullptr) { Impl::Invalidate(); } FORCEINLINE constexpr TUniqueFunction(nullptr_t = nullptr) { Impl::Invalidate(); }
FORCEINLINE TUniqueFunction(const TUniqueFunction& InValue) = delete; FORCEINLINE TUniqueFunction(const TUniqueFunction& InValue) = delete;
FORCEINLINE TUniqueFunction(TUniqueFunction&& InValue) = default; FORCEINLINE TUniqueFunction(TUniqueFunction&& InValue) = default;
@ -681,12 +681,12 @@ public:
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 TUniqueFunction(TInPlaceType<T>, ArgTypes&&... Args) FORCEINLINE explicit TUniqueFunction(TInPlaceType<T>, ArgTypes&&... Args)
{ {
Impl::template Emplace<T>(Forward<ArgTypes>(Args)...); Impl::template Emplace<T>(Forward<ArgTypes>(Args)...);
} }
constexpr TUniqueFunction& operator=(nullptr_t) { Impl::Destroy(); Impl::Invalidate(); return *this; } FORCEINLINE constexpr TUniqueFunction& operator=(nullptr_t) { Impl::Destroy(); Impl::Invalidate(); return *this; }
template <typename T> requires (NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value template <typename T> requires (NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value
&& !CTFunctionRef<TDecay<T>> && !CTFunction<TDecay<T>> && !CTUniqueFunction<TDecay<T>> && !CTFunctionRef<TDecay<T>> && !CTFunction<TDecay<T>> && !CTUniqueFunction<TDecay<T>>
@ -708,24 +708,24 @@ public:
return Impl::template Emplace<T>(Forward<ArgTypes>(Args)...); return Impl::template Emplace<T>(Forward<ArgTypes>(Args)...);
} }
constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); } FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
}; };
template <CFunction F> template <CFunction F>
constexpr bool operator==(const TFunctionRef<F>& LHS, nullptr_t) FORCEINLINE constexpr bool operator==(const TFunctionRef<F>& LHS, nullptr_t)
{ {
return !LHS; return !LHS;
} }
template <CFunction F> template <CFunction F>
constexpr bool operator==(const TFunction<F>& LHS, nullptr_t) FORCEINLINE constexpr bool operator==(const TFunction<F>& LHS, nullptr_t)
{ {
return !LHS; return !LHS;
} }
template <CFunction F> template <CFunction F>
constexpr bool operator==(const TUniqueFunction<F>& LHS, nullptr_t) FORCEINLINE constexpr bool operator==(const TUniqueFunction<F>& LHS, nullptr_t)
{ {
return !LHS; return !LHS;
} }
@ -743,35 +743,29 @@ struct TNotFunction
{ {
F Storage; F Storage;
TNotFunction(const TNotFunction&) = default;
TNotFunction(TNotFunction&&) = default;
template <typename InF>
constexpr TNotFunction(InF&& InFunc) : Storage(Forward<InF>(InFunc)) { }
template <typename... Ts> requires (CInvocable<F&, Ts&&...>) template <typename... Ts> requires (CInvocable<F&, Ts&&...>)
constexpr auto operator()(Ts&&... Args) & FORCEINLINE constexpr auto operator()(Ts&&... Args) &
-> decltype(!Invoke(Storage, Forward<Ts>(Args)...)) -> decltype(!Invoke(Storage, Forward<Ts>(Args)...))
{ {
return !Invoke(Storage, Forward<Ts>(Args)...); return !Invoke(Storage, Forward<Ts>(Args)...);
} }
template <typename... Ts> requires (CInvocable<F&&, Ts&&...>) template <typename... Ts> requires (CInvocable<F&&, Ts&&...>)
constexpr auto operator()(Ts&&... Args) && FORCEINLINE constexpr auto operator()(Ts&&... Args) &&
-> decltype(!Invoke(MoveTemp(Storage), Forward<Ts>(Args)...)) -> decltype(!Invoke(MoveTemp(Storage), Forward<Ts>(Args)...))
{ {
return !Invoke(MoveTemp(Storage), Forward<Ts>(Args)...); return !Invoke(MoveTemp(Storage), Forward<Ts>(Args)...);
} }
template <typename... Ts> requires (CInvocable<const F&, Ts&&...>) template <typename... Ts> requires (CInvocable<const F&, Ts&&...>)
constexpr auto operator()(Ts&&... Args) const& FORCEINLINE constexpr auto operator()(Ts&&... Args) const&
-> decltype(!Invoke(Storage, Forward<Ts>(Args)...)) -> decltype(!Invoke(Storage, Forward<Ts>(Args)...))
{ {
return !Invoke(Storage, Forward<Ts>(Args)...); return !Invoke(Storage, Forward<Ts>(Args)...);
} }
template <typename... Ts> requires (CInvocable<const F&&, Ts&&...>) template <typename... Ts> requires (CInvocable<const F&&, Ts&&...>)
constexpr auto operator()(Ts&&... Args) const&& FORCEINLINE constexpr auto operator()(Ts&&... Args) const&&
-> decltype(!Invoke(MoveTemp(Storage), Forward<Ts>(Args)...)) -> decltype(!Invoke(MoveTemp(Storage), Forward<Ts>(Args)...))
{ {
return !Invoke(MoveTemp(Storage), Forward<Ts>(Args)...); return !Invoke(MoveTemp(Storage), Forward<Ts>(Args)...);
@ -781,9 +775,9 @@ struct TNotFunction
NAMESPACE_PRIVATE_END NAMESPACE_PRIVATE_END
template <typename F> requires (CConstructibleFrom<F, F&&>) template <typename F> requires (CConstructibleFrom<F, F&&>)
constexpr NAMESPACE_PRIVATE::TNotFunction<TDecay<F>> NotFn(F&& Func) FORCEINLINE constexpr NAMESPACE_PRIVATE::TNotFunction<TDecay<F>> NotFn(F&& Func)
{ {
return NAMESPACE_PRIVATE::TNotFunction<TDecay<F>>(Forward<F>(Func)); return { Forward<F>(Func) };
} }
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)

View File

@ -82,14 +82,14 @@ struct InvokeImpl<F, T, Ts...> : InvokeMember<F, T> { };
NAMESPACE_PRIVATE_END NAMESPACE_PRIVATE_END
template <typename F, typename... Ts> requires (CInvocable<F, Ts...>) template <typename F, typename... Ts> requires (CInvocable<F, Ts...>)
constexpr auto Invoke(F&& Func, Ts&&... Args) FORCEINLINE constexpr auto Invoke(F&& Func, Ts&&... Args)
-> decltype(NAMESPACE_PRIVATE::InvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...)) -> decltype(NAMESPACE_PRIVATE::InvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...))
{ {
return NAMESPACE_PRIVATE::InvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...); return NAMESPACE_PRIVATE::InvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...);
} }
template <typename R, typename F, typename... Ts> requires (CInvocableResult<R, F, Ts...>) template <typename R, typename F, typename... Ts> requires (CInvocableResult<R, F, Ts...>)
constexpr R InvokeResult(F&& Func, Ts&&... Args) FORCEINLINE constexpr R InvokeResult(F&& Func, Ts&&... Args)
{ {
if constexpr (CVoid<R>) Invoke(Forward<F>(Func), Forward<Ts>(Args)...); if constexpr (CVoid<R>) Invoke(Forward<F>(Func), Forward<Ts>(Args)...);
else return Invoke(Forward<F>(Func), Forward<Ts>(Args)...); else return Invoke(Forward<F>(Func), Forward<Ts>(Args)...);

View File

@ -13,8 +13,8 @@ template <typename T, T... Ints>
struct TIntegerSequence struct TIntegerSequence
{ {
using ValueType = T; using ValueType = T;
static constexpr size_t Num() { return sizeof...(Ints); } FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); }
static constexpr const T* GetData() { return NAMESPACE_REDCRAFT::GetData({ Ints... }); } FORCEINLINE static constexpr const T* GetData() { return NAMESPACE_REDCRAFT::GetData({ Ints... }); }
}; };
NAMESPACE_PRIVATE_BEGIN NAMESPACE_PRIVATE_BEGIN

View File

@ -36,12 +36,12 @@ public:
using ValueType = OptionalType; using ValueType = OptionalType;
constexpr TOptional() : bIsValid(false) { } FORCEINLINE constexpr TOptional() : bIsValid(false) { }
constexpr TOptional(FInvalid) : TOptional() { } FORCEINLINE constexpr TOptional(FInvalid) : TOptional() { }
template <typename... Ts> requires (CConstructibleFrom<OptionalType, Ts...>) template <typename... Ts> requires (CConstructibleFrom<OptionalType, Ts...>)
constexpr explicit TOptional(FInPlace, Ts&&... Args) FORCEINLINE constexpr explicit TOptional(FInPlace, Ts&&... Args)
: bIsValid(true) : bIsValid(true)
{ {
new (&Value) OptionalType(Forward<Ts>(Args)...); new (&Value) OptionalType(Forward<Ts>(Args)...);
@ -49,50 +49,50 @@ 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>) && (!CBaseOf<TOptional, TRemoveCVRef<T>>)
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))
{ } { }
constexpr TOptional(const TOptional& InValue) requires (CTriviallyCopyConstructible<OptionalType>) = default; FORCEINLINE constexpr TOptional(const TOptional& InValue) requires (CTriviallyCopyConstructible<OptionalType>) = default;
constexpr TOptional(const TOptional& InValue) requires (CCopyConstructible<OptionalType> && !CTriviallyCopyConstructible<OptionalType>) FORCEINLINE constexpr TOptional(const TOptional& InValue) requires (CCopyConstructible<OptionalType> && !CTriviallyCopyConstructible<OptionalType>)
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
if (InValue.IsValid()) new (&Value) OptionalType(InValue.GetValue()); if (InValue.IsValid()) new (&Value) OptionalType(InValue.GetValue());
} }
constexpr TOptional(TOptional&& InValue) requires (CTriviallyMoveConstructible<OptionalType>) = default; FORCEINLINE constexpr TOptional(TOptional&& InValue) requires (CTriviallyMoveConstructible<OptionalType>) = default;
constexpr TOptional(TOptional&& InValue) requires (CMoveConstructible<OptionalType> && !CTriviallyMoveConstructible<OptionalType>) FORCEINLINE constexpr TOptional(TOptional&& InValue) requires (CMoveConstructible<OptionalType> && !CTriviallyMoveConstructible<OptionalType>)
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
if (InValue.IsValid()) new (&Value) OptionalType(MoveTemp(InValue.GetValue())); if (InValue.IsValid()) new (&Value) OptionalType(MoveTemp(InValue.GetValue()));
} }
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&> && TAllowUnwrapping<T>::Value) template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&> && TAllowUnwrapping<T>::Value)
constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue) FORCEINLINE constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue)
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
if (InValue.IsValid()) new (&Value) OptionalType(InValue.GetValue()); if (InValue.IsValid()) new (&Value) OptionalType(InValue.GetValue());
} }
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&> && TAllowUnwrapping<T>::Value) template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&> && TAllowUnwrapping<T>::Value)
constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(TOptional<T>&& InValue) FORCEINLINE constexpr explicit (!CConvertibleTo<T&&, OptionalType>) TOptional(TOptional<T>&& InValue)
: bIsValid(InValue.IsValid()) : bIsValid(InValue.IsValid())
{ {
if (InValue.IsValid()) new (&Value) OptionalType(MoveTemp(InValue.GetValue())); if (InValue.IsValid()) new (&Value) OptionalType(MoveTemp(InValue.GetValue()));
} }
constexpr ~TOptional() requires (CTriviallyDestructible<OptionalType>) = default; FORCEINLINE constexpr ~TOptional() requires (CTriviallyDestructible<OptionalType>) = default;
constexpr ~TOptional() requires (!CTriviallyDestructible<OptionalType>) FORCEINLINE constexpr ~TOptional() requires (!CTriviallyDestructible<OptionalType>)
{ {
Reset(); Reset();
} }
constexpr TOptional& operator=(const TOptional& InValue) requires (CTriviallyCopyConstructible<OptionalType> && CTriviallyCopyAssignable<OptionalType>) = default; FORCEINLINE constexpr TOptional& operator=(const TOptional& InValue) requires (CTriviallyCopyConstructible<OptionalType> && CTriviallyCopyAssignable<OptionalType>) = default;
constexpr TOptional& operator=(const TOptional& InValue) requires (CCopyConstructible<OptionalType> && CCopyAssignable<OptionalType> FORCEINLINE constexpr TOptional& operator=(const TOptional& InValue) requires (CCopyConstructible<OptionalType> && CCopyAssignable<OptionalType>
&& !CTriviallyCopyConstructible<OptionalType> && !CTriviallyCopyAssignable<OptionalType>) && !CTriviallyCopyConstructible<OptionalType> && !CTriviallyCopyAssignable<OptionalType>)
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -113,9 +113,9 @@ public:
return *this; return *this;
} }
constexpr TOptional& operator=(TOptional&& InValue) requires (CTriviallyMoveConstructible<OptionalType> && CTriviallyMoveAssignable<OptionalType>) = default; FORCEINLINE constexpr TOptional& operator=(TOptional&& InValue) requires (CTriviallyMoveConstructible<OptionalType> && CTriviallyMoveAssignable<OptionalType>) = default;
constexpr TOptional& operator=(TOptional&& InValue) requires (CMoveConstructible<OptionalType> && CMoveAssignable<OptionalType> FORCEINLINE constexpr TOptional& operator=(TOptional&& InValue) requires (CMoveConstructible<OptionalType> && CMoveAssignable<OptionalType>
&& !CTriviallyMoveConstructible<OptionalType> && !CTriviallyMoveAssignable<OptionalType>) && !CTriviallyMoveConstructible<OptionalType> && !CTriviallyMoveAssignable<OptionalType>)
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -138,7 +138,7 @@ public:
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&> template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&>
&& CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value) && CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value)
constexpr TOptional& operator=(const TOptional<T>& InValue) FORCEINLINE constexpr TOptional& operator=(const TOptional<T>& InValue)
{ {
if (!InValue.IsValid()) if (!InValue.IsValid())
{ {
@ -158,7 +158,7 @@ public:
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&> template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&>
&& CAssignableFrom<OptionalType&, T&&> && TAllowUnwrapping<T>::Value) && CAssignableFrom<OptionalType&, T&&> && TAllowUnwrapping<T>::Value)
constexpr TOptional& operator=(TOptional<T>&& InValue) FORCEINLINE constexpr TOptional& operator=(TOptional<T>&& InValue)
{ {
if (!InValue.IsValid()) if (!InValue.IsValid())
{ {
@ -177,7 +177,7 @@ public:
} }
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&>) template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&>)
constexpr TOptional& operator=(T&& InValue) FORCEINLINE constexpr TOptional& operator=(T&& InValue)
{ {
if (IsValid()) GetValue() = Forward<T>(InValue); if (IsValid()) GetValue() = Forward<T>(InValue);
else else
@ -190,7 +190,7 @@ public:
} }
template <typename... ArgTypes> requires (CConstructibleFrom<OptionalType, ArgTypes...>) template <typename... ArgTypes> requires (CConstructibleFrom<OptionalType, ArgTypes...>)
constexpr OptionalType& Emplace(ArgTypes&&... Args) FORCEINLINE constexpr OptionalType& Emplace(ArgTypes&&... Args)
{ {
Reset(); Reset();
@ -200,26 +200,26 @@ public:
return *Result; return *Result;
} }
constexpr bool IsValid() const { return bIsValid; } FORCEINLINE constexpr bool IsValid() const { return bIsValid; }
constexpr explicit operator bool() const { return bIsValid; } FORCEINLINE constexpr explicit operator bool() const { return bIsValid; }
constexpr OptionalType& GetValue() & { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return *reinterpret_cast< OptionalType*>(&Value); } FORCEINLINE constexpr OptionalType& GetValue() & { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return *reinterpret_cast< OptionalType*>(&Value); }
constexpr OptionalType&& GetValue() && { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast< OptionalType*>(&Value)); } FORCEINLINE constexpr OptionalType&& GetValue() && { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast< OptionalType*>(&Value)); }
constexpr const OptionalType& GetValue() const& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const OptionalType*>(&Value); } FORCEINLINE constexpr const OptionalType& GetValue() const& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const OptionalType*>(&Value); }
constexpr const OptionalType&& GetValue() const&& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast<const OptionalType*>(&Value)); } FORCEINLINE constexpr const OptionalType&& GetValue() const&& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast<const OptionalType*>(&Value)); }
constexpr const OptionalType* operator->() const { return &GetValue(); } FORCEINLINE constexpr const OptionalType* operator->() const { return &GetValue(); }
constexpr OptionalType* operator->() { return &GetValue(); } FORCEINLINE constexpr OptionalType* operator->() { return &GetValue(); }
constexpr OptionalType& operator*() & { return GetValue(); } FORCEINLINE constexpr OptionalType& operator*() & { return GetValue(); }
constexpr OptionalType&& operator*() && { return GetValue(); } FORCEINLINE constexpr OptionalType&& operator*() && { return GetValue(); }
constexpr const OptionalType& operator*() const& { return GetValue(); } FORCEINLINE constexpr const OptionalType& operator*() const& { return GetValue(); }
constexpr const OptionalType&& operator*() const&& { return GetValue(); } FORCEINLINE constexpr const OptionalType&& operator*() const&& { return GetValue(); }
constexpr OptionalType& Get( OptionalType& DefaultValue) & { return IsValid() ? GetValue() : DefaultValue; } FORCEINLINE constexpr OptionalType& Get( OptionalType& DefaultValue) & { return IsValid() ? GetValue() : DefaultValue; }
constexpr const OptionalType& Get(const OptionalType& DefaultValue) const& { return IsValid() ? GetValue() : DefaultValue; } FORCEINLINE constexpr const OptionalType& Get(const OptionalType& DefaultValue) const& { return IsValid() ? GetValue() : DefaultValue; }
constexpr void Reset() FORCEINLINE constexpr void Reset()
{ {
if (bIsValid) if (bIsValid)
{ {
@ -230,14 +230,14 @@ public:
} }
} }
constexpr size_t GetTypeHash() const requires (CHashable<OptionalType>) FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable<OptionalType>)
{ {
if (!IsValid()) return 2824517378; if (!IsValid()) return 2824517378;
return NAMESPACE_REDCRAFT::GetTypeHash(GetValue()); return NAMESPACE_REDCRAFT::GetTypeHash(GetValue());
} }
template <typename T> requires (CMoveConstructible<OptionalType> && CSwappable<OptionalType>) template <typename T> requires (CMoveConstructible<OptionalType> && CSwappable<OptionalType>)
constexpr void Swap(TOptional& InValue) FORCEINLINE constexpr void Swap(TOptional& InValue)
{ {
if (!IsValid() && !InValue.IsValid()) return; if (!IsValid() && !InValue.IsValid()) return;
@ -269,7 +269,7 @@ template <typename T>
TOptional(T) -> TOptional<T>; TOptional(T) -> TOptional<T>;
template <typename T, typename U> requires (CWeaklyEqualityComparable<T, U>) template <typename T, typename U> requires (CWeaklyEqualityComparable<T, U>)
constexpr bool operator==(const TOptional<T>& LHS, const TOptional<U>& RHS) FORCEINLINE constexpr bool operator==(const TOptional<T>& LHS, const TOptional<U>& RHS)
{ {
if (LHS.IsValid() != RHS.IsValid()) return false; if (LHS.IsValid() != RHS.IsValid()) return false;
if (LHS.IsValid() == false) return true; if (LHS.IsValid() == false) return true;
@ -277,7 +277,7 @@ constexpr bool operator==(const TOptional<T>& LHS, const TOptional<U>& RHS)
} }
template <typename T, typename U> requires (CSynthThreeWayComparable<T, U>) template <typename T, typename U> requires (CSynthThreeWayComparable<T, U>)
constexpr partial_ordering operator<=>(const TOptional<T>& LHS, const TOptional<U>& RHS) 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() != RHS.IsValid()) return partial_ordering::unordered;
if (LHS.IsValid() == false) return partial_ordering::equivalent; if (LHS.IsValid() == false) return partial_ordering::equivalent;
@ -285,31 +285,31 @@ constexpr partial_ordering operator<=>(const TOptional<T>& LHS, const TOptional<
} }
template <typename T, typename U> requires (CWeaklyEqualityComparable<T, U>) template <typename T, typename U> requires (CWeaklyEqualityComparable<T, U>)
constexpr bool operator==(const TOptional<T>& LHS, const U& RHS) FORCEINLINE constexpr bool operator==(const TOptional<T>& LHS, const U& RHS)
{ {
return LHS.IsValid() ? *LHS == RHS : false; return LHS.IsValid() ? *LHS == RHS : false;
} }
template <typename T> template <typename T>
constexpr bool operator==(const TOptional<T>& LHS, FInvalid) FORCEINLINE constexpr bool operator==(const TOptional<T>& LHS, FInvalid)
{ {
return !LHS.IsValid(); return !LHS.IsValid();
} }
template <typename T> requires (CDestructible<T>) template <typename T> requires (CDestructible<T>)
constexpr TOptional<TDecay<T>> MakeOptional(FInvalid) FORCEINLINE constexpr TOptional<TDecay<T>> MakeOptional(FInvalid)
{ {
return TOptional<TDecay<T>>(Invalid); return TOptional<TDecay<T>>(Invalid);
} }
template <typename T> requires (CDestructible<T> && CConstructibleFrom<T, T&&>) template <typename T> requires (CDestructible<T> && CConstructibleFrom<T, T&&>)
constexpr TOptional<T> MakeOptional(T&& InValue) FORCEINLINE constexpr TOptional<T> MakeOptional(T&& InValue)
{ {
return TOptional<T>(Forward<T>(InValue)); return TOptional<T>(Forward<T>(InValue));
} }
template <typename T, typename... Ts> requires (CDestructible<T> && CConstructibleFrom<T, Ts...>) template <typename T, typename... Ts> requires (CDestructible<T> && CConstructibleFrom<T, Ts...>)
constexpr TOptional<T> MakeOptional(Ts&&... Args) FORCEINLINE constexpr TOptional<T> MakeOptional(Ts&&... Args)
{ {
return TOptional<T>(InPlace, Forward<T>(Args)...); return TOptional<T>(InPlace, Forward<T>(Args)...);
} }

View File

@ -18,43 +18,43 @@ public:
using Type = ReferencedType; using Type = ReferencedType;
template <typename T = ReferencedType> requires (CConvertibleTo<T, ReferencedType&>) template <typename T = ReferencedType> requires (CConvertibleTo<T, ReferencedType&>)
constexpr TReferenceWrapper(T&& Object) FORCEINLINE constexpr TReferenceWrapper(T&& Object)
{ {
ReferencedType& Reference = Forward<T>(Object); ReferencedType& Reference = Forward<T>(Object);
Pointer = AddressOf(Reference); Pointer = AddressOf(Reference);
} }
TReferenceWrapper(const TReferenceWrapper&) = default; FORCEINLINE constexpr TReferenceWrapper(const TReferenceWrapper&) = default;
template <typename T = ReferencedType> requires (CConvertibleTo<T&, ReferencedType&>) template <typename T = ReferencedType> requires (CConvertibleTo<T&, ReferencedType&>)
constexpr TReferenceWrapper(const TReferenceWrapper<T>& InValue) FORCEINLINE constexpr TReferenceWrapper(const TReferenceWrapper<T>& InValue)
: Pointer(InValue.Pointer) : Pointer(InValue.Pointer)
{ } { }
TReferenceWrapper& operator=(const TReferenceWrapper&) = default; FORCEINLINE constexpr TReferenceWrapper& operator=(const TReferenceWrapper&) = default;
template <typename T = ReferencedType> requires (CConvertibleTo<T&, ReferencedType&>) template <typename T = ReferencedType> requires (CConvertibleTo<T&, ReferencedType&>)
constexpr TReferenceWrapper& operator=(const TReferenceWrapper<T>& InValue) FORCEINLINE constexpr TReferenceWrapper& operator=(const TReferenceWrapper<T>& InValue)
{ {
Pointer = InValue.Pointer; Pointer = InValue.Pointer;
return *this; return *this;
} }
constexpr operator ReferencedType&() const { return *Pointer; } FORCEINLINE constexpr operator ReferencedType&() const { return *Pointer; }
constexpr ReferencedType& Get() const { return *Pointer; } FORCEINLINE constexpr ReferencedType& Get() const { return *Pointer; }
template <typename... Ts> template <typename... Ts>
constexpr TInvokeResult<ReferencedType&, Ts...> operator()(Ts&&... Args) const FORCEINLINE constexpr TInvokeResult<ReferencedType&, Ts...> operator()(Ts&&... Args) const
{ {
return Invoke(Get(), Forward<Ts>(Args)...); return Invoke(Get(), Forward<Ts>(Args)...);
} }
constexpr size_t GetTypeHash() const requires (CHashable<ReferencedType>) FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable<ReferencedType>)
{ {
return NAMESPACE_REDCRAFT::GetTypeHash(Get()); return NAMESPACE_REDCRAFT::GetTypeHash(Get());
} }
constexpr void Swap(TReferenceWrapper& InValue) FORCEINLINE constexpr void Swap(TReferenceWrapper& InValue)
{ {
ReferencedType* Temp = Pointer; ReferencedType* Temp = Pointer;
Pointer = InValue.Pointer; Pointer = InValue.Pointer;
@ -68,7 +68,7 @@ private:
template <typename T> requires (CObject<T> || CFunction<T>) friend class TReferenceWrapper; template <typename T> requires (CObject<T> || CFunction<T>) friend class TReferenceWrapper;
// Optimize TOptional with these hacking // Optimize TOptional with these hacking
constexpr TReferenceWrapper(FInvalid) : Pointer(nullptr) { }; FORCEINLINE constexpr TReferenceWrapper(FInvalid) : Pointer(nullptr) { };
template <typename T> requires (CDestructible<T>) friend class TOptional; template <typename T> requires (CDestructible<T>) friend class TOptional;
}; };
@ -80,25 +80,25 @@ template <typename T>
void Ref(const T&&) = delete; void Ref(const T&&) = delete;
template <typename T> template <typename T>
constexpr TReferenceWrapper<T> Ref(T& InValue) FORCEINLINE constexpr TReferenceWrapper<T> Ref(T& InValue)
{ {
return TReferenceWrapper<T>(InValue); return TReferenceWrapper<T>(InValue);
} }
template <typename T> template <typename T>
constexpr TReferenceWrapper<T> Ref(TReferenceWrapper<T> InValue) FORCEINLINE constexpr TReferenceWrapper<T> Ref(TReferenceWrapper<T> InValue)
{ {
return Ref(InValue.Get()); return Ref(InValue.Get());
} }
template <typename T> template <typename T>
constexpr TReferenceWrapper<const T> Ref(const T& InValue) FORCEINLINE constexpr TReferenceWrapper<const T> Ref(const T& InValue)
{ {
return TReferenceWrapper<const T>(InValue); return TReferenceWrapper<const T>(InValue);
} }
template <typename T> template <typename T>
constexpr TReferenceWrapper<const T> Ref(TReferenceWrapper<T> InValue) FORCEINLINE constexpr TReferenceWrapper<const T> Ref(TReferenceWrapper<T> InValue)
{ {
return Ref(InValue.Get()); return Ref(InValue.Get());
} }
@ -151,87 +151,87 @@ public:
using ValueType = OptionalType; using ValueType = OptionalType;
constexpr TOptional() : Reference(Invalid) { } FORCEINLINE constexpr TOptional() : Reference(Invalid) { }
constexpr TOptional(FInvalid) : TOptional() { } FORCEINLINE constexpr TOptional(FInvalid) : TOptional() { }
template <typename... Ts> requires (CConstructibleFrom<OptionalType, Ts...>) template <typename... Ts> requires (CConstructibleFrom<OptionalType, Ts...>)
constexpr explicit TOptional(FInPlace, Ts&&... Args) FORCEINLINE constexpr explicit TOptional(FInPlace, Ts&&... Args)
: Reference(Forward<Ts>(Args)...) : Reference(Forward<Ts>(Args)...)
{ } { }
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> && !CBaseOf<TOptional, TRemoveCVRef<T>>)
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))
{ } { }
TOptional(const TOptional& InValue) = default; FORCEINLINE TOptional(const TOptional& InValue) = default;
TOptional(TOptional&& InValue) = default; FORCEINLINE TOptional(TOptional&& InValue) = default;
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&> && TAllowUnwrapping<T>::Value) template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&> && TAllowUnwrapping<T>::Value)
constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue) FORCEINLINE constexpr explicit (!CConvertibleTo<const T&, OptionalType>) TOptional(const TOptional<T>& InValue)
: Reference(InValue.Reference) : Reference(InValue.Reference)
{ } { }
~TOptional() = default; FORCEINLINE ~TOptional() = default;
TOptional& operator=(const TOptional& InValue) = default; FORCEINLINE TOptional& operator=(const TOptional& InValue) = default;
TOptional& operator=(TOptional&& InValue) = default; FORCEINLINE TOptional& operator=(TOptional&& InValue) = default;
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&> template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, const T&>
&& CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value) && CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value)
constexpr TOptional& operator=(const TOptional<T>& InValue) FORCEINLINE constexpr TOptional& operator=(const TOptional<T>& InValue)
{ {
Reference = InValue.Reference; Reference = InValue.Reference;
return *this; return *this;
} }
template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&>) template <typename T = OptionalType> requires (CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&>)
constexpr TOptional& operator=(T&& InValue) FORCEINLINE constexpr TOptional& operator=(T&& InValue)
{ {
Reference = InValue; Reference = InValue;
return *this; return *this;
} }
template <typename... ArgTypes> requires (CConstructibleFrom<OptionalType, ArgTypes...>) template <typename... ArgTypes> requires (CConstructibleFrom<OptionalType, ArgTypes...>)
constexpr OptionalType& Emplace(ArgTypes&&... Args) FORCEINLINE constexpr OptionalType& Emplace(ArgTypes&&... Args)
{ {
Reference = TReferenceWrapper<ReferencedType>(Forward<ArgTypes>(Args)...); Reference = TReferenceWrapper<ReferencedType>(Forward<ArgTypes>(Args)...);
return Reference; return Reference;
} }
constexpr bool IsValid() const { return Reference.Pointer != nullptr; } FORCEINLINE constexpr bool IsValid() const { return Reference.Pointer != nullptr; }
constexpr explicit operator bool() const { return Reference.Pointer != nullptr; } FORCEINLINE constexpr explicit operator bool() const { return Reference.Pointer != nullptr; }
constexpr OptionalType& GetValue() & { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } FORCEINLINE constexpr OptionalType& GetValue() & { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; }
constexpr OptionalType&& GetValue() && { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } FORCEINLINE constexpr OptionalType&& GetValue() && { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; }
constexpr const OptionalType& GetValue() const& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } FORCEINLINE constexpr const OptionalType& GetValue() const& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; }
constexpr const OptionalType&& GetValue() const&& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; } FORCEINLINE constexpr const OptionalType&& GetValue() const&& { checkf(IsValid(), TEXT("It is an error to call GetValue() on an unset TOptional. Please either check IsValid() or use Get(DefaultValue) instead.")); return Reference; }
constexpr const OptionalType* operator->() const { return &GetValue(); } FORCEINLINE constexpr const OptionalType* operator->() const { return &GetValue(); }
constexpr OptionalType* operator->() { return &GetValue(); } FORCEINLINE constexpr OptionalType* operator->() { return &GetValue(); }
constexpr OptionalType& operator*() & { return GetValue(); } FORCEINLINE constexpr OptionalType& operator*() & { return GetValue(); }
constexpr OptionalType&& operator*() && { return GetValue(); } FORCEINLINE constexpr OptionalType&& operator*() && { return GetValue(); }
constexpr const OptionalType& operator*() const& { return GetValue(); } FORCEINLINE constexpr const OptionalType& operator*() const& { return GetValue(); }
constexpr const OptionalType&& operator*() const&& { return GetValue(); } FORCEINLINE constexpr const OptionalType&& operator*() const&& { return GetValue(); }
constexpr OptionalType& Get( OptionalType& DefaultValue) & { return IsValid() ? GetValue() : DefaultValue; } FORCEINLINE constexpr OptionalType& Get( OptionalType& DefaultValue) & { return IsValid() ? GetValue() : DefaultValue; }
constexpr const OptionalType& Get(const OptionalType& DefaultValue) const& { return IsValid() ? GetValue() : DefaultValue; } FORCEINLINE constexpr const OptionalType& Get(const OptionalType& DefaultValue) const& { return IsValid() ? GetValue() : DefaultValue; }
constexpr void Reset() FORCEINLINE constexpr void Reset()
{ {
Reference = Invalid; Reference = Invalid;
} }
constexpr size_t GetTypeHash() const requires (CHashable<ReferencedType>) FORCEINLINE constexpr size_t GetTypeHash() const requires (CHashable<ReferencedType>)
{ {
if (!IsValid()) return 2824517378; if (!IsValid()) return 2824517378;
return Reference.GetTypeHash(); return Reference.GetTypeHash();
} }
constexpr void Swap(TOptional& InValue) FORCEINLINE constexpr void Swap(TOptional& InValue)
{ {
Reference.Swap(InValue.Reference); Reference.Swap(InValue.Reference);
} }

View File

@ -82,24 +82,25 @@ private:
public: public:
template <typename Type> template <typename Type>
constexpr TTupleBasicElement(Type&& Arg) FORCEINLINE constexpr TTupleBasicElement(Type&& Arg)
: Value(Forward<Type>(Arg)) : Value(Forward<Type>(Arg))
{ } { }
TTupleBasicElement() = default; FORCEINLINE constexpr TTupleBasicElement() = default;
TTupleBasicElement(TTupleBasicElement&&) = default; FORCEINLINE constexpr TTupleBasicElement(const TTupleBasicElement&) = default;
TTupleBasicElement(const TTupleBasicElement&) = default; FORCEINLINE constexpr TTupleBasicElement(TTupleBasicElement&&) = default;
TTupleBasicElement& operator=(TTupleBasicElement&&) = default; FORCEINLINE constexpr TTupleBasicElement& operator=(const TTupleBasicElement&) = default;
TTupleBasicElement& operator=(const TTupleBasicElement&) = default; FORCEINLINE constexpr TTupleBasicElement& operator=(TTupleBasicElement&&) = default;
FORCEINLINE constexpr ~TTupleBasicElement() = default;
constexpr T& GetValue() & { return static_cast< T& >(Value); } FORCEINLINE constexpr T& GetValue() & { return static_cast< T& >(Value); }
constexpr const T& GetValue() const & { return static_cast<const T& >(Value); } FORCEINLINE constexpr const T& GetValue() const & { return static_cast<const T& >(Value); }
constexpr volatile T& GetValue() volatile& { return static_cast< volatile T& >(Value); } FORCEINLINE constexpr volatile T& GetValue() volatile& { return static_cast< volatile T& >(Value); }
constexpr const volatile T& GetValue() const volatile& { return static_cast<const volatile T& >(Value); } FORCEINLINE constexpr const volatile T& GetValue() const volatile& { return static_cast<const volatile T& >(Value); }
constexpr T&& GetValue() && { return static_cast< T&&>(Value); } FORCEINLINE constexpr T&& GetValue() && { return static_cast< T&&>(Value); }
constexpr const T&& GetValue() const && { return static_cast<const T&&>(Value); } FORCEINLINE constexpr const T&& GetValue() const && { return static_cast<const T&&>(Value); }
constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile T&&>(Value); } FORCEINLINE constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile T&&>(Value); }
constexpr const volatile T&& GetValue() const volatile&& { return static_cast<const volatile T&&>(Value); } FORCEINLINE constexpr const volatile T&& GetValue() const volatile&& { return static_cast<const volatile T&&>(Value); }
}; };
#if RS_TUPLE_ELEMENT_STATIC_ALIAS #if RS_TUPLE_ELEMENT_STATIC_ALIAS
@ -112,24 +113,25 @@ public:
Name##Type Name; \ Name##Type Name; \
\ \
template <typename Type> \ template <typename Type> \
constexpr TTupleBasicElement(Type&& Arg) \ FORCEINLINE constexpr TTupleBasicElement(Type&& Arg) \
: Name(Forward<Type>(Arg)) \ : Name(Forward<Type>(Arg)) \
{ } \ { } \
\ \
TTupleBasicElement() = default; \ FORCEINLINE constexpr TTupleBasicElement() = default; \
TTupleBasicElement(TTupleBasicElement&&) = default; \ FORCEINLINE constexpr TTupleBasicElement(const TTupleBasicElement&) = default; \
TTupleBasicElement(const TTupleBasicElement&) = default; \ FORCEINLINE constexpr TTupleBasicElement(TTupleBasicElement&&) = default; \
TTupleBasicElement& operator=(TTupleBasicElement&&) = default; \ FORCEINLINE constexpr TTupleBasicElement& operator=(const TTupleBasicElement&) = default; \
TTupleBasicElement& operator=(const TTupleBasicElement&) = default; \ FORCEINLINE constexpr TTupleBasicElement& operator=(TTupleBasicElement&&) = default; \
FORCEINLINE constexpr ~TTupleBasicElement() = default; \
\ \
constexpr T& GetValue() & { return static_cast< T& >(Name); } \ FORCEINLINE constexpr T& GetValue() & { return static_cast< T& >(Name); } \
constexpr const T& GetValue() const & { return static_cast<const T& >(Name); } \ FORCEINLINE constexpr const T& GetValue() const & { return static_cast<const T& >(Name); } \
constexpr volatile T& GetValue() volatile& { return static_cast< volatile T& >(Name); } \ FORCEINLINE constexpr volatile T& GetValue() volatile& { return static_cast< volatile T& >(Name); } \
constexpr const volatile T& GetValue() const volatile& { return static_cast<const volatile T& >(Name); } \ FORCEINLINE constexpr const volatile T& GetValue() const volatile& { return static_cast<const volatile T& >(Name); } \
constexpr T&& GetValue() && { return static_cast< T&&>(Name); } \ FORCEINLINE constexpr T&& GetValue() && { return static_cast< T&&>(Name); } \
constexpr const T&& GetValue() const && { return static_cast<const T&&>(Name); } \ FORCEINLINE constexpr const T&& GetValue() const && { return static_cast<const T&&>(Name); } \
constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile T&&>(Name); } \ FORCEINLINE constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile T&&>(Name); } \
constexpr const volatile T&& GetValue() const volatile&& { return static_cast<const volatile T&&>(Name); } \ FORCEINLINE constexpr const volatile T&& GetValue() const volatile&& { return static_cast<const volatile T&&>(Name); } \
} }
DEFINE_TTupleBasicElement(0x0, First); DEFINE_TTupleBasicElement(0x0, First);
@ -154,7 +156,7 @@ DEFINE_TTupleBasicElement(0xF, Sixteenth);
#endif #endif
template <typename... Ts> template <typename... Ts>
constexpr TTuple<TUnwrapRefDecay<Ts>...> MakeTupleImpl(Ts&&... Args) FORCEINLINE constexpr TTuple<TUnwrapRefDecay<Ts>...> MakeTupleImpl(Ts&&... Args)
{ {
return TTuple<TUnwrapRefDecay<Ts>...>(Forward<Ts>(Args)...); return TTuple<TUnwrapRefDecay<Ts>...>(Forward<Ts>(Args)...);
} }
@ -167,24 +169,23 @@ class TTupleImpl<TIndexSequence<Indices...>, Ts...> : public TTupleBasicElement<
{ {
protected: protected:
TTupleImpl() = default; FORCEINLINE constexpr TTupleImpl() = default;
FORCEINLINE constexpr TTupleImpl(const TTupleImpl&) = default;
FORCEINLINE constexpr TTupleImpl(TTupleImpl&&) = default;
FORCEINLINE constexpr TTupleImpl& operator=(const TTupleImpl&) = default;
FORCEINLINE constexpr TTupleImpl& operator=(TTupleImpl&&) = default;
FORCEINLINE constexpr ~TTupleImpl() = default;
template <typename... ArgTypes> template <typename... ArgTypes>
constexpr explicit TTupleImpl(FForwardingConstructor, ArgTypes&&... Args) FORCEINLINE constexpr explicit TTupleImpl(FForwardingConstructor, ArgTypes&&... Args)
: TTupleBasicElement<Ts, Indices>(Forward<ArgTypes>(Args))... : TTupleBasicElement<Ts, Indices>(Forward<ArgTypes>(Args))...
{ } { }
template <typename TupleType> template <typename TupleType>
constexpr explicit TTupleImpl(FOtherTupleConstructor, TupleType&& InValue) FORCEINLINE constexpr explicit TTupleImpl(FOtherTupleConstructor, TupleType&& InValue)
: TTupleBasicElement<Ts, Indices>(Forward<TupleType>(InValue).template GetValue<Indices>())... : TTupleBasicElement<Ts, Indices>(Forward<TupleType>(InValue).template GetValue<Indices>())...
{ } { }
constexpr TTupleImpl(const TTupleImpl&) = default;
constexpr TTupleImpl(TTupleImpl&&) = default;
constexpr TTupleImpl& operator=(const TTupleImpl&) = default;
constexpr TTupleImpl& operator=(TTupleImpl&&) = default;
}; };
template <typename Indices, typename... Ts> template <typename Indices, typename... Ts>
@ -196,7 +197,7 @@ class TTupleHelper<TIndexSequence<Indices...>>
public: public:
template <typename LHSTupleType, typename RHSTupleType> template <typename LHSTupleType, typename RHSTupleType>
static constexpr void Assign(LHSTupleType& LHS, RHSTupleType&& RHS) FORCEINLINE static constexpr void Assign(LHSTupleType& LHS, RHSTupleType&& RHS)
{ {
static_assert(sizeof...(Indices) == TTupleArityImpl<TRemoveCVRef<LHSTupleType>>::Value static_assert(sizeof...(Indices) == TTupleArityImpl<TRemoveCVRef<LHSTupleType>>::Value
&& TTupleArityImpl<TRemoveCVRef<LHSTupleType>>::Value == TTupleArityImpl<TRemoveCVRef<RHSTupleType>>::Value, && TTupleArityImpl<TRemoveCVRef<LHSTupleType>>::Value == TTupleArityImpl<TRemoveCVRef<RHSTupleType>>::Value,
@ -206,19 +207,19 @@ public:
} }
template <typename F, typename TTupleType> template <typename F, typename TTupleType>
static constexpr auto Apply(F&& Func, TTupleType&& Arg) FORCEINLINE static constexpr auto Apply(F&& Func, TTupleType&& Arg)
{ {
return Invoke(Forward<F>(Func), Forward<TTupleType>(Arg).template GetValue<Indices>()...); return Invoke(Forward<F>(Func), Forward<TTupleType>(Arg).template GetValue<Indices>()...);
} }
template <typename F, typename TTupleType> template <typename F, typename TTupleType>
static constexpr auto Transform(F&& Func, TTupleType&& Arg) FORCEINLINE static constexpr auto Transform(F&& Func, TTupleType&& Arg)
{ {
return MakeTupleImpl(Invoke(Forward<F>(Func), Forward<TTupleType>(Arg).template GetValue<Indices>())...); return MakeTupleImpl(Invoke(Forward<F>(Func), Forward<TTupleType>(Arg).template GetValue<Indices>())...);
} }
template <typename T, typename TTupleType> template <typename T, typename TTupleType>
static constexpr T Construct(TTupleType&& Arg) FORCEINLINE static constexpr T Construct(TTupleType&& Arg)
{ {
return T(Forward<TTupleType>(Arg).template GetValue<Indices>()...); return T(Forward<TTupleType>(Arg).template GetValue<Indices>()...);
} }
@ -249,34 +250,34 @@ private:
public: public:
constexpr TTuple() = default; FORCEINLINE constexpr TTuple() = default;
template <typename... ArgTypes> requires (sizeof...(Ts) >= 1 && sizeof...(ArgTypes) == sizeof...(Ts)) template <typename... ArgTypes> requires (sizeof...(Ts) >= 1 && sizeof...(ArgTypes) == sizeof...(Ts))
&& (true && ... && CConstructibleFrom<Ts, ArgTypes&&>) && (true && ... && CConstructibleFrom<Ts, ArgTypes&&>)
constexpr explicit (!(true && ... && CConvertibleTo<ArgTypes&&, Ts>)) TTuple(ArgTypes&&... Args) FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<ArgTypes&&, Ts>)) TTuple(ArgTypes&&... Args)
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...) : Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
{ } { }
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
&& (true && ... && CConstructibleFrom<Ts, const OtherTypes&>) && (true && ... && CConstructibleFrom<Ts, const OtherTypes&>)
&& NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value) && NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value)
constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(const TTuple<OtherTypes...>& InValue) FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(const TTuple<OtherTypes...>& InValue)
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue) : Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
{ } { }
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
&& (true && ... && CConstructibleFrom<Ts, OtherTypes&&>) && (true && ... && CConstructibleFrom<Ts, OtherTypes&&>)
&& NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value) && NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Ts) != 1, Ts..., OtherTypes...>::Value)
constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(TTuple<OtherTypes...>&& InValue) FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Ts>)) TTuple(TTuple<OtherTypes...>&& InValue)
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue)) : Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
{ } { }
constexpr TTuple(const TTuple&) = default; FORCEINLINE constexpr TTuple(const TTuple&) = default;
constexpr TTuple(TTuple&&) = default; FORCEINLINE constexpr TTuple(TTuple&&) = default;
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
&& (true && ... && CAssignableFrom<Ts&, const OtherTypes&>)) && (true && ... && CAssignableFrom<Ts&, const OtherTypes&>))
constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue) FORCEINLINE constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue)
{ {
Helper::Assign(*this, InValue); Helper::Assign(*this, InValue);
return *this; return *this;
@ -284,61 +285,61 @@ public:
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts) template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Ts)
&& (true && ... && CAssignableFrom<Ts&, OtherTypes&&>)) && (true && ... && CAssignableFrom<Ts&, OtherTypes&&>))
constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue) FORCEINLINE constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue)
{ {
Helper::Assign(*this, MoveTemp(InValue)); Helper::Assign(*this, MoveTemp(InValue));
return *this; return *this;
} }
constexpr TTuple& operator=(const TTuple&) = default; FORCEINLINE constexpr TTuple& operator=(const TTuple&) = default;
constexpr TTuple& operator=(TTuple&&) = default; FORCEINLINE constexpr TTuple& operator=(TTuple&&) = default;
template <size_t I> requires (I < sizeof...(Ts)) 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)) 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(); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() volatile& { return static_cast< volatile 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(); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() const volatile& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>& >(*this).GetValue(); } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() const volatile& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>& >(*this).GetValue(); }
template <size_t I> requires (I < sizeof...(Ts)) 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)) 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(); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() volatile&& { return static_cast< volatile 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(); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>&&>(*this).GetValue(); } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Ts...>>, I>&&>(*this).GetValue(); }
template <typename T> constexpr decltype(auto) GetValue() & { return static_cast< TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() & { return static_cast< TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename T> constexpr decltype(auto) GetValue() const & { return static_cast<const TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() const & { return static_cast<const TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename T> constexpr decltype(auto) GetValue() volatile& { return static_cast< volatile TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() volatile& { return static_cast< volatile TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename T> constexpr decltype(auto) GetValue() const volatile& { return static_cast<const volatile TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() const volatile& { return static_cast<const volatile TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename T> constexpr decltype(auto) GetValue() && { return static_cast< TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() && { return static_cast< TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename T> constexpr decltype(auto) GetValue() const && { return static_cast<const TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() const && { return static_cast<const TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename T> constexpr decltype(auto) GetValue() volatile&& { return static_cast< volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() volatile&& { return static_cast< volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename T> constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Ts...>>>(); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) & { return Helper::Apply(Forward<F>(Func), static_cast< TTuple& >(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) & { return Helper::Apply(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) const & { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple& >(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const & { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) volatile& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) const volatile& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) && { return Helper::Apply(Forward<F>(Func), static_cast< TTuple&&>(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) && { return Helper::Apply(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) const && { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple&&>(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const && { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) volatile&& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile&& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) constexpr decltype(auto) Apply(F&& Func) const volatile&& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); } template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile&& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) & { return Helper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) & { return Helper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) const & { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const & { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) volatile& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) const volatile& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) && { return Helper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) && { return Helper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) const && { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const && { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) constexpr decltype(auto) Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); } template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); } template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); } template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) 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...>) 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)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) constexpr T Construct() && { return Helper::template Construct<T>(static_cast< TTuple&&>(*this)); } template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() && { return Helper::template Construct<T>(static_cast< TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) constexpr T Construct() const && { return Helper::template Construct<T>(static_cast<const TTuple&&>(*this)); } template <typename T> requires (CConstructibleFrom<T, Ts...>) FORCEINLINE constexpr T Construct() const && { return Helper::template Construct<T>(static_cast<const TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) 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...>) 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)); }
constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Ts>) FORCEINLINE constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Ts>)
{ {
return [this]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t return [this]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t
{ {
@ -347,7 +348,7 @@ public:
(TMakeIndexSequence<sizeof...(Ts)>()); (TMakeIndexSequence<sizeof...(Ts)>());
} }
constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible<Ts>&& CSwappable<Ts>)) FORCEINLINE constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible<Ts> && CSwappable<Ts>))
{ {
[&A = *this, &B = InValue]<size_t... Indices>(TIndexSequence<Indices...>) [&A = *this, &B = InValue]<size_t... Indices>(TIndexSequence<Indices...>)
{ {
@ -365,19 +366,19 @@ template <typename T, typename U>
using TPair = TTuple<T, U>; using TPair = TTuple<T, U>;
template <typename... Ts> template <typename... Ts>
constexpr TTuple<TUnwrapRefDecay<Ts>...> MakeTuple(Ts&&... Args) FORCEINLINE constexpr TTuple<TUnwrapRefDecay<Ts>...> MakeTuple(Ts&&... Args)
{ {
return TTuple<TUnwrapRefDecay<Ts>...>(Forward<Ts>(Args)...); return TTuple<TUnwrapRefDecay<Ts>...>(Forward<Ts>(Args)...);
} }
template <typename... Ts> template <typename... Ts>
constexpr TTuple<Ts&...> Tie(Ts&... Args) FORCEINLINE constexpr TTuple<Ts&...> Tie(Ts&... Args)
{ {
return TTuple<Ts&...>(Args...); return TTuple<Ts&...>(Args...);
} }
template <typename... Ts> template <typename... Ts>
constexpr TTuple<Ts&&...> ForwardAsTuple(Ts&&... Args) FORCEINLINE constexpr TTuple<Ts&&...> ForwardAsTuple(Ts&&... Args)
{ {
return TTuple<Ts&&...>(Forward<Ts>(Args)...); return TTuple<Ts&&...>(Forward<Ts>(Args)...);
} }
@ -411,7 +412,7 @@ struct TTupleCatMake<TTuple<RTypes...>, TIndexSequence<Indices...>>
struct ForwardType { using Type = TConditional<CRValueReference<T>, TRemoveReference<U>&&, U>; }; struct ForwardType { using Type = TConditional<CRValueReference<T>, TRemoveReference<U>&&, U>; };
template <typename TTupleType> template <typename TTupleType>
static constexpr TTuple<RTypes...> Do(TTupleType&& InValue) FORCEINLINE static constexpr TTuple<RTypes...> Do(TTupleType&& InValue)
{ {
return TTuple<RTypes...> return TTuple<RTypes...>
( (
@ -430,7 +431,7 @@ template <size_t... ForwardIndices, size_t... TTupleIndices>
struct TTupleCatForward<TIndexSequence<ForwardIndices...>, TIndexSequence<TTupleIndices...>> struct TTupleCatForward<TIndexSequence<ForwardIndices...>, TIndexSequence<TTupleIndices...>>
{ {
template <typename ForwardType, typename TTupleType> template <typename ForwardType, typename TTupleType>
static constexpr decltype(auto) Do(ForwardType&& ForwardTuple, TTupleType&& InValue) FORCEINLINE static constexpr decltype(auto) Do(ForwardType&& ForwardTuple, TTupleType&& InValue)
{ {
return ForwardAsTuple(Forward<ForwardType>(ForwardTuple).template GetValue<ForwardIndices>()..., Forward<TTupleType>(InValue).template GetValue<TTupleIndices>()...); return ForwardAsTuple(Forward<ForwardType>(ForwardTuple).template GetValue<ForwardIndices>()..., Forward<TTupleType>(InValue).template GetValue<TTupleIndices>()...);
} }
@ -440,7 +441,7 @@ template <typename R>
struct TTupleCatImpl struct TTupleCatImpl
{ {
template <typename ForwardType, typename TTupleType, typename... OtherTTupleTypes> template <typename ForwardType, typename TTupleType, typename... OtherTTupleTypes>
static constexpr decltype(auto) Do(ForwardType&& ForwardTuple, TTupleType&& InValue, OtherTTupleTypes&&... OtherValue) FORCEINLINE static constexpr decltype(auto) Do(ForwardType&& ForwardTuple, TTupleType&& InValue, OtherTTupleTypes&&... OtherValue)
{ {
return Do(TTupleCatForward< return Do(TTupleCatForward<
TMakeIndexSequence<TTupleArity<TRemoveReference<ForwardType>>>, TMakeIndexSequence<TTupleArity<TRemoveReference<ForwardType>>>,
@ -449,7 +450,7 @@ struct TTupleCatImpl
} }
template <typename ForwardType> template <typename ForwardType>
static constexpr decltype(auto) Do(ForwardType&& ForwardTuple) FORCEINLINE static constexpr decltype(auto) Do(ForwardType&& ForwardTuple)
{ {
return TTupleCatMake<R, TMakeIndexSequence<TTupleArity<ForwardType>>>::Do(Forward<ForwardType>(ForwardTuple)); return TTupleCatMake<R, TMakeIndexSequence<TTupleArity<ForwardType>>>::Do(Forward<ForwardType>(ForwardTuple));
} }
@ -462,7 +463,7 @@ template <typename R, size_t I, size_t... Indices>
struct TTupleThreeWay<R, TIndexSequence<I, Indices...>> struct TTupleThreeWay<R, TIndexSequence<I, Indices...>>
{ {
template <typename LHSTupleType, typename RHSTupleType> template <typename LHSTupleType, typename RHSTupleType>
static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS) FORCEINLINE static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS)
{ {
auto Result = SynthThreeWayCompare(LHS.template GetValue<I>(), RHS.template GetValue<I>()); auto Result = SynthThreeWayCompare(LHS.template GetValue<I>(), RHS.template GetValue<I>());
if (Result != 0) return Result; if (Result != 0) return Result;
@ -474,7 +475,7 @@ template <typename R>
struct TTupleThreeWay<R, TIndexSequence<>> struct TTupleThreeWay<R, TIndexSequence<>>
{ {
template <typename LHSTupleType, typename RHSTupleType> template <typename LHSTupleType, typename RHSTupleType>
static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS) FORCEINLINE static constexpr R Do(const LHSTupleType& LHS, const RHSTupleType& RHS)
{ {
return R::equivalent; return R::equivalent;
} }
@ -487,7 +488,7 @@ template <size_t I, size_t... Indices>
struct TTupleVisitImpl<TIndexSequence<I, Indices...>> struct TTupleVisitImpl<TIndexSequence<I, Indices...>>
{ {
template <typename F, typename... TupleTypes> template <typename F, typename... TupleTypes>
static constexpr void Do(F&& Func, TupleTypes&&... Tuples) FORCEINLINE static constexpr void Do(F&& Func, TupleTypes&&... Tuples)
{ {
Invoke(Forward<F>(Func), Forward<TupleTypes>(Tuples).template GetValue<I>()...); Invoke(Forward<F>(Func), Forward<TupleTypes>(Tuples).template GetValue<I>()...);
TTupleVisitImpl<TIndexSequence<Indices...>>::Do(Forward<F>(Func), Forward<TupleTypes>(Tuples)...); TTupleVisitImpl<TIndexSequence<Indices...>>::Do(Forward<F>(Func), Forward<TupleTypes>(Tuples)...);
@ -498,7 +499,7 @@ template <>
struct TTupleVisitImpl<TIndexSequence<>> struct TTupleVisitImpl<TIndexSequence<>>
{ {
template <typename... TupleTypes> template <typename... TupleTypes>
static constexpr void Do(TupleTypes&&... Tuples) { } FORCEINLINE static constexpr void Do(TupleTypes&&... Tuples) { }
}; };
NAMESPACE_PRIVATE_END NAMESPACE_PRIVATE_END
@ -507,7 +508,7 @@ template <typename... TTupleTypes> requires (true && ... && CTTuple<TRemoveCVRef
using TTupleCatResult = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<TRemoveReference<TTupleTypes>..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type;; using TTupleCatResult = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<TRemoveReference<TTupleTypes>..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type;;
template <typename... TTupleTypes> requires (true && ... && CTTuple<TRemoveCVRef<TTupleTypes>>) template <typename... TTupleTypes> requires (true && ... && CTTuple<TRemoveCVRef<TTupleTypes>>)
constexpr decltype(auto) TupleCat(TTupleTypes&&... Args) FORCEINLINE constexpr decltype(auto) TupleCat(TTupleTypes&&... Args)
{ {
using R = TTupleCatResult<TTupleTypes...>; using R = TTupleCatResult<TTupleTypes...>;
if constexpr (sizeof...(Args) == 0) return R(); if constexpr (sizeof...(Args) == 0) return R();
@ -515,14 +516,14 @@ constexpr decltype(auto) TupleCat(TTupleTypes&&... Args)
} }
template <typename... LHSTypes, typename... RHSTypes> requires (sizeof...(LHSTypes) != sizeof...(RHSTypes) || (true && ... && CWeaklyEqualityComparable<LHSTypes, RHSTypes>)) template <typename... LHSTypes, typename... RHSTypes> requires (sizeof...(LHSTypes) != sizeof...(RHSTypes) || (true && ... && CWeaklyEqualityComparable<LHSTypes, RHSTypes>))
constexpr bool operator==(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS) FORCEINLINE constexpr bool operator==(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS)
{ {
if constexpr (sizeof...(LHSTypes) != sizeof...(RHSTypes)) return false; 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)>()); 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>))) template <typename... LHSTypes, typename... RHSTypes> requires (sizeof...(LHSTypes) == sizeof...(RHSTypes) && (true && ... && (CSynthThreeWayComparable<LHSTypes, RHSTypes>)))
constexpr TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...> operator<=>(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS) FORCEINLINE constexpr TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...> operator<=>(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS)
{ {
using R = TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...>; using R = TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...>;
return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(LHSTypes)>>::Do(LHS, RHS); return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(LHSTypes)>>::Do(LHS, RHS);
@ -530,7 +531,7 @@ constexpr TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...>
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>>))
constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples) FORCEINLINE constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples)
{ {
NAMESPACE_PRIVATE::TTupleVisitImpl<TMakeIndexSequence<TTupleArity<TRemoveReference<FirstTupleType>>>> NAMESPACE_PRIVATE::TTupleVisitImpl<TMakeIndexSequence<TTupleArity<TRemoveReference<FirstTupleType>>>>
::Do(Forward<F>(Func), Forward<FirstTupleType>(FirstTuple), Forward<TupleTypes>(Tuples)...); ::Do(Forward<F>(Func), Forward<FirstTupleType>(FirstTuple), Forward<TupleTypes>(Tuples)...);
@ -566,14 +567,14 @@ NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
// Support structure binding, should not be directly used // Support structure binding, should not be directly used
template <size_t Index, typename ...Ts> constexpr decltype(auto) get( TTuple<Ts...>& InValue) { return static_cast< TTuple<Ts...>& >(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get( TTuple<Ts...>& InValue) { return static_cast< TTuple<Ts...>& >(InValue).template GetValue<Index>(); }
template <size_t Index, typename ...Ts> constexpr decltype(auto) get(const TTuple<Ts...>& InValue) { return static_cast<const TTuple<Ts...>& >(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get(const TTuple<Ts...>& InValue) { return static_cast<const TTuple<Ts...>& >(InValue).template GetValue<Index>(); }
template <size_t Index, typename ...Ts> constexpr decltype(auto) get( volatile TTuple<Ts...>& InValue) { return static_cast< volatile TTuple<Ts...>& >(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get( volatile TTuple<Ts...>& InValue) { return static_cast< volatile TTuple<Ts...>& >(InValue).template GetValue<Index>(); }
template <size_t Index, typename ...Ts> constexpr decltype(auto) get(const volatile TTuple<Ts...>& InValue) { return static_cast<const volatile TTuple<Ts...>& >(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get(const volatile TTuple<Ts...>& InValue) { return static_cast<const volatile TTuple<Ts...>& >(InValue).template GetValue<Index>(); }
template <size_t Index, typename ...Ts> constexpr decltype(auto) get( TTuple<Ts...>&& InValue) { return static_cast< TTuple<Ts...>&&>(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get( TTuple<Ts...>&& InValue) { return static_cast< TTuple<Ts...>&&>(InValue).template GetValue<Index>(); }
template <size_t Index, typename ...Ts> constexpr decltype(auto) get(const TTuple<Ts...>&& InValue) { return static_cast<const TTuple<Ts...>&&>(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get(const TTuple<Ts...>&& InValue) { return static_cast<const TTuple<Ts...>&&>(InValue).template GetValue<Index>(); }
template <size_t Index, typename ...Ts> constexpr decltype(auto) get( volatile TTuple<Ts...>&& InValue) { return static_cast< volatile TTuple<Ts...>&&>(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get( volatile TTuple<Ts...>&& InValue) { return static_cast< volatile TTuple<Ts...>&&>(InValue).template GetValue<Index>(); }
template <size_t Index, typename ...Ts> constexpr decltype(auto) get(const volatile TTuple<Ts...>&& InValue) { return static_cast<const volatile TTuple<Ts...>&&>(InValue).template GetValue<Index>(); } template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get(const volatile TTuple<Ts...>&& InValue) { return static_cast<const volatile TTuple<Ts...>&&>(InValue).template GetValue<Index>(); }
NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft) NAMESPACE_MODULE_END(Redcraft)

View File

@ -9,17 +9,17 @@ NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
constexpr size_t HashCombine() FORCEINLINE constexpr size_t HashCombine()
{ {
return 0; return 0;
} }
constexpr size_t HashCombine(size_t A) FORCEINLINE constexpr size_t HashCombine(size_t A)
{ {
return A; return A;
} }
constexpr size_t HashCombine(size_t A, size_t C) FORCEINLINE constexpr size_t HashCombine(size_t A, size_t C)
{ {
size_t B = static_cast<size_t>(0x9E3779B97F4A7C16); size_t B = static_cast<size_t>(0x9E3779B97F4A7C16);
@ -40,14 +40,14 @@ constexpr size_t HashCombine(size_t A, size_t C)
} }
template <typename... Ts> requires (true && ... && CConvertibleTo<Ts, size_t>) template <typename... Ts> requires (true && ... && CConvertibleTo<Ts, size_t>)
constexpr size_t HashCombine(size_t A, size_t C, Ts... InOther) FORCEINLINE constexpr size_t HashCombine(size_t A, size_t C, Ts... InOther)
{ {
size_t B = HashCombine(A, C); size_t B = HashCombine(A, C);
return HashCombine(B, InOther...); return HashCombine(B, InOther...);
} }
template <CIntegral T> template <CIntegral T>
constexpr size_t GetTypeHash(T A) FORCEINLINE constexpr size_t GetTypeHash(T A)
{ {
static_assert(sizeof(T) <= 16, "GetTypeHash only works with T up to 128 bits."); static_assert(sizeof(T) <= 16, "GetTypeHash only works with T up to 128 bits.");
@ -60,7 +60,7 @@ constexpr size_t GetTypeHash(T A)
} }
template <CFloatingPoint T> template <CFloatingPoint T>
constexpr size_t GetTypeHash(T A) FORCEINLINE constexpr size_t GetTypeHash(T A)
{ {
static_assert(sizeof(T) <= 16, "GetTypeHash only works with T up to 128 bits."); static_assert(sizeof(T) <= 16, "GetTypeHash only works with T up to 128 bits.");
@ -75,25 +75,25 @@ constexpr size_t GetTypeHash(T A)
} }
template <CEnum T> template <CEnum T>
constexpr size_t GetTypeHash(T A) FORCEINLINE constexpr size_t GetTypeHash(T A)
{ {
return GetTypeHash(static_cast<TUnderlyingType<T>>(A)); return GetTypeHash(static_cast<TUnderlyingType<T>>(A));
} }
template <typename T> requires (CPointer<T> || CSameAs<T, nullptr_t>) template <typename T> requires (CPointer<T> || CSameAs<T, nullptr_t>)
constexpr size_t GetTypeHash(T A) 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>; }) template <typename T> requires (requires(const T& A) { { GetTypeHash(A.GetTypeHash()) } -> CSameAs<size_t>; })
constexpr size_t GetTypeHash(const T& A) FORCEINLINE constexpr size_t GetTypeHash(const T& A)
{ {
return GetTypeHash(A.GetTypeHash()); 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>; })
constexpr size_t GetTypeHash(const T& A) FORCEINLINE constexpr size_t GetTypeHash(const T& A)
{ {
return GetTypeHash(A.hash_code()); return GetTypeHash(A.hash_code());
} }

View File

@ -10,7 +10,7 @@ NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
template <typename T> template <typename T>
constexpr const T& AsConst(T& Ref) FORCEINLINE constexpr const T& AsConst(T& Ref)
{ {
return Ref; return Ref;
} }
@ -19,45 +19,45 @@ template <typename T>
void AsConst(const T&& Ref) = delete; void AsConst(const T&& Ref) = delete;
template <typename T> template <typename T>
constexpr TRemoveReference<T>&& MoveTemp(T&& Obj) FORCEINLINE constexpr TRemoveReference<T>&& MoveTemp(T&& Obj)
{ {
using CastType = TRemoveReference<T>; using CastType = TRemoveReference<T>;
return static_cast<CastType&&>(Obj); return static_cast<CastType&&>(Obj);
} }
template <typename T> template <typename T>
constexpr T CopyTemp(T& Obj) FORCEINLINE constexpr T CopyTemp(T& Obj)
{ {
return const_cast<const T&>(Obj); return const_cast<const T&>(Obj);
} }
template <typename T> template <typename T>
constexpr T CopyTemp(const T& Obj) FORCEINLINE constexpr T CopyTemp(const T& Obj)
{ {
return Obj; return Obj;
} }
template <typename T> template <typename T>
constexpr T&& CopyTemp(T&& Obj) FORCEINLINE constexpr T&& CopyTemp(T&& Obj)
{ {
return MoveTemp(Obj); return MoveTemp(Obj);
} }
template <typename T> template <typename T>
constexpr T&& Forward(TRemoveReference<T>& Obj) FORCEINLINE constexpr T&& Forward(TRemoveReference<T>& Obj)
{ {
return static_cast<T&&>(Obj); return static_cast<T&&>(Obj);
} }
template <typename T> template <typename T>
constexpr T&& Forward(TRemoveReference<T>&& Obj) 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 (requires(T& A, T& B) { A.Swap(B); }
|| (CMoveConstructible<T> && CMoveAssignable<T>)) || (CMoveConstructible<T> && CMoveAssignable<T>))
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); }) if constexpr (requires(T& A, T& B) { A.Swap(B); })
{ {
@ -72,7 +72,7 @@ constexpr void Swap(T& A, T& B)
} }
template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>) template <typename T, typename U = T> requires (CMoveConstructible<T> && CAssignableFrom<T&, U>)
constexpr T Exchange(T& A, U&& B) FORCEINLINE constexpr T Exchange(T& A, U&& B)
{ {
T Temp = MoveTemp(A); T Temp = MoveTemp(A);
A = Forward<U>(B); A = Forward<U>(B);
@ -80,16 +80,16 @@ constexpr T Exchange(T& A, U&& B)
} }
template <typename T> template <typename T>
constexpr TAddRValueReference<T> DeclVal(); TAddRValueReference<T> DeclVal();
template <typename T> requires (CObject<T>) template <typename T> requires (CObject<T>)
constexpr T* AddressOf(T& Object) FORCEINLINE constexpr T* AddressOf(T& Object)
{ {
return reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(Object))); return reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char&>(Object)));
} }
template <typename T> requires (!CObject<T>) template <typename T> requires (!CObject<T>)
constexpr T* AddressOf(T& Object) FORCEINLINE constexpr T* AddressOf(T& Object)
{ {
return &Object; return &Object;
} }
@ -97,7 +97,7 @@ constexpr T* AddressOf(T& Object)
struct FIgnore struct FIgnore
{ {
template <typename T> template <typename T>
constexpr void operator=(T&&) const { } FORCEINLINE constexpr void operator=(T&&) const { }
}; };
inline constexpr FIgnore Ignore; inline constexpr FIgnore Ignore;

View File

@ -84,21 +84,21 @@ class TVariant
{ {
public: public:
constexpr TVariant() : TypeIndex(0xFF) { }; FORCEINLINE constexpr TVariant() : TypeIndex(0xFF) { };
constexpr TVariant(FInvalid) : TVariant() { }; FORCEINLINE constexpr TVariant(FInvalid) : TVariant() { };
constexpr TVariant(const TVariant& InValue) requires (true && ... && CTriviallyCopyConstructible<Ts>) = default; FORCEINLINE constexpr TVariant(const TVariant& InValue) requires (true && ... && CTriviallyCopyConstructible<Ts>) = default;
constexpr TVariant(const TVariant& InValue) requires ((true && ... && CCopyConstructible<Ts>) && !(true && ... && CTriviallyCopyConstructible<Ts>)) FORCEINLINE constexpr TVariant(const TVariant& InValue) requires ((true && ... && CCopyConstructible<Ts>) && !(true && ... && CTriviallyCopyConstructible<Ts>))
: TypeIndex(static_cast<uint8>(InValue.GetIndex())) : TypeIndex(static_cast<uint8>(InValue.GetIndex()))
{ {
if (IsValid()) CopyConstructImpl[InValue.GetIndex()](&Value, &InValue.Value); if (IsValid()) CopyConstructImpl[InValue.GetIndex()](&Value, &InValue.Value);
} }
constexpr TVariant(TVariant&& InValue) requires (true && ... && CTriviallyMoveConstructible<Ts>) = default; FORCEINLINE constexpr TVariant(TVariant&& InValue) requires (true && ... && CTriviallyMoveConstructible<Ts>) = default;
constexpr TVariant(TVariant&& InValue) requires ((true && ... && CMoveConstructible<Ts>) && !(true && ... && CTriviallyMoveConstructible<Ts>)) FORCEINLINE constexpr TVariant(TVariant&& InValue) requires ((true && ... && CMoveConstructible<Ts>) && !(true && ... && CTriviallyMoveConstructible<Ts>))
: TypeIndex(static_cast<uint8>(InValue.GetIndex())) : TypeIndex(static_cast<uint8>(InValue.GetIndex()))
{ {
if (IsValid()) MoveConstructImpl[InValue.GetIndex()](&Value, &InValue.Value); if (IsValid()) MoveConstructImpl[InValue.GetIndex()](&Value, &InValue.Value);
@ -106,7 +106,7 @@ public:
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...>)
constexpr explicit TVariant(TInPlaceIndex<I>, ArgTypes&&... Args) FORCEINLINE constexpr explicit TVariant(TInPlaceIndex<I>, ArgTypes&&... Args)
: TypeIndex(I) : TypeIndex(I)
{ {
using SelectedType = TVariantAlternative<I, TVariant<Ts...>>; using SelectedType = TVariantAlternative<I, TVariant<Ts...>>;
@ -114,26 +114,26 @@ public:
} }
template <typename T, typename... ArgTypes> requires (CConstructibleFrom<T, ArgTypes...>) template <typename T, typename... ArgTypes> requires (CConstructibleFrom<T, ArgTypes...>)
constexpr explicit TVariant(TInPlaceType<T>, ArgTypes&&... Args) FORCEINLINE constexpr explicit TVariant(TInPlaceType<T>, ArgTypes&&... Args)
: TVariant(InPlaceIndex<TVariantIndex<T, TVariant<Ts...>>>, Forward<ArgTypes>(Args)...) : TVariant(InPlaceIndex<TVariantIndex<T, TVariant<Ts...>>>, Forward<ArgTypes>(Args)...)
{ } { }
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>>) && !CBaseOf<TVariant, TRemoveCVRef<T>>)
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))
{ } { }
constexpr ~TVariant() requires (true && ... && CTriviallyDestructible<Ts>) = default; FORCEINLINE constexpr ~TVariant() requires (true && ... && CTriviallyDestructible<Ts>) = default;
constexpr ~TVariant() requires (!(true && ... && CTriviallyDestructible<Ts>)) FORCEINLINE constexpr ~TVariant() requires (!(true && ... && CTriviallyDestructible<Ts>))
{ {
Reset(); Reset();
} }
constexpr TVariant& operator=(const TVariant& InValue) requires (true && ... && (CTriviallyCopyConstructible<Ts> && CTriviallyCopyAssignable<Ts>)) = default; FORCEINLINE constexpr TVariant& operator=(const TVariant& InValue) requires (true && ... && (CTriviallyCopyConstructible<Ts> && CTriviallyCopyAssignable<Ts>)) = default;
constexpr TVariant& operator=(const TVariant& InValue) requires ((true && ... && (CCopyConstructible<Ts> && CCopyAssignable<Ts>)) FORCEINLINE constexpr TVariant& operator=(const TVariant& InValue) requires ((true && ... && (CCopyConstructible<Ts> && CCopyAssignable<Ts>))
&& !(true && ... && (CTriviallyCopyConstructible<Ts> && CTriviallyCopyAssignable<Ts>))) && !(true && ... && (CTriviallyCopyConstructible<Ts> && CTriviallyCopyAssignable<Ts>)))
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -155,9 +155,9 @@ public:
return *this; return *this;
} }
constexpr TVariant& operator=(TVariant&& InValue) requires (true && ... && (CTriviallyMoveConstructible<Ts> && CTriviallyMoveAssignable<Ts>)) = default; FORCEINLINE constexpr TVariant& operator=(TVariant&& InValue) requires (true && ... && (CTriviallyMoveConstructible<Ts> && CTriviallyMoveAssignable<Ts>)) = default;
constexpr TVariant& operator=(TVariant&& InValue) requires ((true && ... && (CMoveConstructible<Ts> && CMoveAssignable<Ts>)) FORCEINLINE constexpr TVariant& operator=(TVariant&& InValue) requires ((true && ... && (CMoveConstructible<Ts> && CMoveAssignable<Ts>))
&& !(true && ... && (CTriviallyMoveConstructible<Ts> && CTriviallyMoveAssignable<Ts>))) && !(true && ... && (CTriviallyMoveConstructible<Ts> && CTriviallyMoveAssignable<Ts>)))
{ {
if (&InValue == this) return *this; if (&InValue == this) return *this;
@ -180,7 +180,7 @@ public:
} }
template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; }) template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; })
constexpr TVariant& operator=(T&& InValue) FORCEINLINE constexpr TVariant& operator=(T&& InValue)
{ {
using SelectedType = NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; using SelectedType = NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>;
@ -197,7 +197,7 @@ public:
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...>)
constexpr TVariantAlternative<I, TVariant<Ts...>>& Emplace(ArgTypes&&... Args) FORCEINLINE constexpr TVariantAlternative<I, TVariant<Ts...>>& Emplace(ArgTypes&&... Args)
{ {
Reset(); Reset();
@ -209,37 +209,37 @@ public:
} }
template <typename T, typename... ArgTypes> requires (CConstructibleFrom<T, ArgTypes...>) template <typename T, typename... ArgTypes> requires (CConstructibleFrom<T, ArgTypes...>)
constexpr T& Emplace(ArgTypes&&... Args) FORCEINLINE constexpr T& Emplace(ArgTypes&&... Args)
{ {
return Emplace<TVariantIndex<T, TVariant<Ts...>>>(Forward<ArgTypes>(Args)...); return Emplace<TVariantIndex<T, TVariant<Ts...>>>(Forward<ArgTypes>(Args)...);
} }
constexpr const type_info& GetTypeInfo() const { return IsValid() ? *TypeInfos[GetIndex()] : typeid(void); } FORCEINLINE constexpr const type_info& GetTypeInfo() const { return IsValid() ? *TypeInfos[GetIndex()] : typeid(void); }
constexpr size_t GetIndex() const { return TypeIndex != 0xFF ? TypeIndex : INDEX_NONE; } FORCEINLINE constexpr size_t GetIndex() const { return TypeIndex != 0xFF ? TypeIndex : INDEX_NONE; }
constexpr bool IsValid() const { return TypeIndex != 0xFF; } FORCEINLINE constexpr bool IsValid() const { return TypeIndex != 0xFF; }
constexpr explicit operator bool() const { return TypeIndex != 0xFF; } FORCEINLINE constexpr explicit operator bool() const { return TypeIndex != 0xFF; }
template <size_t I> constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == I : false; } template <size_t I> FORCEINLINE constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == I : false; }
template <typename T> constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == TVariantIndex<T, TVariant<Ts...>> : false; } template <typename T> FORCEINLINE constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == TVariantIndex<T, TVariant<Ts...>> : false; }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() & { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< TVariantAlternative<I, TVariant<Ts...>>*>(&Value); } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() & { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< TVariantAlternative<I, TVariant<Ts...>>*>(&Value); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() && { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast< TVariantAlternative<I, TVariant<Ts...>>*>(&Value)); } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() && { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast< TVariantAlternative<I, TVariant<Ts...>>*>(&Value)); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() const& { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const TVariantAlternative<I, TVariant<Ts...>>*>(&Value); } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() const& { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const TVariantAlternative<I, TVariant<Ts...>>*>(&Value); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) GetValue() const&& { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast<const TVariantAlternative<I, TVariant<Ts...>>*>(&Value)); } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) GetValue() const&& { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast<const TVariantAlternative<I, TVariant<Ts...>>*>(&Value)); }
template <typename T> constexpr decltype(auto) GetValue() & { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< T*>(&Value); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() & { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< T*>(&Value); }
template <typename T> constexpr decltype(auto) GetValue() && { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast< T*>(&Value)); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() && { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast< T*>(&Value)); }
template <typename T> constexpr decltype(auto) GetValue() const& { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const T*>(&Value); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() const& { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const T*>(&Value); }
template <typename T> constexpr decltype(auto) GetValue() const&& { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast<const T*>(&Value)); } template <typename T> FORCEINLINE constexpr decltype(auto) GetValue() const&& { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast<const T*>(&Value)); }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) Get( TVariantAlternative<I, TVariant<Ts...>>& DefaultValue) & { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) Get( TVariantAlternative<I, TVariant<Ts...>>& DefaultValue) & { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; }
template <size_t I> requires (I < sizeof...(Ts)) constexpr decltype(auto) Get(const TVariantAlternative<I, TVariant<Ts...>>& DefaultValue) const& { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; } template <size_t I> requires (I < sizeof...(Ts)) FORCEINLINE constexpr decltype(auto) Get(const TVariantAlternative<I, TVariant<Ts...>>& DefaultValue) const& { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; }
template <typename T> constexpr decltype(auto) Get( T& DefaultValue) & { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; } template <typename T> FORCEINLINE constexpr decltype(auto) Get( T& DefaultValue) & { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; }
template <typename T> constexpr decltype(auto) Get(const T& DefaultValue) const& { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; } template <typename T> FORCEINLINE constexpr decltype(auto) Get(const T& DefaultValue) const& { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; }
constexpr void Reset() FORCEINLINE constexpr void Reset()
{ {
if (GetIndex() == INDEX_NONE) return; if (GetIndex() == INDEX_NONE) return;
@ -251,7 +251,7 @@ public:
TypeIndex = static_cast<uint8>(INDEX_NONE); TypeIndex = static_cast<uint8>(INDEX_NONE);
} }
constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Ts>) FORCEINLINE constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Ts>)
{ {
if (!IsValid()) return 114514; if (!IsValid()) return 114514;
@ -263,7 +263,7 @@ public:
return HashCombine(GetTypeHash(GetIndex()), HashImpl[GetIndex()](&Value)); return HashCombine(GetTypeHash(GetIndex()), HashImpl[GetIndex()](&Value));
} }
constexpr void Swap(TVariant& InValue) requires (true && ... && (CMoveConstructible<Ts> && CSwappable<Ts>)) FORCEINLINE constexpr void Swap(TVariant& InValue) requires (true && ... && (CMoveConstructible<Ts> && CSwappable<Ts>))
{ {
if (!IsValid() && !InValue.IsValid()) return; if (!IsValid() && !InValue.IsValid()) return;
@ -317,7 +317,7 @@ 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>) friend FORCEINLINE constexpr bool operator==(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CEqualityComparable<Ts>)
{ {
if (LHS.GetIndex() != RHS.GetIndex()) return false; if (LHS.GetIndex() != RHS.GetIndex()) return false;
if (LHS.IsValid() == false) return true; if (LHS.IsValid() == false) return true;
@ -328,7 +328,7 @@ private:
return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value); return CompareImpl[LHS.GetIndex()](&LHS.Value, &RHS.Value);
} }
friend constexpr partial_ordering operator<=>(const TVariant& LHS, const TVariant& RHS) requires (true && ... && CSynthThreeWayComparable<Ts>) friend FORCEINLINE 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.GetIndex() != RHS.GetIndex()) return partial_ordering::unordered;
if (LHS.IsValid() == false) return partial_ordering::equivalent; if (LHS.IsValid() == false) return partial_ordering::equivalent;
@ -342,13 +342,13 @@ private:
}; };
template <typename T, typename... Ts> requires (!CBaseOf<TVariant<Ts...>, T> && CEqualityComparable<T>) template <typename T, typename... Ts> requires (!CBaseOf<TVariant<Ts...>, T> && CEqualityComparable<T>)
constexpr bool operator==(const TVariant<Ts...>& LHS, const T& RHS) FORCEINLINE constexpr bool operator==(const TVariant<Ts...>& LHS, const T& RHS)
{ {
return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() == RHS : false; return LHS.template HoldsAlternative<T>() ? LHS.template GetValue<T>() == RHS : false;
} }
template <typename... Ts> template <typename... Ts>
constexpr bool operator==(const TVariant<Ts...>& LHS, FInvalid) FORCEINLINE constexpr bool operator==(const TVariant<Ts...>& LHS, FInvalid)
{ {
return !LHS.IsValid(); return !LHS.IsValid();
} }
@ -360,7 +360,7 @@ struct TVariantVisitImpl
{ {
struct GetTotalNum struct GetTotalNum
{ {
static constexpr size_t Do() FORCEINLINE static constexpr size_t Do()
{ {
if (sizeof...(VariantTypes) == 0) return 0; if (sizeof...(VariantTypes) == 0) return 0;
@ -379,7 +379,7 @@ struct TVariantVisitImpl
struct EncodeIndices struct EncodeIndices
{ {
static constexpr size_t Do(initializer_list<size_t> Indices) FORCEINLINE static constexpr size_t Do(initializer_list<size_t> Indices)
{ {
constexpr size_t VariantNums[] = { TVariantNum<TRemoveReference<VariantTypes>>... }; constexpr size_t VariantNums[] = { TVariantNum<TRemoveReference<VariantTypes>>... };
@ -397,7 +397,7 @@ struct TVariantVisitImpl
struct DecodeExtent struct DecodeExtent
{ {
static constexpr size_t Do(size_t EncodedIndex, size_t Extent) FORCEINLINE static constexpr size_t Do(size_t EncodedIndex, size_t Extent)
{ {
constexpr size_t VariantNums[] = { TVariantNum<TRemoveReference<VariantTypes>>... }; constexpr size_t VariantNums[] = { TVariantNum<TRemoveReference<VariantTypes>>... };
@ -416,7 +416,7 @@ struct TVariantVisitImpl
template <size_t EncodedIndex, size_t... ExtentIndices> template <size_t EncodedIndex, size_t... ExtentIndices>
struct InvokeEncoded<EncodedIndex, TIndexSequence<ExtentIndices...>> struct InvokeEncoded<EncodedIndex, TIndexSequence<ExtentIndices...>>
{ {
static constexpr decltype(auto) Do(F&& Func, VariantTypes&&... Variants) FORCEINLINE static constexpr decltype(auto) Do(F&& Func, VariantTypes&&... Variants)
{ {
return Invoke(Forward<F>(Func), Forward<VariantTypes>(Variants).template GetValue<DecodeExtent::Do(EncodedIndex, ExtentIndices)>()...); return Invoke(Forward<F>(Func), Forward<VariantTypes>(Variants).template GetValue<DecodeExtent::Do(EncodedIndex, ExtentIndices)>()...);
} }
@ -424,7 +424,7 @@ struct TVariantVisitImpl
template <typename Ret> template <typename Ret>
struct Result struct Result
{ {
static constexpr Ret Do(F&& Func, VariantTypes&&... Variants) FORCEINLINE static constexpr Ret Do(F&& Func, VariantTypes&&... Variants)
{ {
return InvokeResult<Ret>(Forward<F>(Func), Forward<VariantTypes>(Variants).template GetValue<DecodeExtent::Do(EncodedIndex, ExtentIndices)>()...); return InvokeResult<Ret>(Forward<F>(Func), Forward<VariantTypes>(Variants).template GetValue<DecodeExtent::Do(EncodedIndex, ExtentIndices)>()...);
} }
@ -437,7 +437,7 @@ struct TVariantVisitImpl
template <size_t... EncodedIndices> template <size_t... EncodedIndices>
struct InvokeVariant<TIndexSequence<EncodedIndices...>> struct InvokeVariant<TIndexSequence<EncodedIndices...>>
{ {
static constexpr decltype(auto) Do(F&& Func, VariantTypes&&... Variants) FORCEINLINE static constexpr decltype(auto) Do(F&& Func, VariantTypes&&... Variants)
{ {
using ExtentIndices = TIndexSequenceFor<VariantTypes...>; using ExtentIndices = TIndexSequenceFor<VariantTypes...>;
@ -453,7 +453,7 @@ struct TVariantVisitImpl
template <typename Ret> template <typename Ret>
struct Result struct Result
{ {
static constexpr Ret Do(F&& Func, VariantTypes&&... Variants) FORCEINLINE static constexpr Ret Do(F&& Func, VariantTypes&&... Variants)
{ {
using ExtentIndices = TIndexSequenceFor<VariantTypes...>; using ExtentIndices = TIndexSequenceFor<VariantTypes...>;
@ -466,7 +466,7 @@ struct TVariantVisitImpl
}; };
}; };
static constexpr decltype(auto) Do(F&& Func, VariantTypes&&... Variants) FORCEINLINE static constexpr decltype(auto) Do(F&& Func, VariantTypes&&... Variants)
{ {
return InvokeVariant<TMakeIndexSequence<GetTotalNum::Do()>>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...); return InvokeVariant<TMakeIndexSequence<GetTotalNum::Do()>>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...);
} }
@ -474,7 +474,7 @@ struct TVariantVisitImpl
template <typename Ret> template <typename Ret>
struct Result struct Result
{ {
static constexpr Ret Do(F&& Func, VariantTypes&&... Variants) FORCEINLINE static constexpr Ret Do(F&& Func, VariantTypes&&... Variants)
{ {
return InvokeVariant<TMakeIndexSequence<GetTotalNum::Do()>>::template Result<Ret>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...); return InvokeVariant<TMakeIndexSequence<GetTotalNum::Do()>>::template Result<Ret>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...);
} }
@ -485,7 +485,7 @@ NAMESPACE_PRIVATE_END
template <typename F, typename FirstVariantType, typename... VariantTypes> template <typename F, typename FirstVariantType, typename... VariantTypes>
requires (CTVariant<TRemoveReference<FirstVariantType>> && (true && ... && CTVariant<TRemoveReference<VariantTypes>>)) requires (CTVariant<TRemoveReference<FirstVariantType>> && (true && ... && CTVariant<TRemoveReference<VariantTypes>>))
constexpr decltype(auto) Visit(F&& Func, FirstVariantType&& FirstVariant, VariantTypes&&... Variants) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, FirstVariantType&& FirstVariant, VariantTypes&&... Variants)
{ {
checkf((true && ... && Variants.IsValid()), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid().")); checkf((true && ... && Variants.IsValid()), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid()."));
return NAMESPACE_PRIVATE::TVariantVisitImpl<F, FirstVariantType, VariantTypes...>::Do(Forward<F>(Func), Forward<FirstVariantType>(FirstVariant), Forward<VariantTypes>(Variants)...); return NAMESPACE_PRIVATE::TVariantVisitImpl<F, FirstVariantType, VariantTypes...>::Do(Forward<F>(Func), Forward<FirstVariantType>(FirstVariant), Forward<VariantTypes>(Variants)...);
@ -493,7 +493,7 @@ constexpr decltype(auto) Visit(F&& Func, FirstVariantType&& FirstVariant, Varian
template <typename Ret, typename F, typename FirstVariantType, typename... VariantTypes> template <typename Ret, typename F, typename FirstVariantType, typename... VariantTypes>
requires (CTVariant<TRemoveReference<FirstVariantType>> && (true && ... && CTVariant<TRemoveReference<VariantTypes>>)) requires (CTVariant<TRemoveReference<FirstVariantType>> && (true && ... && CTVariant<TRemoveReference<VariantTypes>>))
constexpr Ret Visit(F&& Func, FirstVariantType&& FirstVariant, VariantTypes&&... Variants) FORCEINLINE constexpr Ret Visit(F&& Func, FirstVariantType&& FirstVariant, VariantTypes&&... Variants)
{ {
checkf((true && ... && Variants.IsValid()), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid().")); checkf((true && ... && Variants.IsValid()), TEXT("It is an error to call Visit() on an wrong TVariant. Please either check IsValid()."));
return NAMESPACE_PRIVATE::TVariantVisitImpl<F, FirstVariantType, VariantTypes...>::template Result<Ret>::Do(Forward<F>(Func), Forward<FirstVariantType>(FirstVariant), Forward<VariantTypes>(Variants)...); return NAMESPACE_PRIVATE::TVariantVisitImpl<F, FirstVariantType, VariantTypes...>::template Result<Ret>::Do(Forward<F>(Func), Forward<FirstVariantType>(FirstVariant), Forward<VariantTypes>(Variants)...);

View File

@ -12,8 +12,8 @@ struct TConstant
using ValueType = InType; using ValueType = InType;
using Type = TConstant; using Type = TConstant;
static constexpr ValueType Value = InValue; static constexpr ValueType Value = InValue;
constexpr operator ValueType() const { return Value; } FORCEINLINE constexpr operator ValueType() const { return Value; }
constexpr ValueType operator()() const { return Value; } FORCEINLINE constexpr ValueType operator()() const { return Value; }
}; };
template <bool InValue> template <bool InValue>