refactor(*): make type alias identifiers conform to the style for general type identifiers

This commit is contained in:
2024-12-16 19:34:47 +08:00
parent d2b6e0c669
commit 312cfe4097
54 changed files with 1738 additions and 1698 deletions

View File

@ -15,9 +15,9 @@ NAMESPACE_MODULE_BEGIN(Utility)
// NOTE: In the STL, the assignment operation of the std::any type uses the copy-and-swap idiom
// instead of directly calling the assignment operation of the contained value.
// The purpose of this is as follows:
// 1) the copy assignment might not exist.
// 2) the typical case is that the objects are different.
// The purpose of this is as follows:
// 1) the copy assignment might not exist.
// 2) the typical case is that the objects are different.
// 3) it is less exception-safe
// But we don't follow the the copy-and-swap idiom, because we assume that no function throws an exception.
@ -107,7 +107,7 @@ public:
{
EmplaceImpl<T>(Forward<Ts>(Args)...);
}
/** Constructs an object with initial content an object of type TDecay<T>, direct-non-list-initialized from IL, Forward<Ts>(Args).... */
template <typename T, typename U, typename... Ts> requires (NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, initializer_list<U>, Ts&&...>)
FORCEINLINE explicit FAny(TInPlaceType<T>, initializer_list<U> IL, Ts&&... Args)
@ -244,23 +244,23 @@ public:
&& NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CConstructibleFrom<TDecay<T>, T&&>)
FORCEINLINE FAny& operator=(T&& InValue)
{
using DecayedType = TDecay<T>;
using FDecayedType = TDecay<T>;
if constexpr (CAssignableFrom<DecayedType, T&&>)
if constexpr (CAssignableFrom<FDecayedType, T&&>)
{
if (HoldsAlternative<DecayedType>())
if (HoldsAlternative<FDecayedType>())
{
GetValue<DecayedType>() = Forward<T>(InValue);
GetValue<FDecayedType>() = Forward<T>(InValue);
return *this;
}
}
Destroy();
EmplaceImpl<DecayedType>(Forward<T>(InValue));
EmplaceImpl<FDecayedType>(Forward<T>(InValue));
return *this;
}
/** Check if the contained value is equivalent to 'InValue'. */
template <typename T> requires (!CSameAs<FAny, TRemoveCVRef<T>> && NAMESPACE_PRIVATE::CFAnyPlaceable<T> && CEqualityComparable<T>)
NODISCARD FORCEINLINE constexpr bool operator==(const T& InValue) const&
@ -352,12 +352,12 @@ public:
Destroy();
Invalidate();
}
/** Overloads the Swap algorithm for FAny. */
friend void Swap(FAny& A, FAny& B)
{
if (!A.IsValid() && !B.IsValid()) return;
if (A.IsValid() && !B.IsValid())
{
B = MoveTemp(A);
@ -524,7 +524,7 @@ private:
default: check_no_entry(); return nullptr;
}
}
FORCEINLINE const void* GetStorage() const
{
switch (GetRepresentation())
@ -536,36 +536,36 @@ private:
default: check_no_entry(); return nullptr;
}
}
template <typename T, typename... Ts>
void EmplaceImpl(Ts&&... Args)
{
using DecayedType = TDecay<T>;
using FDecayedType = TDecay<T>;
TypeInfo = reinterpret_cast<uintptr>(&typeid(DecayedType));
TypeInfo = reinterpret_cast<uintptr>(&typeid(FDecayedType));
if constexpr (CEmpty<DecayedType> && CTrivial<DecayedType>) return; // ERepresentation::Empty
if constexpr (CEmpty<FDecayedType> && CTrivial<FDecayedType>) return; // ERepresentation::Empty
constexpr bool bIsTriviallyStorable = sizeof(DecayedType) <= sizeof(TrivialStorage.Internal) && alignof(DecayedType) <= alignof(FAny) && CTriviallyCopyable<DecayedType>;
constexpr bool bIsSmallStorable = sizeof(DecayedType) <= sizeof( SmallStorage.Internal) && alignof(DecayedType) <= alignof(FAny);
constexpr bool bIsTriviallyStorable = sizeof(FDecayedType) <= sizeof(TrivialStorage.Internal) && alignof(FDecayedType) <= alignof(FAny) && CTriviallyCopyable<FDecayedType>;
constexpr bool bIsSmallStorable = sizeof(FDecayedType) <= sizeof( SmallStorage.Internal) && alignof(FDecayedType) <= alignof(FAny);
static constexpr const FRTTI SelectedRTTI(InPlaceType<DecayedType>);
static constexpr const FRTTI SelectedRTTI(InPlaceType<FDecayedType>);
if constexpr (bIsTriviallyStorable)
{
new (&TrivialStorage.Internal) DecayedType(Forward<Ts>(Args)...);
new (&TrivialStorage.Internal) FDecayedType(Forward<Ts>(Args)...);
TypeInfo |= static_cast<uintptr>(ERepresentation::Trivial);
}
else if constexpr (bIsSmallStorable)
{
new (&SmallStorage.Internal) DecayedType(Forward<Ts>(Args)...);
new (&SmallStorage.Internal) FDecayedType(Forward<Ts>(Args)...);
SmallStorage.RTTI = &SelectedRTTI;
TypeInfo |= static_cast<uintptr>(ERepresentation::Small);
}
else
{
BigStorage.External = Memory::Malloc(sizeof(DecayedType), alignof(DecayedType));
new (BigStorage.External) DecayedType(Forward<Ts>(Args)...);
BigStorage.External = Memory::Malloc(sizeof(FDecayedType), alignof(FDecayedType));
new (BigStorage.External) FDecayedType(Forward<Ts>(Args)...);
BigStorage.RTTI = &SelectedRTTI;
TypeInfo |= static_cast<uintptr>(ERepresentation::Big);
}

View File

@ -20,7 +20,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
* the values change in an order different from the order another thread wrote them. Indeed,
* the apparent order of changes can even differ among multiple reader threads. Some similar effects
* can occur even on uniprocessor systems due to compiler transformations allowed by the memory model.
*
*
* @see https://en.cppreference.com/w/cpp/atomic/memory_order
*/
enum class EMemoryOrder : uint8
@ -68,48 +68,48 @@ struct TAtomicImpl : FSingleton
{
protected:
using NativeAtomicType = TConditional<bIsRef, NAMESPACE_STD::atomic_ref<T>, NAMESPACE_STD::atomic<T>>;
using FNativeAtomic = TConditional<bIsRef, NAMESPACE_STD::atomic_ref<T>, NAMESPACE_STD::atomic<T>>;
public:
using ValueType = T;
using FValueType = T;
/** Indicates that the type is always lock-free */
static constexpr bool bIsAlwaysLockFree = NativeAtomicType::is_always_lock_free;
static constexpr bool bIsAlwaysLockFree = FNativeAtomic::is_always_lock_free;
/** Indicates the required alignment of an object to be referenced by TAtomicRef. */
static constexpr size_t RequiredAlignment = NAMESPACE_STD::atomic_ref<T>::required_alignment;
/** Constructs an atomic object. */
FORCEINLINE constexpr TAtomicImpl() requires (!bIsRef) : NativeAtomic() { };
FORCEINLINE constexpr TAtomicImpl(ValueType Desired) requires (!bIsRef) : NativeAtomic(Desired) { };
FORCEINLINE constexpr TAtomicImpl() requires (!bIsRef) : NativeAtomic() { }
FORCEINLINE constexpr TAtomicImpl(FValueType Desired) requires (!bIsRef) : NativeAtomic(Desired) { }
/** Constructs an atomic reference. */
FORCEINLINE explicit TAtomicImpl(ValueType& Desired) requires (bIsRef) : NativeAtomic(Desired) { check(Memory::IsAligned(&Desired, RequiredAlignment)); };
FORCEINLINE TAtomicImpl(TAtomicImpl& InValue) requires (bIsRef) : NativeAtomic(InValue) { };
FORCEINLINE explicit TAtomicImpl(FValueType& Desired) requires (bIsRef) : NativeAtomic(Desired) { check(Memory::IsAligned(&Desired, RequiredAlignment)); }
FORCEINLINE TAtomicImpl(TAtomicImpl& InValue) requires (bIsRef) : NativeAtomic(InValue) { }
/** Stores a value into an atomic object. */
FORCEINLINE ValueType operator=(ValueType Desired) { return NativeAtomic = Desired; }
FORCEINLINE ValueType operator=(ValueType Desired) volatile requires (bIsAlwaysLockFree) { return NativeAtomic = Desired; }
FORCEINLINE FValueType operator=(FValueType Desired) { return NativeAtomic = Desired; }
FORCEINLINE FValueType operator=(FValueType Desired) volatile requires (bIsAlwaysLockFree) { return NativeAtomic = Desired; }
/** Atomically replaces the value of the atomic object with a non-atomic argument. */
FORCEINLINE void Store(ValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.store(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Store(ValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (bIsAlwaysLockFree) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.store(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Store(FValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.store(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Store(FValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (bIsAlwaysLockFree) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.store(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically obtains the value of the atomic object. */
NODISCARD FORCEINLINE ValueType Load(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); return NativeAtomic.load(static_cast<NAMESPACE_STD::memory_order>(Order)); }
NODISCARD FORCEINLINE ValueType Load(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const volatile requires (bIsAlwaysLockFree) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); return NativeAtomic.load(static_cast<NAMESPACE_STD::memory_order>(Order)); }
NODISCARD FORCEINLINE FValueType Load(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); return NativeAtomic.load(static_cast<NAMESPACE_STD::memory_order>(Order)); }
NODISCARD FORCEINLINE FValueType Load(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const volatile requires (bIsAlwaysLockFree) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); return NativeAtomic.load(static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Loads a value from an atomic object. */
NODISCARD FORCEINLINE operator ValueType() const { return static_cast<ValueType>(NativeAtomic); }
NODISCARD FORCEINLINE operator ValueType() const volatile requires (bIsAlwaysLockFree) { return static_cast<ValueType>(NativeAtomic); }
NODISCARD FORCEINLINE operator FValueType() const { return static_cast<FValueType>(NativeAtomic); }
NODISCARD FORCEINLINE operator FValueType() const volatile requires (bIsAlwaysLockFree) { return static_cast<FValueType>(NativeAtomic); }
/** Atomically replaces the value of the atomic object and obtains the value held previously. */
NODISCARD FORCEINLINE ValueType Exchange(ValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { return NativeAtomic.exchange(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
NODISCARD FORCEINLINE ValueType Exchange(ValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (bIsAlwaysLockFree) { return NativeAtomic.exchange(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
NODISCARD FORCEINLINE FValueType Exchange(FValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { return NativeAtomic.exchange(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
NODISCARD FORCEINLINE FValueType Exchange(FValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (bIsAlwaysLockFree) { return NativeAtomic.exchange(Desired, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not. */
NODISCARD FORCEINLINE bool CompareExchange(ValueType& Expected, ValueType Desired, EMemoryOrder Success, EMemoryOrder Failure, bool bIsWeak = false)
NODISCARD FORCEINLINE bool CompareExchange(FValueType& Expected, FValueType Desired, EMemoryOrder Success, EMemoryOrder Failure, bool bIsWeak = false)
{
MEMORY_ORDER_CHECK(Failure, 0x01 | 0x02 | 0x04 | 0x20);
if (bIsWeak) return NativeAtomic.compare_exchange_weak(Expected, Desired, static_cast<NAMESPACE_STD::memory_order>(Success), static_cast<NAMESPACE_STD::memory_order>(Failure));
@ -117,7 +117,7 @@ public:
}
/** Atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not. */
NODISCARD FORCEINLINE bool CompareExchange(ValueType& Expected, ValueType Desired, EMemoryOrder Success, EMemoryOrder Failure, bool bIsWeak = false) volatile requires (bIsAlwaysLockFree)
NODISCARD FORCEINLINE bool CompareExchange(FValueType& Expected, FValueType Desired, EMemoryOrder Success, EMemoryOrder Failure, bool bIsWeak = false) volatile requires (bIsAlwaysLockFree)
{
MEMORY_ORDER_CHECK(Failure, 0x01 | 0x02 | 0x04 | 0x20);
if (bIsWeak) return NativeAtomic.compare_exchange_weak(Expected, Desired, static_cast<NAMESPACE_STD::memory_order>(Success), static_cast<NAMESPACE_STD::memory_order>(Failure));
@ -125,162 +125,162 @@ public:
}
/** Atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not. */
NODISCARD FORCEINLINE bool CompareExchange(ValueType& Expected, ValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent, bool bIsWeak = false)
NODISCARD FORCEINLINE bool CompareExchange(FValueType& Expected, FValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent, bool bIsWeak = false)
{
if (bIsWeak) return NativeAtomic.compare_exchange_weak(Expected, Desired, static_cast<NAMESPACE_STD::memory_order>(Order));
else return NativeAtomic.compare_exchange_strong(Expected, Desired, static_cast<NAMESPACE_STD::memory_order>(Order));
}
/** Atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not. */
NODISCARD FORCEINLINE bool CompareExchange(ValueType& Expected, ValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent, bool bIsWeak = false) volatile requires (bIsAlwaysLockFree)
NODISCARD FORCEINLINE bool CompareExchange(FValueType& Expected, FValueType Desired, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent, bool bIsWeak = false) volatile requires (bIsAlwaysLockFree)
{
if (bIsWeak) return NativeAtomic.compare_exchange_weak(Expected, Desired, static_cast<NAMESPACE_STD::memory_order>(Order));
else return NativeAtomic.compare_exchange_strong(Expected, Desired, static_cast<NAMESPACE_STD::memory_order>(Order));
}
/** Blocks the thread until notified and the atomic value changes. */
FORCEINLINE void Wait(ValueType Old, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); NativeAtomic.wait(Old, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Wait(ValueType Old, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); NativeAtomic.wait(Old, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Wait(FValueType Old, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); NativeAtomic.wait(Old, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Wait(FValueType Old, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); NativeAtomic.wait(Old, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Notifies at least one or all threads blocked waiting on the atomic object. */
FORCEINLINE void Notify(bool bIsAll = false) { if (bIsAll) NativeAtomic.notify_all(); else NativeAtomic.notify_one(); }
FORCEINLINE void Notify(bool bIsAll = false) volatile { if (bIsAll) NativeAtomic.notify_all(); else NativeAtomic.notify_one(); }
/** Atomically executes the 'Func' on the value stored in the atomic object and obtains the value held previously. */
template <typename F> requires (CInvocableResult<ValueType, F, ValueType>)
FORCEINLINE ValueType FetchFn(F&& Func, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent)
template <typename F> requires (CInvocableResult<FValueType, F, FValueType>)
FORCEINLINE FValueType FetchFn(F&& Func, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent)
{
ValueType Temp(Load(EMemoryOrder::Relaxed));
FValueType Temp(Load(EMemoryOrder::Relaxed));
// We do a weak read here because we require a loop.
while (!CompareExchange(Temp, InvokeResult<ValueType>(Forward<F>(Func), Temp), Order, true));
while (!CompareExchange(Temp, InvokeResult<FValueType>(Forward<F>(Func), Temp), Order, true));
return Temp;
}
/** Atomically executes the 'Func' on the value stored in the atomic object and obtains the value held previously. */
template <typename F> requires (CInvocableResult<ValueType, F, ValueType> && bIsAlwaysLockFree)
FORCEINLINE ValueType FetchFn(F&& Func, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile
template <typename F> requires (CInvocableResult<FValueType, F, FValueType> && bIsAlwaysLockFree)
FORCEINLINE FValueType FetchFn(F&& Func, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile
{
ValueType Temp(Load(EMemoryOrder::Relaxed));
FValueType Temp(Load(EMemoryOrder::Relaxed));
// We do a weak read here because we require a loop.
while (!CompareExchange(Temp, InvokeResult<ValueType>(Forward<F>(Func), Temp), Order, true));
while (!CompareExchange(Temp, InvokeResult<FValueType>(Forward<F>(Func), Temp), Order, true));
return Temp;
}
/** Atomically adds the argument to the value stored in the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchAdd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAdd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchAdd(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchAdd(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically adds the argument to the value stored in the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchAdd(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CPointer<T> ) { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAdd(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchAdd(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CPointer<T> ) { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchAdd(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchSub(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchSub(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchSub(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically subtracts the argument from the value stored in the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchSub(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CPointer<T> ) { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchSub(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CPointer<T> ) { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchSub(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically multiples the argument from the value stored in the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchMul(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old * InValue; }); }
FORCEINLINE ValueType FetchMul(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return FetchFn([InValue](ValueType Old) -> ValueType { return Old * InValue; }); }
FORCEINLINE FValueType FetchMul(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old * InValue; }); }
FORCEINLINE FValueType FetchMul(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return FetchFn([InValue](FValueType Old) -> FValueType { return Old * InValue; }); }
/** Atomically divides the argument from the value stored in the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchDiv(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old / InValue; }); }
FORCEINLINE ValueType FetchDiv(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return FetchFn([InValue](ValueType Old) -> ValueType { return Old / InValue; }); }
FORCEINLINE FValueType FetchDiv(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old / InValue; }); }
FORCEINLINE FValueType FetchDiv(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return FetchFn([InValue](FValueType Old) -> FValueType { return Old / InValue; }); }
/** Atomically models the argument from the value stored in the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchMod(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old % InValue; }); }
FORCEINLINE ValueType FetchMod(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old % InValue; }); }
FORCEINLINE FValueType FetchMod(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old % InValue; }); }
FORCEINLINE FValueType FetchMod(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old % InValue; }); }
/** Atomically performs bitwise AND between the argument and the value of the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchAnd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return NativeAtomic.fetch_and(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAnd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_and(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchAnd(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return NativeAtomic.fetch_and(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchAnd(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_and(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically performs bitwise OR between the argument and the value of the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchOr(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return NativeAtomic.fetch_or(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchOr(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_or(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchOr(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return NativeAtomic.fetch_or(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchOr(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_or(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically performs bitwise XOR between the argument and the value of the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchXor(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return NativeAtomic.fetch_xor(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchXor(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_xor(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchXor(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return NativeAtomic.fetch_xor(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE FValueType FetchXor(FValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic.fetch_xor(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Atomically performs bitwise LSH between the argument and the value of the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchLsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old << InValue; }); }
FORCEINLINE ValueType FetchLsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old << InValue; }); }
FORCEINLINE FValueType FetchLsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old << InValue; }); }
FORCEINLINE FValueType FetchLsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old << InValue; }); }
/** Atomically performs bitwise RSH between the argument and the value of the atomic object and obtains the value held previously. */
FORCEINLINE ValueType FetchRsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old >> InValue; }); }
FORCEINLINE ValueType FetchRsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old >> InValue; }); }
/** Increments the atomic value by one. */
FORCEINLINE ValueType operator++() requires ((CIntegral<T> || CPointer<T>) ) { return ++NativeAtomic; }
FORCEINLINE ValueType operator++() volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return ++NativeAtomic; }
FORCEINLINE FValueType FetchRsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> ) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old >> InValue; }); }
FORCEINLINE FValueType FetchRsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchFn([InValue](FValueType Old) -> FValueType { return Old >> InValue; }); }
/** Increments the atomic value by one. */
FORCEINLINE ValueType operator++(int) requires ((CIntegral<T> || CPointer<T>) ) { return NativeAtomic++; }
FORCEINLINE ValueType operator++(int) volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return NativeAtomic++; }
FORCEINLINE FValueType operator++() requires ((CIntegral<T> || CPointer<T>) ) { return ++NativeAtomic; }
FORCEINLINE FValueType operator++() volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return ++NativeAtomic; }
/** Increments the atomic value by one. */
FORCEINLINE FValueType operator++(int) requires ((CIntegral<T> || CPointer<T>) ) { return NativeAtomic++; }
FORCEINLINE FValueType operator++(int) volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return NativeAtomic++; }
/** Decrements the atomic value by one. */
FORCEINLINE ValueType operator--() requires ((CIntegral<T> || CPointer<T>) ) { return --NativeAtomic; }
FORCEINLINE ValueType operator--() volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return --NativeAtomic; }
FORCEINLINE FValueType operator--() requires ((CIntegral<T> || CPointer<T>) ) { return --NativeAtomic; }
FORCEINLINE FValueType operator--() volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return --NativeAtomic; }
/** Decrements the atomic value by one. */
FORCEINLINE ValueType operator--(int) requires ((CIntegral<T> || CPointer<T>) ) { return NativeAtomic--; }
FORCEINLINE ValueType operator--(int) volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return NativeAtomic--; }
/** Adds with the atomic value. */
FORCEINLINE ValueType operator+=(ValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return NativeAtomic += InValue; }
FORCEINLINE ValueType operator+=(ValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return NativeAtomic += InValue; }
FORCEINLINE FValueType operator--(int) requires ((CIntegral<T> || CPointer<T>) ) { return NativeAtomic--; }
FORCEINLINE FValueType operator--(int) volatile requires ((CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree) { return NativeAtomic--; }
/** Adds with the atomic value. */
FORCEINLINE ValueType operator+=(ptrdiff InValue) requires (CPointer<T> ) { return NativeAtomic += InValue; }
FORCEINLINE ValueType operator+=(ptrdiff InValue) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic += InValue; }
FORCEINLINE FValueType operator+=(FValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return NativeAtomic += InValue; }
FORCEINLINE FValueType operator+=(FValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return NativeAtomic += InValue; }
/** Adds with the atomic value. */
FORCEINLINE FValueType operator+=(ptrdiff InValue) requires (CPointer<T> ) { return NativeAtomic += InValue; }
FORCEINLINE FValueType operator+=(ptrdiff InValue) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic += InValue; }
/** Subtracts with the atomic value. */
FORCEINLINE ValueType operator-=(ValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return NativeAtomic -= InValue; }
FORCEINLINE ValueType operator-=(ValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return NativeAtomic -= InValue; }
FORCEINLINE FValueType operator-=(FValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return NativeAtomic -= InValue; }
FORCEINLINE FValueType operator-=(FValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return NativeAtomic -= InValue; }
/** Subtracts with the atomic value. */
FORCEINLINE ValueType operator-=(ptrdiff InValue) requires (CPointer<T> ) { return NativeAtomic -= InValue; }
FORCEINLINE ValueType operator-=(ptrdiff InValue) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic -= InValue; }
FORCEINLINE FValueType operator-=(ptrdiff InValue) requires (CPointer<T> ) { return NativeAtomic -= InValue; }
FORCEINLINE FValueType operator-=(ptrdiff InValue) volatile requires (CPointer<T> && bIsAlwaysLockFree) { return NativeAtomic -= InValue; }
/** Multiples with the atomic value. */
FORCEINLINE ValueType operator*=(ValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return FetchMul(InValue) * InValue; }
FORCEINLINE ValueType operator*=(ValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return FetchMul(InValue) * InValue; }
FORCEINLINE FValueType operator*=(FValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return FetchMul(InValue) * InValue; }
FORCEINLINE FValueType operator*=(FValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return FetchMul(InValue) * InValue; }
/** Divides with the atomic value. */
FORCEINLINE ValueType operator/=(ValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return FetchDiv(InValue) / InValue; }
FORCEINLINE ValueType operator/=(ValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return FetchDiv(InValue) / InValue; }
FORCEINLINE FValueType operator/=(FValueType InValue) requires ((CIntegral<T> || CFloatingPoint<T>) ) { return FetchDiv(InValue) / InValue; }
FORCEINLINE FValueType operator/=(FValueType InValue) volatile requires ((CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree) { return FetchDiv(InValue) / InValue; }
/** Models with the atomic value. */
FORCEINLINE ValueType operator%=(ValueType InValue) requires (CIntegral<T> ) { return FetchMod(InValue) % InValue; }
FORCEINLINE ValueType operator%=(ValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchMod(InValue) % InValue; }
FORCEINLINE FValueType operator%=(FValueType InValue) requires (CIntegral<T> ) { return FetchMod(InValue) % InValue; }
FORCEINLINE FValueType operator%=(FValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchMod(InValue) % InValue; }
/** Performs bitwise AND with the atomic value. */
FORCEINLINE ValueType operator&=(ValueType InValue) requires (CIntegral<T> ) { return NativeAtomic &= InValue; }
FORCEINLINE ValueType operator&=(ValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic &= InValue; }
FORCEINLINE FValueType operator&=(FValueType InValue) requires (CIntegral<T> ) { return NativeAtomic &= InValue; }
FORCEINLINE FValueType operator&=(FValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic &= InValue; }
/** Performs bitwise OR with the atomic value. */
FORCEINLINE ValueType operator|=(ValueType InValue) requires (CIntegral<T> ) { return NativeAtomic |= InValue; }
FORCEINLINE ValueType operator|=(ValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic |= InValue; }
FORCEINLINE FValueType operator|=(FValueType InValue) requires (CIntegral<T> ) { return NativeAtomic |= InValue; }
FORCEINLINE FValueType operator|=(FValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic |= InValue; }
/** Performs bitwise XOR with the atomic value. */
FORCEINLINE ValueType operator^=(ValueType InValue) requires (CIntegral<T> ) { return NativeAtomic ^= InValue; }
FORCEINLINE ValueType operator^=(ValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic ^= InValue; }
FORCEINLINE FValueType operator^=(FValueType InValue) requires (CIntegral<T> ) { return NativeAtomic ^= InValue; }
FORCEINLINE FValueType operator^=(FValueType InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return NativeAtomic ^= InValue; }
/** Performs bitwise LSH with the atomic value. */
FORCEINLINE ValueType operator<<=(size_t InValue) requires (CIntegral<T> ) { return FetchLsh(InValue) << InValue; }
FORCEINLINE ValueType operator<<=(size_t InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchLsh(InValue) << InValue; }
FORCEINLINE FValueType operator<<=(size_t InValue) requires (CIntegral<T> ) { return FetchLsh(InValue) << InValue; }
FORCEINLINE FValueType operator<<=(size_t InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchLsh(InValue) << InValue; }
/** Performs bitwise RSH with the atomic value. */
FORCEINLINE ValueType operator>>=(size_t InValue) requires (CIntegral<T> ) { return FetchRsh(InValue) >> InValue; }
FORCEINLINE ValueType operator>>=(size_t InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchRsh(InValue) >> InValue; }
FORCEINLINE FValueType operator>>=(size_t InValue) requires (CIntegral<T> ) { return FetchRsh(InValue) >> InValue; }
FORCEINLINE FValueType operator>>=(size_t InValue) volatile requires (CIntegral<T> && bIsAlwaysLockFree) { return FetchRsh(InValue) >> InValue; }
protected:
NativeAtomicType NativeAtomic;
FNativeAtomic NativeAtomic;
};
@ -311,7 +311,7 @@ struct FAtomicFlag final : FSingleton
public:
/** Constructs an atomic flag. */
FORCEINLINE constexpr FAtomicFlag() : NativeAtomic() { };
FORCEINLINE constexpr FAtomicFlag() = default;
/** Atomically sets flag to false. */
FORCEINLINE void Clear(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) { MEMORY_ORDER_CHECK(Order, 0x01 | 0x08 | 0x20); NativeAtomic.clear(static_cast<NAMESPACE_STD::memory_order>(Order)); }
@ -324,7 +324,7 @@ public:
/** Atomically returns the value of the flag. */
NODISCARD FORCEINLINE bool Test(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); return NativeAtomic.test(static_cast<NAMESPACE_STD::memory_order>(Order)); }
NODISCARD FORCEINLINE bool Test(EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const volatile { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); return NativeAtomic.test(static_cast<NAMESPACE_STD::memory_order>(Order)); }
/** Blocks the thread until notified and the atomic value changes. */
FORCEINLINE void Wait(bool Old, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); const_cast<const NAMESPACE_STD::atomic_flag&>(NativeAtomic).wait(Old, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE void Wait(bool Old, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) const volatile { MEMORY_ORDER_CHECK(Order, 0x01 | 0x02 | 0x04 | 0x20); const_cast<const NAMESPACE_STD::atomic_flag&>(NativeAtomic).wait(Old, static_cast<NAMESPACE_STD::memory_order>(Order)); }
@ -332,7 +332,7 @@ public:
/** Notifies at least one or all threads blocked waiting on the atomic object. */
FORCEINLINE void Notify(bool bIsAll = false) { if (bIsAll) const_cast<NAMESPACE_STD::atomic_flag&>(NativeAtomic).notify_all(); else const_cast<NAMESPACE_STD::atomic_flag&>(NativeAtomic).notify_one(); }
FORCEINLINE void Notify(bool bIsAll = false) volatile { if (bIsAll) const_cast<NAMESPACE_STD::atomic_flag&>(NativeAtomic).notify_all(); else const_cast<NAMESPACE_STD::atomic_flag&>(NativeAtomic).notify_one(); }
private:
NAMESPACE_STD::atomic_flag NativeAtomic;

View File

@ -262,29 +262,29 @@ public:
{
Callable = InCallable;
using DecayedType = TDecay<T>;
using FDecayedType = TDecay<T>;
static constexpr const FRTTI SelectedRTTI(InPlaceType<DecayedType>);
static constexpr const FRTTI SelectedRTTI(InPlaceType<FDecayedType>);
RTTI = reinterpret_cast<uintptr>(&SelectedRTTI);
if constexpr (CEmpty<DecayedType> && CTrivial<DecayedType>) return; // ERepresentation::Empty
if constexpr (CEmpty<FDecayedType> && CTrivial<FDecayedType>) return; // ERepresentation::Empty
constexpr bool bIsTriviallyStorable = sizeof(DecayedType) <= sizeof(InternalStorage) && alignof(DecayedType) <= alignof(TFunctionStorage) && CTriviallyCopyable<DecayedType>;
constexpr bool bIsSmallStorable = sizeof(DecayedType) <= sizeof(InternalStorage) && alignof(DecayedType) <= alignof(TFunctionStorage);
constexpr bool bIsTriviallyStorable = sizeof(FDecayedType) <= sizeof(InternalStorage) && alignof(FDecayedType) <= alignof(TFunctionStorage) && CTriviallyCopyable<FDecayedType>;
constexpr bool bIsSmallStorable = sizeof(FDecayedType) <= sizeof(InternalStorage) && alignof(FDecayedType) <= alignof(TFunctionStorage);
if constexpr (bIsTriviallyStorable)
{
new (&InternalStorage) DecayedType(Forward<Ts>(Args)...);
new (&InternalStorage) FDecayedType(Forward<Ts>(Args)...);
RTTI |= static_cast<uintptr>(ERepresentation::Trivial);
}
else if constexpr (bIsSmallStorable)
{
new (&InternalStorage) DecayedType(Forward<Ts>(Args)...);
new (&InternalStorage) FDecayedType(Forward<Ts>(Args)...);
RTTI |= static_cast<uintptr>(ERepresentation::Small);
}
else
{
ExternalStorage = new DecayedType(Forward<Ts>(Args)...);
ExternalStorage = new FDecayedType(Forward<Ts>(Args)...);
RTTI |= static_cast<uintptr>(ERepresentation::Big);
}
@ -446,12 +446,12 @@ template <typename Ret, typename... Ts, typename F> struct TIsInvocableSignature
template <typename Ret, typename... Ts, typename F> struct TIsInvocableSignature<Ret(Ts...) const&&, F> : TBoolConstant<CInvocableResult<Ret, const F , Ts...>> { };
template <typename F> struct TFunctionInfo;
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) > { using Fn = Ret(Ts...); using CVRef = int; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) & > { using Fn = Ret(Ts...); using CVRef = int&; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) && > { using Fn = Ret(Ts...); using CVRef = int&&; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) const > { using Fn = Ret(Ts...); using CVRef = const int; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) const& > { using Fn = Ret(Ts...); using CVRef = const int&; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) const&&> { using Fn = Ret(Ts...); using CVRef = const int&&; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) > { using FFn = Ret(Ts...); using FCVRef = int; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) & > { using FFn = Ret(Ts...); using FCVRef = int&; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) && > { using FFn = Ret(Ts...); using FCVRef = int&&; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) const > { using FFn = Ret(Ts...); using FCVRef = const int; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) const& > { using FFn = Ret(Ts...); using FCVRef = const int&; };
template <typename Ret, typename... Ts> struct TFunctionInfo<Ret(Ts...) const&&> { using FFn = Ret(Ts...); using FCVRef = const int&&; };
template <typename F, typename CVRef, bool bIsRef, bool bIsUnique = false> class TFunctionImpl;
@ -460,8 +460,8 @@ class TFunctionImpl<Ret(Ts...), CVRef, bIsRef, bIsUnique>
{
public:
using ResultType = Ret;
using ArgumentType = TTypeSequence<Ts...>;
using FResultType = Ret;
using FArgumentType = TTypeSequence<Ts...>;
FORCEINLINE constexpr TFunctionImpl() = default;
FORCEINLINE constexpr TFunctionImpl(const TFunctionImpl&) = default;
@ -471,12 +471,12 @@ public:
FORCEINLINE constexpr ~TFunctionImpl() = default;
/** Invokes the stored callable function target with the parameters 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)...); }
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 FResultType operator()(Ts... Args) requires (CSameAs<CVRef, int >) { return CallImpl(Forward<Ts>(Args)...); }
FORCEINLINE FResultType operator()(Ts... Args) & requires (CSameAs<CVRef, int& >) { return CallImpl(Forward<Ts>(Args)...); }
FORCEINLINE FResultType operator()(Ts... Args) && requires (CSameAs<CVRef, int&&>) { return CallImpl(Forward<Ts>(Args)...); }
FORCEINLINE FResultType operator()(Ts... Args) const requires (CSameAs<CVRef, const int >) { return CallImpl(Forward<Ts>(Args)...); }
FORCEINLINE FResultType operator()(Ts... Args) const& requires (CSameAs<CVRef, const int& >) { return CallImpl(Forward<Ts>(Args)...); }
FORCEINLINE FResultType operator()(Ts... Args) const&& requires (CSameAs<CVRef, const int&&>) { return CallImpl(Forward<Ts>(Args)...); }
/** @return false if instance stores a callable function target, true otherwise. */
NODISCARD FORCEINLINE constexpr bool operator==(nullptr_t) const& requires (!bIsRef) { return !IsValid(); }
@ -487,14 +487,14 @@ public:
private:
using CallableType = ResultType(*)(uintptr, Ts&&...);
using FCallableType = FResultType(*)(uintptr, Ts&&...);
TFunctionStorage<bIsRef, bIsUnique> Storage;
FORCEINLINE ResultType CallImpl(Ts&&... Args) const
FORCEINLINE FResultType CallImpl(Ts&&... Args) const
{
checkf(Storage.IsValid(), TEXT("Attempting to call an unbound TFunction!"));
CallableType Callable = reinterpret_cast<CallableType>(Storage.GetCallable());
FCallableType Callable = reinterpret_cast<FCallableType>(Storage.GetCallable());
return Callable(Storage.GetValuePtr(), Forward<Ts>(Args)...);
}
@ -510,26 +510,26 @@ protected:
template <typename T, typename... Us>
FORCEINLINE constexpr TDecay<T>& Emplace(Us&&... Args)
{
using DecayedType = TDecay<T>;
using FDecayedType = TDecay<T>;
// This add a l-value reference to a non-reference type, while preserving the r-value reference.
using ObjectType = TCopyCVRef<CVRef, DecayedType>;
using InvokeType = TConditional<CReference<ObjectType>, ObjectType, ObjectType&>;
using FObjectType = TCopyCVRef<CVRef, FDecayedType>;
using FInvokeType = TConditional<CReference<FObjectType>, FObjectType, FObjectType&>;
CallableType Callable = [](uintptr ObjectPtr, Ts&&... Args) -> ResultType
FCallableType Callable = [](uintptr ObjectPtr, Ts&&... Args) -> FResultType
{
return InvokeResult<ResultType>(
static_cast<InvokeType>(*reinterpret_cast<DecayedType*>(ObjectPtr)),
return InvokeResult<FResultType>(
static_cast<FInvokeType>(*reinterpret_cast<FDecayedType*>(ObjectPtr)),
Forward<Ts>(Args)...
);
};
Storage.template Emplace<DecayedType>(
Storage.template Emplace<FDecayedType>(
reinterpret_cast<uintptr>(Callable),
Forward<Us>(Args)...
);
return *reinterpret_cast<DecayedType*>(Storage.GetValuePtr());
return *reinterpret_cast<FDecayedType*>(Storage.GetValuePtr());
}
friend FORCEINLINE constexpr void Swap(TFunctionImpl& A, TFunctionImpl& B) requires (!bIsRef) { Swap(A.Storage, B.Storage); }
@ -552,15 +552,15 @@ NAMESPACE_PRIVATE_END
template <CFunction F>
class TFunctionRef final
: public NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::CVRef,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FFn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FCVRef,
true>
{
private:
using Impl = NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::CVRef,
using FImpl = NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FFn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FCVRef,
true>;
public:
@ -585,7 +585,7 @@ public:
FORCEINLINE constexpr TFunctionRef(T&& InValue)
{
checkf(NAMESPACE_PRIVATE::FunctionIsBound(InValue), TEXT("Cannot bind a null/unbound callable to a TFunctionRef"));
Impl::template Emplace<T>(Forward<T>(InValue));
FImpl::template Emplace<T>(Forward<T>(InValue));
}
template <typename T>
@ -602,21 +602,21 @@ public:
template <CFunction F>
class TFunction final
: public NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::CVRef,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FFn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FCVRef,
false, false>
{
private:
using Impl = NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::CVRef,
using FImpl = NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FFn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FCVRef,
false, false>;
public:
/** Default constructor. */
FORCEINLINE constexpr TFunction(nullptr_t = nullptr) { Impl::Invalidate(); }
FORCEINLINE constexpr TFunction(nullptr_t = nullptr) { FImpl::Invalidate(); }
FORCEINLINE TFunction(const TFunction&) = default;
FORCEINLINE TFunction(TFunction&&) = default;
@ -634,8 +634,8 @@ public:
&& NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value)
FORCEINLINE TFunction(T&& InValue)
{
if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Impl::Invalidate();
else Impl::template Emplace<T>(Forward<T>(InValue));
if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) FImpl::Invalidate();
else FImpl::template Emplace<T>(Forward<T>(InValue));
}
/**
@ -647,7 +647,7 @@ public:
&& CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE explicit TFunction(TInPlaceType<T>, Ts&&... Args)
{
Impl::template Emplace<T>(Forward<Ts>(Args)...);
FImpl::template Emplace<T>(Forward<Ts>(Args)...);
}
/**
@ -659,7 +659,7 @@ public:
&& CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE explicit TFunction(TInPlaceType<T>, initializer_list<U> IL, Ts&&... Args)
{
Impl::template Emplace<T>(IL, Forward<Ts>(Args)...);
FImpl::template Emplace<T>(IL, Forward<Ts>(Args)...);
}
/** Removes any bound callable from the TFunction, restoring it to the default empty state. */
@ -692,8 +692,8 @@ public:
&& CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE TDecay<T>& Emplace(Ts&&... Args)
{
Impl::Destroy();
return Impl::template Emplace<T>(Forward<Ts>(Args)...);
FImpl::Destroy();
return FImpl::template Emplace<T>(Forward<Ts>(Args)...);
}
/**
@ -710,15 +710,15 @@ public:
&& CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE TDecay<T>& Emplace(initializer_list<U> IL, Ts&&... Args)
{
Impl::Destroy();
return Impl::template Emplace<T>(IL, Forward<Ts>(Args)...);
FImpl::Destroy();
return FImpl::template Emplace<T>(IL, Forward<Ts>(Args)...);
}
/** Removes any bound callable from the TFunction, restoring it to the default empty state. */
FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
FORCEINLINE constexpr void Reset() { FImpl::Destroy(); FImpl::Invalidate(); }
/** Overloads the Swap algorithm for TFunction. */
friend FORCEINLINE constexpr void Swap(TFunction& A, TFunction& B) { Swap(static_cast<Impl&>(A), static_cast<Impl&>(B)); }
friend FORCEINLINE constexpr void Swap(TFunction& A, TFunction& B) { Swap(static_cast<FImpl&>(A), static_cast<FImpl&>(B)); }
};
@ -731,21 +731,21 @@ public:
template <CFunction F>
class TUniqueFunction final
: public NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::CVRef,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FFn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FCVRef,
false, true>
{
private:
using Impl = NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::CVRef,
using FImpl = NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FFn,
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::FCVRef,
false, true>;
public:
/** Default constructor. */
FORCEINLINE constexpr TUniqueFunction(nullptr_t = nullptr) { Impl::Invalidate(); }
FORCEINLINE constexpr TUniqueFunction(nullptr_t = nullptr) { FImpl::Invalidate(); }
FORCEINLINE TUniqueFunction(const TUniqueFunction&) = delete;
FORCEINLINE TUniqueFunction(TUniqueFunction&&) = default;
@ -788,8 +788,8 @@ public:
&& NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value)
FORCEINLINE TUniqueFunction(T&& InValue)
{
if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) Impl::Invalidate();
else Impl::template Emplace<T>(Forward<T>(InValue));
if (!NAMESPACE_PRIVATE::FunctionIsBound(InValue)) FImpl::Invalidate();
else FImpl::template Emplace<T>(Forward<T>(InValue));
}
/**
@ -800,7 +800,7 @@ public:
&& CConstructibleFrom<TDecay<T>, Ts...> && CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE explicit TUniqueFunction(TInPlaceType<T>, Ts&&... Args)
{
Impl::template Emplace<T>(Forward<Ts>(Args)...);
FImpl::template Emplace<T>(Forward<Ts>(Args)...);
}
/**
@ -811,11 +811,11 @@ public:
&& CConstructibleFrom<TDecay<T>, initializer_list<U>, Ts...> && CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE explicit TUniqueFunction(TInPlaceType<T>, initializer_list<U> IL, Ts&&... Args)
{
Impl::template Emplace<T>(IL, Forward<Ts>(Args)...);
FImpl::template Emplace<T>(IL, Forward<Ts>(Args)...);
}
/** Removes any bound callable from the TUniqueFunction, restoring it to the default empty state. */
FORCEINLINE constexpr TUniqueFunction& operator=(nullptr_t) { Impl::Destroy(); Impl::Invalidate(); return *this; }
FORCEINLINE constexpr TUniqueFunction& operator=(nullptr_t) { FImpl::Destroy(); FImpl::Invalidate(); return *this; }
template <typename T> requires (NAMESPACE_PRIVATE::TIsInvocableSignature<F, TDecay<T>>::Value
&& !CTFunctionRef<TDecay<T>> && !CTFunction<TDecay<T>> && !CTUniqueFunction<TDecay<T>>
@ -841,9 +841,9 @@ public:
&& CConstructibleFrom<TDecay<T>, Ts...> && CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE TDecay<T>& Emplace(Ts&&... Args)
{
Impl::Destroy();
using DecayedType = TDecay<T>;
return Impl::template Emplace<T>(Forward<Ts>(Args)...);
FImpl::Destroy();
return FImpl::template Emplace<T>(Forward<Ts>(Args)...);
}
/**
@ -859,16 +859,16 @@ public:
&& CConstructibleFrom<TDecay<T>, initializer_list<U>, Ts...> && CMoveConstructible<TDecay<T>> && CDestructible<TDecay<T>>)
FORCEINLINE TDecay<T>& Emplace(initializer_list<U> IL, Ts&&... Args)
{
Impl::Destroy();
using DecayedType = TDecay<T>;
return Impl::template Emplace<T>(IL, Forward<Ts>(Args)...);
FImpl::Destroy();
return FImpl::template Emplace<T>(IL, Forward<Ts>(Args)...);
}
/** Removes any bound callable from the TUniqueFunction, restoring it to the default empty state. */
FORCEINLINE constexpr void Reset() { Impl::Destroy(); Impl::Invalidate(); }
FORCEINLINE constexpr void Reset() { FImpl::Destroy(); FImpl::Invalidate(); }
/** Overloads the Swap algorithm for TUniqueFunction. */
friend FORCEINLINE constexpr void Swap(TUniqueFunction& A, TUniqueFunction& B) { Swap(static_cast<Impl&>(A), static_cast<Impl&>(B)); }
friend FORCEINLINE constexpr void Swap(TUniqueFunction& A, TUniqueFunction& B) { Swap(static_cast<FImpl&>(A), static_cast<FImpl&>(B)); }
};

View File

@ -10,7 +10,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
NAMESPACE_PRIVATE_BEGIN
struct InvokeFunction
struct FInvokeFunction
{
template <typename F, typename... Ts>
static auto Invoke(F&& Object, Ts&&... Args)
@ -20,7 +20,7 @@ struct InvokeFunction
}
};
struct InvokeMemberFunction
struct FInvokeMemberFunction
{
template <typename F, typename ObjectType, typename... Ts>
static auto Invoke(F&& Func, ObjectType&& Object, Ts&&... Args)
@ -37,7 +37,7 @@ struct InvokeMemberFunction
}
};
struct InvokeMemberObject
struct FInvokeMemberObject
{
template <typename F, typename ObjectType>
static auto Invoke(F&& Func, ObjectType&& Object)
@ -59,34 +59,34 @@ template <typename F,
typename Decayed = TDecay<F>,
bool IsMemberFunction = CMemberFunctionPointer<Decayed>,
bool IsMemberObject = CMemberObjectPointer<Decayed>>
struct InvokeMember;
struct FInvokeMember;
template <typename F, typename T, typename Decayed>
struct InvokeMember<F, T, Decayed, true, false> : InvokeMemberFunction { };
struct FInvokeMember<F, T, Decayed, true, false> : FInvokeMemberFunction { };
template <typename F, typename T, typename Decayed>
struct InvokeMember<F, T, Decayed, false, true> : InvokeMemberObject { };
struct FInvokeMember<F, T, Decayed, false, true> : FInvokeMemberObject { };
template <typename F, typename T, typename Decayed>
struct InvokeMember<F, T, Decayed, false, false> : InvokeFunction { };
struct FInvokeMember<F, T, Decayed, false, false> : FInvokeFunction { };
template <typename F, typename... Ts>
struct InvokeImpl;
struct FInvokeImpl;
template <typename F>
struct InvokeImpl<F> : InvokeFunction { };
struct FInvokeImpl<F> : FInvokeFunction { };
template <typename F, typename T, typename... Ts>
struct InvokeImpl<F, T, Ts...> : InvokeMember<F, T> { };
struct FInvokeImpl<F, T, Ts...> : FInvokeMember<F, T> { };
NAMESPACE_PRIVATE_END
/** Invoke the Callable object f with the parameters args. */
template <typename F, typename... Ts> requires (CInvocable<F, Ts...>)
FORCEINLINE constexpr auto Invoke(F&& Func, Ts&&... Args)
-> decltype(NAMESPACE_PRIVATE::InvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...))
-> decltype(NAMESPACE_PRIVATE::FInvokeImpl<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::FInvokeImpl<F, Ts...>::Invoke(Forward<F>(Func), Forward<Ts>(Args)...);
}
/** Invoke the Callable object f with the parameters args. */

View File

@ -12,7 +12,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, T... Ints>
struct TIntegerSequence
{
using ValueType = T;
using FValueType = T;
FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); }
FORCEINLINE static constexpr const T* GetData() { return NAMESPACE_REDCRAFT::GetData({ Ints... }); }
};
@ -24,7 +24,7 @@ NAMESPACE_PRIVATE_BEGIN
template <unsigned N, typename T>
struct TMakeIntegerSequenceImpl
{
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
using FType = typename __make_integer_seq<TIntegerSequence, T, N>;
};
#elif __has_builtin(__make_integer_seq)
@ -32,7 +32,7 @@ struct TMakeIntegerSequenceImpl
template <unsigned N, typename T>
struct TMakeIntegerSequenceImpl
{
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
using FType = typename __make_integer_seq<TIntegerSequence, T, N>;
};
#else
@ -40,13 +40,13 @@ struct TMakeIntegerSequenceImpl
template <unsigned N, typename T, T... Ints>
struct TMakeIntegerSequenceImpl
{
using Type = typename TMakeIntegerSequenceImpl<N - 1, T, T(N - 1), Ints...>::Type;
using FType = typename TMakeIntegerSequenceImpl<N - 1, T, T(N - 1), Ints...>::FType;
};
template <typename T, T... Ints>
struct TMakeIntegerSequenceImpl<0, T, Ints...>
{
using Type = TIntegerSequence<T, Ints...>;
using FType = TIntegerSequence<T, Ints...>;
};
#endif
@ -57,7 +57,7 @@ template <size_t... Ints>
using TIndexSequence = TIntegerSequence<size_t, Ints...>;
template <typename T, T N>
using TMakeIntegerSequence = typename NAMESPACE_PRIVATE::TMakeIntegerSequenceImpl<N, T>::Type;
using TMakeIntegerSequence = typename NAMESPACE_PRIVATE::TMakeIntegerSequenceImpl<N, T>::FType;
template <size_t N>
using TMakeIndexSequence = TMakeIntegerSequence<size_t, N>;
@ -103,7 +103,7 @@ struct TFrontImpl;
template <typename T, typename... Ts>
struct TFrontImpl<TTypeSequence<T, Ts...>>
{
using Type = T;
using FType = T;
};
template <typename TSequence>
@ -112,7 +112,7 @@ struct TPopImpl;
template <typename T, typename... Ts>
struct TPopImpl<TTypeSequence<T, Ts...>>
{
using Type = TTypeSequence<Ts...>;
using FType = TTypeSequence<Ts...>;
};
template <typename T, typename TSequence>
@ -121,19 +121,19 @@ struct TPushImpl;
template <typename T, typename... Ts>
struct TPushImpl<T, TTypeSequence<Ts...>>
{
using Type = TTypeSequence<T, Ts...>;
using FType = TTypeSequence<T, Ts...>;
};
NAMESPACE_PRIVATE_END
template <CTTypeSequence TSequence>
using TFront = typename NAMESPACE_PRIVATE::TFrontImpl<TSequence>::Type;
using TFront = typename NAMESPACE_PRIVATE::TFrontImpl<TSequence>::FType;
template <CTTypeSequence TSequence>
using TPop = typename NAMESPACE_PRIVATE::TPopImpl<TSequence>::Type;
using TPop = typename NAMESPACE_PRIVATE::TPopImpl<TSequence>::FType;
template <typename T, typename TSequence>
using TPush = typename NAMESPACE_PRIVATE::TPushImpl<T, TSequence>::Type;
using TPush = typename NAMESPACE_PRIVATE::TPushImpl<T, TSequence>::FType;
NAMESPACE_PRIVATE_BEGIN
@ -194,19 +194,19 @@ struct TIndexAssert
template <size_t I, typename TSequence>
struct TTypeImpl
{
using Type = typename TTypeImpl<I - 1, TPop<TSequence>>::Type;
using FType = typename TTypeImpl<I - 1, TPop<TSequence>>::FType;
};
template <typename TSequence>
struct TTypeImpl<0, TSequence>
{
using Type = TFront<TSequence>;
using FType = TFront<TSequence>;
};
template <typename TSequence>
struct TTypeImpl<INDEX_NONE, TSequence>
{
using Type = void;
using FType = void;
};
template <size_t I, typename TSequence>
@ -214,7 +214,7 @@ struct TTypeAssert
{
static_assert(I < TSizeImpl<TSequence>::Value, "I is invalid index in type sequence");
static constexpr size_t SafeIndex = I < TSizeImpl<TSequence>::Value ? I : INDEX_NONE;
using Type = TCopyCV<TSequence, typename TTypeImpl<SafeIndex, TSequence>::Type>;
using FType = TCopyCV<TSequence, typename TTypeImpl<SafeIndex, TSequence>::FType>;
};
NAMESPACE_PRIVATE_END
@ -226,29 +226,29 @@ template <typename T, CTTypeSequence TSequence>
inline constexpr size_t TIndex = NAMESPACE_PRIVATE::TIndexAssert<T, TSequence>::Value;
template <size_t I, CTTypeSequence TSequence>
using TType = typename NAMESPACE_PRIVATE::TTypeAssert<I, TSequence>::Type;
using TType = typename NAMESPACE_PRIVATE::TTypeAssert<I, TSequence>::FType;
NAMESPACE_PRIVATE_BEGIN
template <typename TSequence>
struct TUniqueTypeSequenceImpl
{
using FrontType = TFront<TSequence>;
using NextSequence = TPop<TSequence>;
using NextUniqueSequence = typename TUniqueTypeSequenceImpl<NextSequence>::Type;
using Type = TConditional<!CExistentType<FrontType, NextSequence>, TPush<FrontType, NextUniqueSequence>, NextUniqueSequence>;
using FFrontType = TFront<TSequence>;
using FNextSequence = TPop<TSequence>;
using FNextUniqueSequence = typename TUniqueTypeSequenceImpl<FNextSequence>::FType;
using FType = TConditional<!CExistentType<FFrontType, FNextSequence>, TPush<FFrontType, FNextUniqueSequence>, FNextUniqueSequence>;
};
template <>
struct TUniqueTypeSequenceImpl<TTypeSequence<>>
{
using Type = TTypeSequence<>;
using FType = TTypeSequence<>;
};
NAMESPACE_PRIVATE_END
template <CTTypeSequence TSequence>
using TUniqueTypeSequence = typename NAMESPACE_PRIVATE::TUniqueTypeSequenceImpl<TSequence>::Type;
using TUniqueTypeSequence = typename NAMESPACE_PRIVATE::TUniqueTypeSequenceImpl<TSequence>::FType;
NAMESPACE_PRIVATE_BEGIN

View File

@ -45,9 +45,9 @@ class TOptional<T, false> final
{
public:
using ValueType = T;
using FValueType = T;
static_assert(!CReference<ValueType>);
static_assert(!CReference<FValueType>);
/** Constructs an object that does not contain a value. */
FORCEINLINE constexpr TOptional() : bIsValid(false) { }
@ -67,7 +67,7 @@ public:
FORCEINLINE constexpr explicit TOptional(FInPlace, Ts&&... Args)
: bIsValid(true)
{
new (&Value) ValueType(Forward<Ts>(Args)...);
new (&Value) FValueType(Forward<Ts>(Args)...);
}
/** Constructs an object with initial content an object, direct-non-list-initialized from IL, Forward<Ts>(Args).... */
@ -75,7 +75,7 @@ public:
FORCEINLINE constexpr explicit TOptional(FInPlace, initializer_list<W> IL, Ts&&... Args)
: bIsValid(true)
{
new (&Value) ValueType(IL, Forward<Ts>(Args)...);
new (&Value) FValueType(IL, Forward<Ts>(Args)...);
}
/** Copies content of other into a new instance. */
@ -85,7 +85,7 @@ public:
FORCEINLINE constexpr TOptional(const TOptional& InValue) requires (CCopyConstructible<T> && !CTriviallyCopyConstructible<T>)
: bIsValid(InValue.IsValid())
{
if (InValue.IsValid()) new (&Value) ValueType(InValue.GetValue());
if (InValue.IsValid()) new (&Value) FValueType(InValue.GetValue());
}
/** Moves content of other into a new instance. */
@ -95,7 +95,7 @@ public:
FORCEINLINE constexpr TOptional(TOptional&& InValue) requires (CMoveConstructible<T> && !CTriviallyMoveConstructible<T>)
: bIsValid(InValue.IsValid())
{
if (InValue.IsValid()) new (&Value) ValueType(MoveTemp(InValue.GetValue()));
if (InValue.IsValid()) new (&Value) FValueType(MoveTemp(InValue.GetValue()));
}
/** Converting copy constructor. */
@ -103,7 +103,7 @@ public:
FORCEINLINE constexpr explicit (!CConvertibleTo<const U&, T>) TOptional(const TOptional<U>& InValue)
: bIsValid(InValue.IsValid())
{
if (InValue.IsValid()) new (&Value) ValueType(InValue.GetValue());
if (InValue.IsValid()) new (&Value) FValueType(InValue.GetValue());
}
/** Converting move constructor. */
@ -111,7 +111,7 @@ public:
FORCEINLINE constexpr explicit (!CConvertibleTo<U&&, T>) TOptional(TOptional<U>&& InValue)
: bIsValid(InValue.IsValid())
{
if (InValue.IsValid()) new (&Value) ValueType(MoveTemp(InValue.GetValue()));
if (InValue.IsValid()) new (&Value) FValueType(MoveTemp(InValue.GetValue()));
}
/** Destroys the contained object, if any, as if by a call to Reset(). */
@ -141,7 +141,7 @@ public:
if (IsValid()) GetValue() = InValue.GetValue();
else
{
new (&Value) ValueType(InValue.GetValue());
new (&Value) FValueType(InValue.GetValue());
bIsValid = true;
}
@ -166,7 +166,7 @@ public:
if (IsValid()) GetValue() = MoveTemp(InValue.GetValue());
else
{
new (&Value) ValueType(MoveTemp(InValue.GetValue()));
new (&Value) FValueType(MoveTemp(InValue.GetValue()));
bIsValid = true;
}
@ -187,7 +187,7 @@ public:
if (IsValid()) GetValue() = InValue.GetValue();
else
{
new (&Value) ValueType(InValue.GetValue());
new (&Value) FValueType(InValue.GetValue());
bIsValid = true;
}
@ -208,7 +208,7 @@ public:
if (IsValid()) GetValue() = MoveTemp(InValue.GetValue());
else
{
new (&Value) ValueType(MoveTemp(InValue.GetValue()));
new (&Value) FValueType(MoveTemp(InValue.GetValue()));
bIsValid = true;
}
@ -222,7 +222,7 @@ public:
if (IsValid()) GetValue() = Forward<U>(InValue);
else
{
new (&Value) ValueType(Forward<U>(InValue));
new (&Value) FValueType(Forward<U>(InValue));
bIsValid = true;
}
@ -278,7 +278,7 @@ public:
{
Reset();
T* Result = new (&Value) ValueType(Forward<Ts>(Args)...);
T* Result = new (&Value) FValueType(Forward<Ts>(Args)...);
bIsValid = true;
return *Result;
@ -298,7 +298,7 @@ public:
{
Reset();
T* Result = new (&Value) ValueType(IL, Forward<Ts>(Args)...);
T* Result = new (&Value) FValueType(IL, Forward<Ts>(Args)...);
bIsValid = true;
return *Result;
@ -335,7 +335,7 @@ public:
{
bIsValid = false;
reinterpret_cast<T*>(&Value)->~ValueType();
reinterpret_cast<T*>(&Value)->~FValueType();
}
}
@ -380,9 +380,9 @@ class TOptional<T, true> final
{
public:
using ValueType = TRemoveReference<T>;
using FValueType = TRemoveReference<T>;
static_assert(!CReference<ValueType>);
static_assert(!CReference<FValueType>);
/** Constructs an object that does not contain a reference. */
FORCEINLINE constexpr TOptional() : Ptr(nullptr) { }
@ -408,13 +408,13 @@ public:
{ }
/** Converting constructor. */
template <typename U> requires (!CConst<ValueType> && CConstructibleFrom<T, U&> && NAMESPACE_PRIVATE::CTOptionalAllowUnwrappable<U, T>)
template <typename U> requires (!CConst<FValueType> && CConstructibleFrom<T, U&> && NAMESPACE_PRIVATE::CTOptionalAllowUnwrappable<U, T>)
FORCEINLINE constexpr explicit (!CConvertibleTo<U&, T>) TOptional(TOptional<U, false>& InValue)
: Ptr(InValue.IsValid() ? AddressOf(static_cast<T>(InValue.GetValue())) : nullptr)
{ }
/** Converting constructor. */
template <typename U> requires (CConst<ValueType> && CConstructibleFrom<T, const U&> && NAMESPACE_PRIVATE::CTOptionalAllowUnwrappable<U, T>)
template <typename U> requires (CConst<FValueType> && CConstructibleFrom<T, const U&> && NAMESPACE_PRIVATE::CTOptionalAllowUnwrappable<U, T>)
FORCEINLINE constexpr explicit (!CConvertibleTo<const U&, T>) TOptional(const TOptional<U, false>& InValue)
: Ptr(InValue.IsValid() ? AddressOf(static_cast<T>(InValue.GetValue())) : nullptr)
{ }
@ -492,7 +492,7 @@ public:
private:
ValueType* Ptr;
FValueType* Ptr;
};

View File

@ -24,7 +24,7 @@ template <typename T>
concept CTPropagateConst = NAMESPACE_PRIVATE::TIsTPropagateConst<TRemoveCV<T>>::Value;
/**
* TPropagateConst is a const-propagating wrapper for pointers and pointer-like objects.
* TPropagateConst is a const-propagating wrapper for pointers and pointer-like objects.
* It treats the wrapped pointer as a pointer to const when accessed through a const access path, hence the name.
*/
template <typename T> requires (TPointerTraits<T>::bIsPointer)
@ -32,7 +32,7 @@ class TPropagateConst final
{
public:
using ElementType = TPointerTraits<T>::ElementType;
using FElementType = TPointerTraits<T>::FElementType;
/** Constructs an TPropagateConst, default-initializing underlying pointer. */
FORCEINLINE constexpr TPropagateConst() = default;
@ -105,26 +105,26 @@ public:
NODISCARD FORCEINLINE constexpr decltype(auto) operator<=>(U InPtr) const& { return SynthThreeWayCompare(Ptr, InPtr); }
/** @return The pointer to the object pointed to by the wrapped pointer. */
NODISCARD FORCEINLINE constexpr ElementType* Get() { return TPointerTraits<T>::ToAddress(Ptr); }
NODISCARD FORCEINLINE constexpr const ElementType* Get() const { return TPointerTraits<T>::ToAddress(Ptr); }
NODISCARD FORCEINLINE constexpr FElementType* Get() { return TPointerTraits<T>::ToAddress(Ptr); }
NODISCARD FORCEINLINE constexpr const FElementType* Get() const { return TPointerTraits<T>::ToAddress(Ptr); }
/** @return true if *this owns an object, false otherwise. */
NODISCARD FORCEINLINE constexpr bool IsValid() const { return Get() != nullptr; }
NODISCARD FORCEINLINE constexpr explicit operator bool() const { return Get() != nullptr; }
/** @return The a reference or pointer to the object owned by *this, i.e. Get(). */
NODISCARD FORCEINLINE constexpr ElementType& operator*() { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return *Get(); }
NODISCARD FORCEINLINE constexpr const ElementType& operator*() const { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return *Get(); }
NODISCARD FORCEINLINE constexpr ElementType* operator->() { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return Get(); }
NODISCARD FORCEINLINE constexpr const ElementType* operator->() const { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return Get(); }
NODISCARD FORCEINLINE constexpr FElementType& operator*() { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return *Get(); }
NODISCARD FORCEINLINE constexpr const FElementType& operator*() const { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return *Get(); }
NODISCARD FORCEINLINE constexpr FElementType* operator->() { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return Get(); }
NODISCARD FORCEINLINE constexpr const FElementType* operator->() const { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return Get(); }
/** @return The element at index, i.e. Get()[Index]. */
NODISCARD FORCEINLINE constexpr T& operator[](size_t Index) { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return Get()[Index]; }
NODISCARD FORCEINLINE constexpr const T& operator[](size_t Index) const { checkf(IsValid(), TEXT("Read access violation. Please check IsValid().")); return Get()[Index]; }
/** @return The pointer to the object pointed to by the wrapped pointer-like object. */
NODISCARD FORCEINLINE constexpr operator ElementType*() requires (CConvertibleTo<T, ElementType*>) { return Ptr; }
NODISCARD FORCEINLINE constexpr operator const ElementType*() const requires (CConvertibleTo<T, ElementType*>) { return Ptr; }
NODISCARD FORCEINLINE constexpr operator FElementType*() requires (CConvertibleTo<T, FElementType*>) { return Ptr; }
NODISCARD FORCEINLINE constexpr operator const FElementType*() const requires (CConvertibleTo<T, FElementType*>) { return Ptr; }
/** @return The reference to the pointer-like object stored. */
NODISCARD FORCEINLINE constexpr T& GetUnderlying() { return Ptr; }

View File

@ -22,7 +22,7 @@ class TReferenceWrapper final
{
public:
using Type = ReferencedType;
using FType = ReferencedType;
/** Constructs a new reference wrapper. */
template <typename T = ReferencedType&> requires (CConvertibleTo<T&&, ReferencedType&> && !CSameAs<TReferenceWrapper, TRemoveCVRef<T>>)
@ -111,10 +111,10 @@ NAMESPACE_PRIVATE_BEGIN
template <typename T> struct TIsTReferenceWrapperImpl : FFalse { };
template <typename T> struct TIsTReferenceWrapperImpl<TReferenceWrapper<T>> : FTrue { };
template <typename T> struct TUnwrapReferenceImpl { using Type = T; };
template <typename T> struct TUnwrapReferenceImpl<TReferenceWrapper<T>> { using Type = T&; };
template <typename T> struct TUnwrapReferenceImpl { using FType = T; };
template <typename T> struct TUnwrapReferenceImpl<TReferenceWrapper<T>> { using FType = T&; };
template <typename T> struct TUnwrapRefDecayImpl { using Type = typename TUnwrapReferenceImpl<TDecay<T>>::Type; };
template <typename T> struct TUnwrapRefDecayImpl { using FType = typename TUnwrapReferenceImpl<TDecay<T>>::FType; };
NAMESPACE_PRIVATE_END
@ -122,10 +122,10 @@ template <typename T>
concept CTReferenceWrapper = NAMESPACE_PRIVATE::TIsTReferenceWrapperImpl<TRemoveCV<T>>::Value;
template <typename T>
using TUnwrapReference = typename NAMESPACE_PRIVATE::TUnwrapReferenceImpl<T>::Type;
using TUnwrapReference = typename NAMESPACE_PRIVATE::TUnwrapReferenceImpl<T>::FType;
template <typename T>
using TUnwrapRefDecay = typename NAMESPACE_PRIVATE::TUnwrapRefDecayImpl<T>::Type;
using TUnwrapRefDecay = typename NAMESPACE_PRIVATE::TUnwrapRefDecayImpl<T>::FType;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)

View File

@ -49,7 +49,7 @@ struct TTupleElementImpl;
template <size_t I, typename... Ts>
struct TTupleElementImpl<I, TTuple<Ts...>>
{
using Type = Meta::TType<I, TTypeSequence<Ts...>>;
using FType = Meta::TType<I, TTypeSequence<Ts...>>;
};
template <bool bTrue, typename... Ts>
@ -77,12 +77,12 @@ struct TTupleBasicElement
{
private:
using ValueType = T;
ValueType Value;
using FValueType = T;
FValueType Value;
public:
template <typename Type>
template <typename Type> requires (CConstructibleFrom<T, Type&&>)
FORCEINLINE constexpr TTupleBasicElement(Type&& Arg)
: Value(Forward<Type>(Arg))
{ }
@ -110,10 +110,10 @@ public:
template <typename T> \
struct TTupleBasicElement<T, Index> \
{ \
using Name##Type = T; \
Name##Type Name; \
using F##Name##Type = T; \
F##Name##Type Name; \
\
template <typename Type> \
template <typename Type> requires (CConstructibleFrom<T, F##Name##Type&&>) \
FORCEINLINE constexpr TTupleBasicElement(Type&& Arg) \
: Name(Forward<Type>(Arg)) \
{ } \
@ -315,15 +315,15 @@ template <typename T, CTTuple U>
inline constexpr size_t TTupleIndex = NAMESPACE_PRIVATE::TTupleIndexImpl<T, TRemoveCV<U>>::Value;
template <size_t I, CTTuple U>
using TTupleElement = TCopyCV<U, typename NAMESPACE_PRIVATE::TTupleElementImpl<I, TRemoveCV<U>>::Type>;
using TTupleElement = TCopyCV<U, typename NAMESPACE_PRIVATE::TTupleElementImpl<I, TRemoveCV<U>>::FType>;
template <typename... Ts>
class TTuple final : public NAMESPACE_PRIVATE::TTupleImpl<TIndexSequenceFor<Ts...>, Ts...>
{
private:
using Super = NAMESPACE_PRIVATE::TTupleImpl<TIndexSequenceFor<Ts...>, Ts...>;
using Helper = NAMESPACE_PRIVATE::TTupleHelper<TIndexSequenceFor<Ts...>>;
using FSuper = NAMESPACE_PRIVATE::TTupleImpl<TIndexSequenceFor<Ts...>, Ts...>;
using FHelper = NAMESPACE_PRIVATE::TTupleHelper<TIndexSequenceFor<Ts...>>;
public:
@ -334,7 +334,7 @@ public:
template <typename... Us> requires (sizeof...(Ts) >= 1 && sizeof...(Us) == sizeof...(Ts))
&& (true && ... && CConstructibleFrom<Ts, Us&&>)
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<Us&&, Ts>)) TTuple(Us&&... Args)
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<Us>(Args)...)
: FSuper(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<Us>(Args)...)
{ }
/** Converting copy constructor. Initializes each element of the tuple with the corresponding element of other. */
@ -342,7 +342,7 @@ public:
&& (true && ... && CConstructibleFrom<Ts, const Us&>)
&& NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Ts) != 1, Ts..., Us...>::Value)
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<Us&&, Ts>)) TTuple(const TTuple<Us...>& InValue)
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
: FSuper(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
{ }
/** Converting move constructor. Initializes each element of the tuple with the corresponding element of other. */
@ -350,7 +350,7 @@ public:
&& (true && ... && CConstructibleFrom<Ts, Us&&>)
&& NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Ts) != 1, Ts..., Us...>::Value)
FORCEINLINE constexpr explicit (!(true && ... && CConvertibleTo<Us&&, Ts>)) TTuple(TTuple<Us...>&& InValue)
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
: FSuper(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
{ }
/** Copies/moves content of other into a new instance. */
@ -362,7 +362,7 @@ public:
&& (true && ... && CAssignableFrom<Ts&, const Us&>))
FORCEINLINE constexpr TTuple& operator=(const TTuple<Us...>& InValue)
{
Helper::Assign(*this, InValue);
FHelper::Assign(*this, InValue);
return *this;
}
@ -371,7 +371,7 @@ public:
&& (true && ... && CAssignableFrom<Ts&, Us&&>))
FORCEINLINE constexpr TTuple& operator=(TTuple<Us...>&& InValue)
{
Helper::Assign(*this, MoveTemp(InValue));
FHelper::Assign(*this, MoveTemp(InValue));
return *this;
}
@ -396,8 +396,8 @@ public:
template <typename... Us> requires (sizeof...(Ts) == sizeof...(Us) && NAMESPACE_PRIVATE::CTTupleSynthThreeWayComparable<TTypeSequence<Ts...>, TTypeSequence<Us...>>)
NODISCARD friend FORCEINLINE constexpr TCommonComparisonCategory<TSynthThreeWayResult<Ts, Us>...> operator<=>(const TTuple& LHS, const TTuple<Us...>& RHS)
{
using R = TCommonComparisonCategory<TSynthThreeWayResult<Ts, Us>...>;
return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(Ts)>>::Do(LHS, RHS);
using FResult = TCommonComparisonCategory<TSynthThreeWayResult<Ts, Us>...>;
return NAMESPACE_PRIVATE::TTupleThreeWay<FResult, TMakeIndexSequence<sizeof...(Ts)>>::Do(LHS, RHS);
}
/** Extracts the Ith element from the tuple. I must be an integer value in [0, sizeof...(Ts)). */
@ -421,14 +421,14 @@ public:
template <typename T> NODISCARD FORCEINLINE constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple>>(); }
/** Invoke the callable object 'Func' with a tuple of arguments. */
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...>) 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...>) 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...>) 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...>) FORCEINLINE 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) 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) 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) 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) & { return FHelper::Apply(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const & { return FHelper::Apply(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile& { return FHelper::Apply(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile& { return FHelper::Apply(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) && { return FHelper::Apply(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const && { return FHelper::Apply(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile&& { return FHelper::Apply(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile&& { return FHelper::Apply(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
/** Visits each element in a tuple in parallel and applies it as arguments to the function. */
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) & { VisitTuple(Forward<F>(Func), static_cast< TTuple& >(*this)); }
@ -461,24 +461,24 @@ public:
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const volatile&& { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Index); }
/** Transform a tuple into another tuple using the given function. */
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD 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>>)) NODISCARD 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>>)) NODISCARD 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>>)) NODISCARD 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>>)) NODISCARD 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>>)) NODISCARD 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>>)) NODISCARD 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>>)) NODISCARD 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>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) & { return FHelper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const & { return FHelper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile& { return FHelper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile& { return FHelper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) && { return FHelper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const && { return FHelper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile&& { return FHelper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile&& { return FHelper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
/** Constructs an object of type T with a tuple as an argument. */
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() volatile& { return Helper::template Construct<T>(static_cast< volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile& { return Helper::template Construct<T>(static_cast<const volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() && { return Helper::template Construct<T>(static_cast< TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const && { return Helper::template Construct<T>(static_cast<const TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() volatile&& { return Helper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile&& { return Helper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() & { return FHelper::template Construct<T>(static_cast< TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const & { return FHelper::template Construct<T>(static_cast<const TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() volatile& { return FHelper::template Construct<T>(static_cast< volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile& { return FHelper::template Construct<T>(static_cast<const volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() && { return FHelper::template Construct<T>(static_cast< TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const && { return FHelper::template Construct<T>(static_cast<const TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() volatile&& { return FHelper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile&& { return FHelper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); }
/** @return The number of elements in the tuple. */
NODISCARD static FORCEINLINE constexpr size_t Num() { return sizeof...(Ts); }
@ -555,13 +555,13 @@ struct TTupleCatResultImpl;
template <typename... Ts, typename... TTupleTypes>
struct TTupleCatResultImpl<TTuple<Ts...>, TTupleTypes...>
{
using Type = typename TTupleCatResultImpl<TTupleTypes..., Ts...>::Type;
using FType = typename TTupleCatResultImpl<TTupleTypes..., Ts...>::FType;
};
template <typename... Ts>
struct TTupleCatResultImpl<FTupleEndFlag, Ts...>
{
using Type = TTuple<Ts...>;
using FType = TTuple<Ts...>;
};
template <typename R, typename Indices>
@ -571,14 +571,14 @@ template <typename... RTypes, size_t... Indices>
struct TTupleCatMake<TTuple<RTypes...>, TIndexSequence<Indices...>>
{
template <typename T, typename U>
struct ForwardType { using Type = TConditional<CRValueReference<T>, TRemoveReference<U>&&, U>; };
struct FForwardType { using FType = TConditional<CRValueReference<T>, TRemoveReference<U>&&, U>; };
template <typename TTupleType>
FORCEINLINE static constexpr TTuple<RTypes...> Do(TTupleType&& InValue)
{
return TTuple<RTypes...>
(
static_cast<typename ForwardType<RTypes, decltype(Forward<TTupleType>(InValue).template GetValue<Indices>())>::Type>
static_cast<typename FForwardType<RTypes, decltype(Forward<TTupleType>(InValue).template GetValue<Indices>())>::FType>
(
Forward<TTupleType>(InValue).template GetValue<Indices>()
)...
@ -642,15 +642,15 @@ struct TTupleVisitImpl<TIndexSequence<>>
NAMESPACE_PRIVATE_END
template <typename... TTupleTypes> requires (true && ... && CTTuple<TRemoveCVRef<TTupleTypes>>)
using TTupleCatResult = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<TRemoveReference<TTupleTypes>..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type;;
using TTupleCatResult = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<TRemoveReference<TTupleTypes>..., NAMESPACE_PRIVATE::FTupleEndFlag>::FType;
/** Creates a tuple by concatenating any number of tuples. */
template <typename... TTupleTypes> requires (true && ... && CTTuple<TRemoveCVRef<TTupleTypes>>)
FORCEINLINE constexpr decltype(auto) TupleCat(TTupleTypes&&... Args)
{
using R = TTupleCatResult<TTupleTypes...>;
if constexpr (sizeof...(Args) == 0) return R();
else return NAMESPACE_PRIVATE::TTupleCatImpl<R>::Do(Forward<TTupleTypes>(Args)...);
using FResult = TTupleCatResult<TTupleTypes...>;
if constexpr (sizeof...(Args) == 0) return FResult();
else return NAMESPACE_PRIVATE::TTupleCatImpl<FResult>::Do(Forward<TTupleTypes>(Args)...);
}
/**
@ -679,20 +679,22 @@ FORCEINLINE constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, Tup
template <typename... Ts, typename... Us> requires (requires { typename TTuple<TCommonType<Ts, Us>...>; })
struct TBasicCommonType<TTuple<Ts...>, TTuple<Us...>>
{
using Type = TTuple<TCommonType<Ts, Us>...>;
using FType = TTuple<TCommonType<Ts, Us>...>;
};
template <typename... Ts, typename... Us, template<typename> typename TQualifiers, template<typename> typename UQualifiers>
requires (requires { typename TTuple<TCommonReference<TQualifiers<Ts>, UQualifiers<Us>>...>; })
struct TBasicCommonReference<TTuple<Ts...>, TTuple<Us...>, TQualifiers, UQualifiers>
{
using Type = TTuple<TCommonReference<TQualifiers<Ts>, UQualifiers<Us>>...>;
using FType = TTuple<TCommonReference<TQualifiers<Ts>, UQualifiers<Us>>...>;
};
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END
// ReSharper disable CppInconsistentNaming
NAMESPACE_STD_BEGIN
// Support structure binding, should not be directly used.
@ -718,3 +720,5 @@ template <size_t Index, typename ...Ts> FORCEINLINE constexpr decltype(auto) get
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)
NAMESPACE_REDCRAFT_END
// ReSharper restore CppInconsistentNaming

View File

@ -24,8 +24,8 @@ void AsConst(const T&& Ref) = delete;
template <typename T>
FORCEINLINE constexpr TRemoveReference<T>&& MoveTemp(T&& Obj)
{
using CastType = TRemoveReference<T>;
return static_cast<CastType&&>(Obj);
using FCastType = TRemoveReference<T>;
return static_cast<FCastType&&>(Obj);
}
/** CopyTemp will enforce the creation of an rvalue which can bind to rvalue reference parameters. */

View File

@ -40,30 +40,30 @@ struct TVariantAlternativeImpl;
template <size_t I, typename... Ts>
struct TVariantAlternativeImpl<I, TVariant<Ts...>>
{
using Type = Meta::TType<I, TTypeSequence<Ts...>>;
using FType = Meta::TType<I, TTypeSequence<Ts...>>;
};
template <typename T, typename TSequence>
struct TVariantOverloadType
{
using FrontType = Meta::TFront<TSequence>;
using NextSequence = Meta::TPop<TSequence>;
using NextUniqueSequence = typename TVariantOverloadType<T, NextSequence>::Type;
using FFrontType = Meta::TFront<TSequence>;
using FNextSequence = Meta::TPop<TSequence>;
using FNextUniqueSequence = typename TVariantOverloadType<T, FNextSequence>::FType;
// T_i x[] = { Forward<T>(t) };
static constexpr bool bConditional = requires { DeclVal<void(FrontType(&&)[1])>()({ DeclVal<T>() }); };
static constexpr bool bConditional = requires { DeclVal<void(FFrontType(&&)[1])>()({ DeclVal<T>() }); };
using Type = TConditional<bConditional, Meta::TPush<FrontType, NextUniqueSequence>, NextUniqueSequence>;
using FType = TConditional<bConditional, Meta::TPush<FFrontType, FNextUniqueSequence>, FNextUniqueSequence>;
};
template <typename T>
struct TVariantOverloadType<T, TTypeSequence<>>
{
using Type = TTypeSequence<>;
using FType = TTypeSequence<>;
};
template <typename T, typename... Ts>
using TVariantSelectedType = Meta::TOverloadResolution<T, typename NAMESPACE_PRIVATE::TVariantOverloadType<T, TTypeSequence<Ts...>>::Type>;
using TVariantSelectedType = Meta::TOverloadResolution<T, typename NAMESPACE_PRIVATE::TVariantOverloadType<T, TTypeSequence<Ts...>>::FType>;
NAMESPACE_PRIVATE_END
@ -77,7 +77,7 @@ template <typename T, CTVariant U>
inline constexpr size_t TVariantIndex = NAMESPACE_PRIVATE::TVariantIndexImpl<T, TRemoveCV<U>>::Value;
template <size_t I, CTVariant U>
using TVariantAlternative = TCopyCV<U, typename NAMESPACE_PRIVATE::TVariantAlternativeImpl<I, TRemoveCV<U>>::Type>;
using TVariantAlternative = TCopyCV<U, typename NAMESPACE_PRIVATE::TVariantAlternativeImpl<I, TRemoveCV<U>>::FType>;
/**
* The class template TVariant represents a type-safe union. An instance of TVariant
@ -113,7 +113,7 @@ public:
{
if (IsValid()) MoveConstructImpl[InValue.GetIndex()](&Value, &InValue.Value);
}
/**
* Converting constructor. Constructs a variant holding the alternative type that would be selected
* by overload resolution for the expression F(Forward<T>(InValue)) if there was an overload of
@ -126,7 +126,7 @@ public:
&& !CSameAs<TVariant, TRemoveCVRef<T>>)
FORCEINLINE constexpr TVariant(T&& InValue) : TVariant(InPlaceType<NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>>, Forward<T>(InValue))
{ }
/** Constructs a variant with the specified alternative T and initializes the contained value with the arguments Forward<Us>(Args).... */
template <typename T, typename... Us> requires (CConstructibleFrom<T, Us...>)
FORCEINLINE constexpr explicit TVariant(TInPlaceType<T>, Us&&... Args)
@ -139,10 +139,10 @@ public:
FORCEINLINE constexpr explicit TVariant(TInPlaceIndex<I>, Us&&... Args)
: TypeIndex(I)
{
using SelectedType = TVariantAlternative<I, TVariant<Ts...>>;
new (&Value) SelectedType(Forward<Us>(Args)...);
using FSelectedType = TVariantAlternative<I, TVariant<Ts...>>;
new (&Value) FSelectedType(Forward<Us>(Args)...);
}
/** Constructs a variant with the specified alternative T and initializes the contained value with the arguments IL, Forward<Us>(Args).... */
template <typename T, typename U, typename... Us> requires (CConstructibleFrom<T, initializer_list<U>, Us...>)
FORCEINLINE constexpr explicit TVariant(TInPlaceType<T>, initializer_list<U> IL, Us&&... Args)
@ -155,8 +155,8 @@ public:
FORCEINLINE constexpr explicit TVariant(TInPlaceIndex<I>, initializer_list<T> IL, Us&&... Args)
: TypeIndex(I)
{
using SelectedType = TVariantAlternative<I, TVariant<Ts...>>;
new (&Value) SelectedType(IL, Forward<Us>(Args)...);
using FSelectedType = TVariantAlternative<I, TVariant<Ts...>>;
new (&Value) FSelectedType(IL, Forward<Us>(Args)...);
}
/** Destroys the contained object, if any, as if by a call to Reset(). */
@ -185,7 +185,7 @@ public:
if (GetIndex() == InValue.GetIndex()) CopyAssignImpl[InValue.GetIndex()](&Value, &InValue.Value);
else
{
{
Reset();
CopyConstructImpl[InValue.GetIndex()](&Value, &InValue.Value);
TypeIndex = static_cast<uint8>(InValue.GetIndex());
@ -224,14 +224,14 @@ public:
template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; })
FORCEINLINE constexpr TVariant& operator=(T&& InValue)
{
using SelectedType = NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>;
using FSelectedType = NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>;
if (GetIndex() == TVariantIndex<SelectedType, TVariant<Ts...>>) GetValue<SelectedType>() = Forward<T>(InValue);
if (GetIndex() == TVariantIndex<FSelectedType, TVariant<Ts...>>) GetValue<FSelectedType>() = Forward<T>(InValue);
else
{
Reset();
new (&Value) SelectedType(Forward<T>(InValue));
TypeIndex = TVariantIndex<SelectedType, TVariant<Ts...>>;
new (&Value) FSelectedType(Forward<T>(InValue));
TypeIndex = TVariantIndex<FSelectedType, TVariant<Ts...>>;
}
return *this;
@ -277,7 +277,7 @@ public:
/** @return true if instance does not contain a value, otherwise false. */
NODISCARD FORCEINLINE constexpr bool operator==(FInvalid) const& { return !IsValid(); }
/** Equivalent to Emplace<I>(Forward<Us>(Args)...), where I is the zero-based index of T in Types.... */
template <typename T, typename... Us> requires (CConstructibleFrom<T, Us...>)
FORCEINLINE constexpr T& Emplace(Us&&... Args)
@ -290,7 +290,7 @@ public:
* Then direct-initializes the contained value as if constructing a value of type T with the arguments Forward<Us>(Args)....
*
* @param Args - The arguments to be passed to the constructor of the contained object.
*
*
* @return A reference to the new contained object.
*/
template <size_t I, typename... Us> requires (I < sizeof...(Ts)
@ -299,13 +299,13 @@ public:
{
Reset();
using SelectedType = TVariantAlternative<I, TVariant<Ts...>>;
SelectedType* Result = new (&Value) SelectedType(Forward<Us>(Args)...);
using FSelectedType = TVariantAlternative<I, TVariant<Ts...>>;
FSelectedType* Result = new (&Value) FSelectedType(Forward<Us>(Args)...);
TypeIndex = I;
return *Result;
}
/** Equivalent to Emplace<I>(IL, Forward<Us>(Args)...), where I is the zero-based index of T in Types.... */
template <typename T, typename U, typename... Us> requires (CConstructibleFrom<T, initializer_list<U>, Us...>)
FORCEINLINE constexpr T& Emplace(initializer_list<U> IL, Us&&... Args)
@ -318,7 +318,7 @@ public:
* Then direct-initializes the contained value as if constructing a value of type T with the arguments IL, Forward<Us>(Args)....
*
* @param IL, Args - The arguments to be passed to the constructor of the contained object.
*
*
* @return A reference to the new contained object.
*/
template <size_t I, typename T, typename... Us> requires (I < sizeof...(Ts)
@ -327,8 +327,8 @@ public:
{
Reset();
using SelectedType = TVariantAlternative<I, TVariant<Ts...>>;
SelectedType* Result = new (&Value) SelectedType(IL, Forward<Us>(Args)...);
using FSelectedType = TVariantAlternative<I, TVariant<Ts...>>;
FSelectedType* Result = new (&Value) FSelectedType(IL, Forward<Us>(Args)...);
TypeIndex = I;
return *Result;
@ -423,7 +423,7 @@ public:
}
private:
static constexpr const type_info* TypeInfos[] = { &typeid(Ts)... };
using FCopyConstructImpl = void(*)(void*, const void*);
@ -448,7 +448,7 @@ NAMESPACE_PRIVATE_BEGIN
template <typename F, typename... VariantTypes>
struct TVariantVisitImpl
{
struct GetTotalNum
struct FGetTotalNum
{
FORCEINLINE static constexpr size_t Do()
{
@ -464,10 +464,10 @@ struct TVariantVisitImpl
}
return Result;
};
}
};
struct EncodeIndices
struct FEncodeIndices
{
FORCEINLINE static constexpr size_t Do(initializer_list<size_t> Indices)
{
@ -482,10 +482,10 @@ struct TVariantVisitImpl
}
return Result;
};
}
};
struct DecodeExtent
struct FDecodeExtent
{
FORCEINLINE static constexpr size_t Do(size_t EncodedIndex, size_t Extent)
{
@ -497,76 +497,76 @@ struct TVariantVisitImpl
}
return EncodedIndex % VariantNums[Extent];
};
}
};
template <size_t EncodedIndex, typename>
struct InvokeEncoded;
struct FInvokeEncoded;
template <size_t EncodedIndex, size_t... ExtentIndices>
struct InvokeEncoded<EncodedIndex, TIndexSequence<ExtentIndices...>>
struct FInvokeEncoded<EncodedIndex, TIndexSequence<ExtentIndices...>>
{
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<FDecodeExtent::Do(EncodedIndex, ExtentIndices)>()...);
}
template <typename Ret>
struct Result
struct FResult
{
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<FDecodeExtent::Do(EncodedIndex, ExtentIndices)>()...);
}
};
};
template <typename>
struct InvokeVariant;
struct FInvokeVariant;
template <size_t... EncodedIndices>
struct InvokeVariant<TIndexSequence<EncodedIndices...>>
struct FInvokeVariant<TIndexSequence<EncodedIndices...>>
{
FORCEINLINE static constexpr decltype(auto) Do(F&& Func, VariantTypes&&... Variants)
{
using ExtentIndices = TIndexSequenceFor<VariantTypes...>;
using FExtentIndices = TIndexSequenceFor<VariantTypes...>;
using ResultType = TCommonType<decltype(InvokeEncoded<EncodedIndices, ExtentIndices>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...))...>;
using InvokeImplType = ResultType(*)(F&&, VariantTypes&&...);
using FResultType = TCommonType<decltype(FInvokeEncoded<EncodedIndices, FExtentIndices>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...))...>;
constexpr InvokeImplType InvokeImpl[] = { InvokeEncoded<EncodedIndices, ExtentIndices>::template Result<ResultType>::Do... };
using FInvokeImplType = FResultType(*)(F&&, VariantTypes&&...);
return InvokeImpl[EncodeIndices::Do({ Variants.GetIndex()... })](Forward<F>(Func), Forward<VariantTypes>(Variants)...);
constexpr FInvokeImplType InvokeImpl[] = { FInvokeEncoded<EncodedIndices, FExtentIndices>::template FResult<FResultType>::Do... };
return InvokeImpl[FEncodeIndices::Do({ Variants.GetIndex()... })](Forward<F>(Func), Forward<VariantTypes>(Variants)...);
}
template <typename Ret>
struct Result
struct FResult
{
FORCEINLINE static constexpr Ret Do(F&& Func, VariantTypes&&... Variants)
{
using ExtentIndices = TIndexSequenceFor<VariantTypes...>;
using FExtentIndices = TIndexSequenceFor<VariantTypes...>;
using InvokeImplType = Ret(*)(F&&, VariantTypes&&...);
using FInvokeImplType = Ret(*)(F&&, VariantTypes&&...);
constexpr InvokeImplType InvokeImpl[] = { InvokeEncoded<EncodedIndices, ExtentIndices>::template Result<Ret>::Do... };
constexpr FInvokeImplType InvokeImpl[] = { FInvokeEncoded<EncodedIndices, FExtentIndices>::template FResult<Ret>::Do... };
return InvokeImpl[EncodeIndices::Do({ Variants.GetIndex()... })](Forward<F>(Func), Forward<VariantTypes>(Variants)...);
return InvokeImpl[FEncodeIndices::Do({ Variants.GetIndex()... })](Forward<F>(Func), Forward<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 FInvokeVariant<TMakeIndexSequence<FGetTotalNum::Do()>>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...);
}
template <typename Ret>
struct Result
struct FResult
{
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 FInvokeVariant<TMakeIndexSequence<FGetTotalNum::Do()>>::template FResult<Ret>::Do(Forward<F>(Func), Forward<VariantTypes>(Variants)...);
}
};
};
@ -588,7 +588,7 @@ template <typename Ret, typename F, typename FirstVariantType, typename... Varia
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()."));
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 FResult<Ret>::Do(Forward<F>(Func), Forward<FirstVariantType>(FirstVariant), Forward<VariantTypes>(Variants)...);
}
NAMESPACE_MODULE_END(Utility)