refactor(*): make type alias identifiers conform to the style for general type identifiers
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)); }
|
||||
|
||||
};
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user