refactor(typetraits): replaces template class type traits with concepts for TypeTraits/PrimaryType.h

This commit is contained in:
_Redstone_c_ 2022-05-15 22:56:53 +08:00
parent 5d1f622af8
commit 1dcd3dc3b3
18 changed files with 152 additions and 156 deletions

View File

@ -271,8 +271,8 @@ void TestVariant()
using T = decltype(Arg);
always_check(Arg == 10);
always_check(TIsConst<typename TRemoveReference<T>::Type>::Value == bIsConst);
always_check(TIsLValueReference<T>::Value == bIsLValue);
always_check(TIsRValueReference<T>::Value == bIsRValue);
always_check(CLValueReference<T> == bIsLValue);
always_check(CRValueReference<T> == bIsRValue);
return 0;
};

View File

@ -64,59 +64,59 @@ void TestTypeTraits()
// PrimaryType.h
always_check(!TIsVoid<int32>::Value);
always_check(TIsVoid<void>::Value);
always_check(TIsVoid<const void>::Value);
always_check(TIsVoid<const volatile void>::Value);
always_check(TIsVoid<volatile void>::Value);
always_check(!CVoid<int32>);
always_check(CVoid<void>);
always_check(CVoid<const void>);
always_check(CVoid<const volatile void>);
always_check(CVoid<volatile void>);
always_check(!TIsNullPointer<int32>::Value);
always_check(TIsNullPointer<nullptr_t>::Value);
always_check(!CNullPointer<int32>);
always_check(CNullPointer<nullptr_t>);
always_check(TIsIntegral<int32>::Value);
always_check(!TIsIntegral<float>::Value);
always_check(CIntegral<int32>);
always_check(!CIntegral<float>);
always_check(!TIsFloatingPoint<int32>::Value);
always_check(TIsFloatingPoint<float>::Value);
always_check(!CFloatingPoint<int32>);
always_check(CFloatingPoint<float>);
always_check(!TIsArray<int32>::Value);
always_check(TIsArray<int32[]>::Value);
always_check(TIsArray<int32[10]>::Value);
always_check(!CArray<int32>);
always_check(CArray<int32[]>);
always_check(CArray<int32[10]>);
always_check(!TIsPointer<int32>::Value);
always_check(TIsPointer<int32*>::Value);
always_check(!CPointer<int32>);
always_check(CPointer<int32*>);
always_check(!TIsLValueReference<int32>::Value);
always_check(TIsLValueReference<int32&>::Value);
always_check(!TIsLValueReference<int32&&>::Value);
always_check(!CLValueReference<int32>);
always_check(CLValueReference<int32&>);
always_check(!CLValueReference<int32&&>);
always_check(!TIsRValueReference<int32>::Value);
always_check(!TIsRValueReference<int32&>::Value);
always_check(TIsRValueReference<int32&&>::Value);
always_check(!CRValueReference<int32>);
always_check(!CRValueReference<int32&>);
always_check(CRValueReference<int32&&>);
always_check(TIsMemberObjectPointer<int32(FTestStructA::*)>::Value);
always_check(!TIsMemberObjectPointer<int32(FTestStructA::*)()>::Value);
always_check(CMemberObjectPointer<int32(FTestStructA::*)>);
always_check(!CMemberObjectPointer<int32(FTestStructA::*)()>);
always_check(!TIsMemberFunctionPointer<int32(FTestStructA::*)>::Value);
always_check(TIsMemberFunctionPointer<int32(FTestStructA::*)()>::Value);
always_check(!CMemberFunctionPointer<int32(FTestStructA::*)>);
always_check(CMemberFunctionPointer<int32(FTestStructA::*)()>);
always_check(!TIsEnum<int32>::Value);
always_check(!TIsEnum<FTestStructA>::Value);
always_check(TIsEnum<ETestEnum>::Value);
always_check(TIsEnum<ETestEnumClass>::Value);
always_check(!CEnum<int32>);
always_check(!CEnum<FTestStructA>);
always_check(CEnum<ETestEnum>);
always_check(CEnum<ETestEnumClass>);
always_check(!TIsUnion<int32>::Value);
always_check(!TIsUnion<FTestStructA>::Value);
always_check(TIsUnion<FTestUnion>::Value);
always_check(!CUnion<int32>);
always_check(!CUnion<FTestStructA>);
always_check(CUnion<FTestUnion>);
always_check(!TIsUnion<int32>::Value);
always_check(!TIsUnion<FTestStructA>::Value);
always_check(TIsUnion<FTestUnion>::Value);
always_check(!CUnion<int32>);
always_check(!CUnion<FTestStructA>);
always_check(CUnion<FTestUnion>);
always_check(!TIsFunction<int32>::Value);
always_check(!TIsFunction<FTestStructA>::Value);
always_check(!TIsFunction<FTestUnion>::Value);
always_check(TIsFunction<int32(int32)>::Value);
always_check(!CFunction<int32>);
always_check(!CFunction<FTestStructA>);
always_check(!CFunction<FTestUnion>);
always_check(CFunction<int32(int32)>);
// CompositeType.h

View File

@ -11,7 +11,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
template <typename T, typename U>
concept CAssignableFrom =
TIsLValueReference<T>::Value &&
CLValueReference<T> &&
CCommonReferenceWith<const typename TRemoveReference<T>::Type&, const typename TRemoveReference<U>::Type&> &&
requires(T A, U&& B)
{

View File

@ -7,11 +7,9 @@ NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T> concept CIntegral = TIsIntegral<T>::Value;
template <typename T> concept CSignedIntegral = CIntegral<T> && TIsSigned<T>::Value;
template <typename T> concept CUnsignedIntegral = CIntegral<T> && TIsUnsigned<T>::Value;
template <typename T> concept CNonBooleanIntegral = CIntegral<T> && !TIsSame<typename TRemoveCVRef<T>::Type, bool>::Value;
template <typename T> concept CFloatingPoint = TIsFloatingPoint<T>::Value;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)

View File

@ -12,28 +12,28 @@ NAMESPACE_BEGIN(Memory)
FORCEINLINE constexpr bool IsValidAlignment(size_t Alignment) { return !(Alignment & (Alignment - 1)); }
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
template <typename T> requires CIntegral<T> || CPointer<T>
FORCEINLINE constexpr T Align(T InValue, size_t Alignment)
{
checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2."));
return (T)(((uint64)(InValue) + static_cast<uint64>(Alignment) - 1) & ~(static_cast<uint64>(Alignment) - 1));
}
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
template <typename T> requires CIntegral<T> || CPointer<T>
FORCEINLINE constexpr T AlignDown(T InValue, size_t Alignment)
{
checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2."));
return (T)((uint64)(InValue) & ~(static_cast<uint64>(Alignment) - 1));
}
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
template <typename T> requires CIntegral<T> || CPointer<T>
FORCEINLINE constexpr T AlignArbitrary(T InValue, size_t Alignment)
{
checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2."));
return (T)((((uint64)(InValue) + static_cast<uint64>(Alignment) - 1) / static_cast<uint64>(Alignment)) * static_cast<uint64>(Alignment));
}
template <typename T> requires TIsIntegral<T>::Value || TIsPointer<T>::Value
template <typename T> requires CIntegral<T> || CPointer<T>
FORCEINLINE constexpr bool IsAligned(T InValue, size_t Alignment)
{
checkf(IsValidAlignment(Alignment), TEXT("The alignment value must be an integer power of 2."));

View File

@ -56,21 +56,21 @@ FORCEINLINE void* Memcpy(void* Destination, const void* Source, size_t Count)
template <typename T>
FORCEINLINE void Memset(T& Source, uint8 ValueToSet)
{
static_assert(!TIsPointer<T>::Value, "For pointers use the three parameters function");
static_assert(!CPointer<T>, "For pointers use the three parameters function");
Memset(&Source, ValueToSet, sizeof(T));
}
template <typename T>
FORCEINLINE void Memzero(T& Source)
{
static_assert(!TIsPointer<T>::Value, "For pointers use the two parameters function");
static_assert(!CPointer<T>, "For pointers use the two parameters function");
Memzero(&Source, sizeof(T));
}
template <typename T>
FORCEINLINE void Memcpy(T& Destination, const T& Source)
{
static_assert(!TIsPointer<T>::Value, "For pointers use the three parameters function");
static_assert(!CPointer<T>, "For pointers use the three parameters function");
Memcpy(&Destination, &Source, sizeof(T));
}

View File

@ -68,8 +68,7 @@ struct alignas(InlineAlignment) TAny
}
}
template <typename T, typename... Types> requires TIsObject<typename TDecay<T>::Type>::Value
&& (!TIsArray<typename TDecay<T>::Type>::Value) && TIsDestructible<typename TDecay<T>::Type>::Value
template <typename T, typename... Types> requires TIsDestructible<typename TDecay<T>::Type>::Value
&& TIsConstructible<typename TDecay<T>::Type, Types...>::Value
FORCEINLINE explicit TAny(TInPlaceType<T>, Types&&... Args)
{
@ -204,8 +203,7 @@ struct alignas(InlineAlignment) TAny
return *this;
}
template <typename T, typename... Types> requires TIsObject<typename TDecay<T>::Type>::Value
&& (!TIsArray<typename TDecay<T>::Type>::Value) && TIsDestructible<typename TDecay<T>::Type>::Value
template <typename T, typename... Types> requires TIsDestructible<typename TDecay<T>::Type>::Value
&& TIsConstructible<typename TDecay<T>::Type, T&&>::Value
FORCEINLINE typename TDecay<T>::Type& Emplace(Types&&... Args)
{

View File

@ -137,89 +137,89 @@ public:
return Temp;
}
FORCEINLINE ValueType FetchAdd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return Element.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAdd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return Element.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAdd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return Element.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 Element.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAdd(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsPointer<T>::Value { return Element.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAdd(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsPointer<T>::Value && bIsAlwaysLockFree { return Element.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAdd(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires CPointer<T> { return Element.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 Element.fetch_add(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return Element.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return Element.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (CIntegral<T> || CFloatingPoint<T>) { return Element.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 Element.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsPointer<T>::Value { return Element.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsPointer<T>::Value && bIsAlwaysLockFree { return Element.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchSub(ptrdiff InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires CPointer<T> { return Element.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 Element.fetch_sub(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchMul(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old * InValue; }); }
FORCEINLINE ValueType FetchMul(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return FetchFn([InValue](ValueType Old) -> ValueType { return Old * InValue; }); }
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 ValueType FetchDiv(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return FetchFn([InValue](ValueType Old) -> ValueType { return Old / InValue; }); }
FORCEINLINE ValueType FetchDiv(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return FetchFn([InValue](ValueType Old) -> ValueType { return Old / InValue; }); }
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 ValueType FetchMod(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsIntegral<T>::Value { return FetchFn([InValue](ValueType Old) -> ValueType { return Old % InValue; }); }
FORCEINLINE ValueType FetchMod(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return FetchFn([InValue](ValueType Old) -> ValueType { return Old % InValue; }); }
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 ValueType FetchAnd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsIntegral<T>::Value { return Element.fetch_and(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAnd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return Element.fetch_and(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchAnd(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires CIntegral<T> { return Element.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 Element.fetch_and(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchOr(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsIntegral<T>::Value { return Element.fetch_or(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchOr(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return Element.fetch_or(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchOr(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires CIntegral<T> { return Element.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 Element.fetch_or(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchXor(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsIntegral<T>::Value { return Element.fetch_xor(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchXor(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return Element.fetch_xor(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchXor(ValueType InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires CIntegral<T> { return Element.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 Element.fetch_xor(InValue, static_cast<NAMESPACE_STD::memory_order>(Order)); }
FORCEINLINE ValueType FetchLsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsIntegral<T>::Value { return FetchFn([InValue](ValueType Old) -> ValueType { return Old << InValue; }); }
FORCEINLINE ValueType FetchLsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return FetchFn([InValue](ValueType Old) -> ValueType { return Old << InValue; }); }
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 ValueType FetchRsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) requires TIsIntegral<T>::Value { return FetchFn([InValue](ValueType Old) -> ValueType { return Old >> InValue; }); }
FORCEINLINE ValueType FetchRsh(size_t InValue, EMemoryOrder Order = EMemoryOrder::SequentiallyConsistent) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return FetchFn([InValue](ValueType Old) -> ValueType { return Old >> InValue; }); }
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; }); }
FORCEINLINE ValueType operator++() requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) { return ++Element; }
FORCEINLINE ValueType operator++() volatile requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) && bIsAlwaysLockFree { return ++Element; }
FORCEINLINE ValueType operator++() requires (CIntegral<T> || CPointer<T>) { return ++Element; }
FORCEINLINE ValueType operator++() volatile requires (CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree { return ++Element; }
FORCEINLINE ValueType operator++(int) requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) { return Element++; }
FORCEINLINE ValueType operator++(int) volatile requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) && bIsAlwaysLockFree { return Element++; }
FORCEINLINE ValueType operator++(int) requires (CIntegral<T> || CPointer<T>) { return Element++; }
FORCEINLINE ValueType operator++(int) volatile requires (CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree { return Element++; }
FORCEINLINE ValueType operator--() requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) { return --Element; }
FORCEINLINE ValueType operator--() volatile requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) && bIsAlwaysLockFree { return --Element; }
FORCEINLINE ValueType operator--() requires (CIntegral<T> || CPointer<T>) { return --Element; }
FORCEINLINE ValueType operator--() volatile requires (CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree { return --Element; }
FORCEINLINE ValueType operator--(int) requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) { return Element--; }
FORCEINLINE ValueType operator--(int) volatile requires (TIsIntegral<T>::Value || TIsPointer<T>::Value) && bIsAlwaysLockFree { return Element--; }
FORCEINLINE ValueType operator--(int) requires (CIntegral<T> || CPointer<T>) { return Element--; }
FORCEINLINE ValueType operator--(int) volatile requires (CIntegral<T> || CPointer<T>) && bIsAlwaysLockFree { return Element--; }
FORCEINLINE ValueType operator+=(ValueType InValue) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return Element += InValue; }
FORCEINLINE ValueType operator+=(ValueType InValue) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return Element += InValue; }
FORCEINLINE ValueType operator+=(ValueType InValue) requires (CIntegral<T> || CFloatingPoint<T>) { return Element += InValue; }
FORCEINLINE ValueType operator+=(ValueType InValue) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return Element += InValue; }
FORCEINLINE ValueType operator+=(ptrdiff InValue) requires TIsPointer<T>::Value { return Element += InValue; }
FORCEINLINE ValueType operator+=(ptrdiff InValue) volatile requires TIsPointer<T>::Value && bIsAlwaysLockFree { return Element += InValue; }
FORCEINLINE ValueType operator+=(ptrdiff InValue) requires CPointer<T> { return Element += InValue; }
FORCEINLINE ValueType operator+=(ptrdiff InValue) volatile requires CPointer<T> && bIsAlwaysLockFree { return Element += InValue; }
FORCEINLINE ValueType operator-=(ValueType InValue) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return Element -= InValue; }
FORCEINLINE ValueType operator-=(ValueType InValue) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return Element -= InValue; }
FORCEINLINE ValueType operator-=(ValueType InValue) requires (CIntegral<T> || CFloatingPoint<T>) { return Element -= InValue; }
FORCEINLINE ValueType operator-=(ValueType InValue) volatile requires (CIntegral<T> || CFloatingPoint<T>) && bIsAlwaysLockFree { return Element -= InValue; }
FORCEINLINE ValueType operator-=(ptrdiff InValue) requires TIsPointer<T>::Value { return Element -= InValue; }
FORCEINLINE ValueType operator-=(ptrdiff InValue) volatile requires TIsPointer<T>::Value && bIsAlwaysLockFree { return Element -= InValue; }
FORCEINLINE ValueType operator-=(ptrdiff InValue) requires CPointer<T> { return Element -= InValue; }
FORCEINLINE ValueType operator-=(ptrdiff InValue) volatile requires CPointer<T> && bIsAlwaysLockFree { return Element -= InValue; }
FORCEINLINE ValueType operator*=(ValueType InValue) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return FetchMul(InValue) * InValue; }
FORCEINLINE ValueType operator*=(ValueType InValue) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return FetchMul(InValue) * InValue; }
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 ValueType operator/=(ValueType InValue) requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) { return FetchDiv(InValue) / InValue; }
FORCEINLINE ValueType operator/=(ValueType InValue) volatile requires (TIsIntegral<T>::Value || TIsFloatingPoint<T>::Value) && bIsAlwaysLockFree { return FetchDiv(InValue) / InValue; }
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 ValueType operator%=(ValueType InValue) requires TIsIntegral<T>::Value { return FetchMod(InValue) % InValue; }
FORCEINLINE ValueType operator%=(ValueType InValue) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return FetchMod(InValue) % InValue; }
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 ValueType operator&=(ValueType InValue) requires TIsIntegral<T>::Value { return Element &= InValue; }
FORCEINLINE ValueType operator&=(ValueType InValue) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return Element &= InValue; }
FORCEINLINE ValueType operator&=(ValueType InValue) requires CIntegral<T> { return Element &= InValue; }
FORCEINLINE ValueType operator&=(ValueType InValue) volatile requires CIntegral<T> && bIsAlwaysLockFree { return Element &= InValue; }
FORCEINLINE ValueType operator|=(ValueType InValue) requires TIsIntegral<T>::Value { return Element |= InValue; }
FORCEINLINE ValueType operator|=(ValueType InValue) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return Element |= InValue; }
FORCEINLINE ValueType operator|=(ValueType InValue) requires CIntegral<T> { return Element |= InValue; }
FORCEINLINE ValueType operator|=(ValueType InValue) volatile requires CIntegral<T> && bIsAlwaysLockFree { return Element |= InValue; }
FORCEINLINE ValueType operator^=(ValueType InValue) requires TIsIntegral<T>::Value { return Element ^= InValue; }
FORCEINLINE ValueType operator^=(ValueType InValue) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return Element ^= InValue; }
FORCEINLINE ValueType operator^=(ValueType InValue) requires CIntegral<T> { return Element ^= InValue; }
FORCEINLINE ValueType operator^=(ValueType InValue) volatile requires CIntegral<T> && bIsAlwaysLockFree { return Element ^= InValue; }
FORCEINLINE ValueType operator<<=(size_t InValue) requires TIsIntegral<T>::Value { return FetchLsh(InValue) << InValue; }
FORCEINLINE ValueType operator<<=(size_t InValue) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return FetchLsh(InValue) << InValue; }
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 ValueType operator>>=(size_t InValue) requires TIsIntegral<T>::Value { return FetchRsh(InValue) >> InValue; }
FORCEINLINE ValueType operator>>=(size_t InValue) volatile requires TIsIntegral<T>::Value && bIsAlwaysLockFree { return FetchRsh(InValue) >> InValue; }
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; }
protected:

View File

@ -19,13 +19,13 @@ NAMESPACE_MODULE_BEGIN(Utility)
inline constexpr size_t FUNCTION_DEFAULT_INLINE_SIZE = ANY_DEFAULT_INLINE_SIZE - sizeof(uintptr);
inline constexpr size_t FUNCTION_DEFAULT_INLINE_ALIGNMENT = ANY_DEFAULT_INLINE_ALIGNMENT;
template <typename F> requires TIsFunction<F>::Value
template <typename F> requires CFunction<F>
struct TFunctionRef;
template <typename F, size_t InlineSize, size_t InlineAlignment> requires TIsFunction<F>::Value && (Memory::IsValidAlignment(InlineAlignment))
template <typename F, size_t InlineSize, size_t InlineAlignment> requires CFunction<F> && (Memory::IsValidAlignment(InlineAlignment))
struct TFunction;
template <typename F, size_t InlineSize, size_t InlineAlignment> requires TIsFunction<F>::Value && (Memory::IsValidAlignment(InlineAlignment))
template <typename F, size_t InlineSize, size_t InlineAlignment> requires CFunction<F> && (Memory::IsValidAlignment(InlineAlignment))
struct TUniqueFunction;
template <typename T> struct TIsTFunctionRef : FFalse { };
@ -42,7 +42,7 @@ NAMESPACE_PRIVATE_BEGIN
template <typename T>
constexpr bool FunctionIsBound(const T& Func)
{
if constexpr (TIsPointer<T>::Value || TIsMemberPointer<T>::Value || TIsTFunctionRef<T>::Value || TIsTFunction<T>::Value || TIsTUniqueFunction<T>::Value)
if constexpr (CPointer<T> || TIsMemberPointer<T>::Value || TIsTFunctionRef<T>::Value || TIsTFunction<T>::Value || TIsTUniqueFunction<T>::Value)
{
return !!Func;
}
@ -213,7 +213,7 @@ protected:
NAMESPACE_PRIVATE_END
template <typename F> requires TIsFunction<F>::Value
template <typename F> requires CFunction<F>
struct TFunctionRef
: public NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
@ -256,7 +256,7 @@ public:
};
template <typename F, size_t InlineSize = FUNCTION_DEFAULT_INLINE_SIZE, size_t InlineAlignment = FUNCTION_DEFAULT_INLINE_ALIGNMENT>
requires TIsFunction<F>::Value && (Memory::IsValidAlignment(InlineAlignment))
requires CFunction<F> && (Memory::IsValidAlignment(InlineAlignment))
struct TFunction
: public NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,
@ -342,7 +342,7 @@ public:
};
template <typename F, size_t InlineSize = FUNCTION_DEFAULT_INLINE_SIZE, size_t InlineAlignment = FUNCTION_DEFAULT_INLINE_ALIGNMENT>
requires TIsFunction<F>::Value && (Memory::IsValidAlignment(InlineAlignment))
requires CFunction<F> && (Memory::IsValidAlignment(InlineAlignment))
struct TUniqueFunction
: public NAMESPACE_PRIVATE::TFunctionImpl<
typename NAMESPACE_PRIVATE::TFunctionInfo<F>::Fn,

View File

@ -57,8 +57,8 @@ struct InvokeMemberObject
template <typename F,
typename T,
typename Decayed = typename TDecay<F>::Type,
bool IsMemberFunction = TIsMemberFunctionPointer<Decayed>::Value,
bool IsMemberObject = TIsMemberObjectPointer<Decayed>::Value>
bool IsMemberFunction = CMemberFunctionPointer<Decayed>,
bool IsMemberObject = CMemberObjectPointer<Decayed>>
struct InvokeMember;
template <typename F, typename T, typename Decayed>
@ -91,8 +91,8 @@ constexpr auto Invoke(F&& Func, Types&&... Args)
template <typename R, typename F, typename... Types> requires TIsInvocableResult<R, F, Types...>::Value
constexpr R InvokeResult(F&& Func, Types&&... Args)
{
if constexpr (TIsVoid<R>::Value) Invoke(Forward<F>(Func), Forward<Types>(Args)...);
else return Invoke(Forward<F>(Func), Forward<Types>(Args)...);
if constexpr (CVoid<R>) Invoke(Forward<F>(Func), Forward<Types>(Args)...);
else return Invoke(Forward<F>(Func), Forward<Types>(Args)...);
}
NAMESPACE_MODULE_END(Utility)

View File

@ -12,7 +12,7 @@ NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename OptionalType> requires TIsObject<OptionalType>::Value && (!TIsArray<OptionalType>::Value) && TIsDestructible<OptionalType>::Value
template <typename OptionalType> requires TIsDestructible<OptionalType>::Value
struct TOptional
{
private:
@ -283,19 +283,19 @@ constexpr bool operator==(const TOptional<T>& LHS, FInvalid)
return !LHS.IsValid();
}
template <typename T> requires (TIsObject<T>::Value && !TIsArray<T>::Value && TIsDestructible<T>::Value)
template <typename T> requires TIsDestructible<T>::Value
constexpr TOptional<typename TDecay<T>::Type> MakeOptional(FInvalid)
{
return TOptional<typename TDecay<T>::Type>(Invalid);
}
template <typename T> requires (TIsObject<T>::Value && !TIsArray<T>::Value && TIsDestructible<T>::Value)
constexpr TOptional<typename TDecay<T>::Type> MakeOptional(T&& InValue)
template <typename T> requires TIsDestructible<T>::Value && TIsConstructible<T, T&&>::Value
constexpr TOptional<T> MakeOptional(T&& InValue)
{
return TOptional<typename TDecay<T>::Type>(Forward<T>(InValue));
return TOptional<T>(Forward<T>(InValue));
}
template <typename T, typename... Types> requires (TIsObject<T>::Value && !TIsArray<T>::Value && TIsDestructible<T>::Value)
template <typename T, typename... Types> requires TIsDestructible<T>::Value && TIsConstructible<T, Types...>::Value
constexpr TOptional<T> MakeOptional(Types&&... Args)
{
return TOptional<T>(InPlace, Forward<T>(Args)...);

View File

@ -10,7 +10,7 @@ NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename ReferencedType> requires (TIsObject<ReferencedType>::Value || TIsFunction<ReferencedType>::Value)
template <typename ReferencedType> requires (TIsObject<ReferencedType>::Value || CFunction<ReferencedType>)
struct TReferenceWrapper
{
public:
@ -61,11 +61,11 @@ private:
ReferencedType* Pointer;
template <typename T> requires (TIsObject<T>::Value || TIsFunction<T>::Value) friend struct TReferenceWrapper;
template <typename T> requires (TIsObject<T>::Value || CFunction<T>) friend struct TReferenceWrapper;
// Optimize TOptional with these hacking
constexpr TReferenceWrapper(FInvalid) : Pointer(nullptr) { };
template <typename T> requires TIsObject<T>::Value && (!TIsArray<T>::Value) && TIsDestructible<T>::Value friend struct TOptional;
template <typename T> requires TIsDestructible<T>::Value friend struct TOptional;
};
@ -221,7 +221,7 @@ public:
private:
TReferenceWrapper<ReferencedType> Reference;
template <typename T> requires TIsObject<T>::Value && (!TIsArray<T>::Value) && TIsDestructible<T>::Value friend struct TOptional;
template <typename T> requires TIsDestructible<T>::Value friend struct TOptional;
};

View File

@ -448,7 +448,7 @@ template <typename... RTypes, size_t... Indices>
struct TTupleCatMake<TTuple<RTypes...>, TIndexSequence<Indices...>>
{
template <typename T, typename U>
struct ForwardType { using Type = typename TConditional<TIsRValueReference<T>::Value, typename TRemoveReference<U>::Type&&, U>::Type; };
struct ForwardType { using Type = typename TConditional<CRValueReference<T>, typename TRemoveReference<U>::Type&&, U>::Type; };
template <typename TTupleType>
static constexpr TTuple<RTypes...> F(TTupleType&& InValue)

View File

@ -47,7 +47,7 @@ constexpr size_t HashCombine(size_t A, size_t C, Ts... InOther)
return HashCombine(B, InOther...);
}
template <typename T> requires TIsIntegral<T>::Value
template <typename T> requires CIntegral<T>
constexpr size_t GetTypeHash(T A)
{
static_assert(sizeof(T) <= 16, "GetTypeHash only works with T up to 128 bits.");
@ -60,7 +60,7 @@ constexpr size_t GetTypeHash(T A)
return INDEX_NONE;
}
template <typename T> requires TIsFloatingPoint<T>::Value
template <typename T> requires CFloatingPoint<T>
constexpr size_t GetTypeHash(T A)
{
static_assert(sizeof(T) <= 16, "GetTypeHash only works with T up to 128 bits.");
@ -75,13 +75,13 @@ constexpr size_t GetTypeHash(T A)
return INDEX_NONE;
}
template <typename T> requires TIsEnum<T>::Value
template <typename T> requires CEnum<T>
constexpr size_t GetTypeHash(T A)
{
return GetTypeHash(static_cast<typename TUnderlyingType<T>::Type>(A));
}
template <typename T> requires TIsPointer<T>::Value || TIsSame<T, nullptr_t>::Value
template <typename T> requires CPointer<T> || TIsSame<T, nullptr_t>::Value
constexpr size_t GetTypeHash(T A)
{
return GetTypeHash(reinterpret_cast<intptr>(A));

View File

@ -78,7 +78,7 @@ struct TVariantSelectedType<T>
NAMESPACE_PRIVATE_END
template <typename... Types> requires (true && ... && (TIsObject<Types>::Value && !TIsArray<Types>::Value && TIsDestructible<Types>::Value)) && (sizeof...(Types) < 0xFF)
template <typename... Types> requires (true && ... && TIsDestructible<Types>::Value) && (sizeof...(Types) < 0xFF)
struct TVariant
{
static constexpr size_t AlternativeSize = sizeof...(Types);

View File

@ -14,7 +14,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
// Assume that all operands of bitwise operations have the same size
// This type traits is allowed to be specialised.
template <typename T> struct TIsZeroConstructible : TBoolConstant<TIsDefaultConstructible<T>::Value && (TIsEnum<T>::Value || TIsArithmetic<T>::Value || TIsPointer<T>::Value)> { };
template <typename T> struct TIsZeroConstructible : TBoolConstant<TIsDefaultConstructible<T>::Value && (CEnum<T> || TIsArithmetic<T>::Value || CPointer<T>)> { };
// This type traits is allowed to be specialised.
template <typename T, typename U> struct TIsBitwiseConstructible;
@ -72,7 +72,7 @@ template <typename T> struct TIsBitwiseRelocatable<T, T> : TBoolConstant<TIsObje
template <typename T, typename U> struct TIsBitwiseRelocatable : TBoolConstant<TIsBitwiseConstructible<T, U>::Value && TIsTriviallyDestructible<U>::Value> { };
// This type traits is allowed to be specialised.
template <typename T> struct TIsBitwiseComparable : TBoolConstant<TIsEnum<T>::Value || TIsArithmetic<T>::Value || TIsPointer<T>::Value> { };
template <typename T> struct TIsBitwiseComparable : TBoolConstant<CEnum<T> || TIsArithmetic<T>::Value || CPointer<T>> { };
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)

View File

@ -9,20 +9,20 @@ NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility)
template <typename T> struct TIsVoid : TBoolConstant<NAMESPACE_STD::is_void_v<T>> { };
template <typename T> struct TIsNullPointer : TBoolConstant<NAMESPACE_STD::is_null_pointer_v<T>> { };
template <typename T> struct TIsIntegral : TBoolConstant<NAMESPACE_STD::is_integral_v<T>> { };
template <typename T> struct TIsFloatingPoint : TBoolConstant<NAMESPACE_STD::is_floating_point_v<T>> { };
template <typename T> struct TIsArray : TBoolConstant<NAMESPACE_STD::is_array_v<T>> { };
template <typename T> struct TIsPointer : TBoolConstant<NAMESPACE_STD::is_pointer_v<T>> { };
template <typename T> struct TIsLValueReference : TBoolConstant<NAMESPACE_STD::is_lvalue_reference_v<T>> { };
template <typename T> struct TIsRValueReference : TBoolConstant<NAMESPACE_STD::is_rvalue_reference_v<T>> { };
template <typename T> struct TIsMemberObjectPointer : TBoolConstant<NAMESPACE_STD::is_member_object_pointer_v<T>> { };
template <typename T> struct TIsMemberFunctionPointer : TBoolConstant<NAMESPACE_STD::is_member_function_pointer_v<T>> { };
template <typename T> struct TIsEnum : TBoolConstant<NAMESPACE_STD::is_enum_v<T>> { };
template <typename T> struct TIsUnion : TBoolConstant<NAMESPACE_STD::is_union_v<T>> { };
template <typename T> struct TIsClass : TBoolConstant<NAMESPACE_STD::is_class_v<T>> { };
template <typename T> struct TIsFunction : TBoolConstant<NAMESPACE_STD::is_function_v<T>> { };
template <typename T> concept CVoid = NAMESPACE_STD::is_void_v<T>;
template <typename T> concept CNullPointer = NAMESPACE_STD::is_null_pointer_v<T>;
template <typename T> concept CIntegral = NAMESPACE_STD::is_integral_v<T>;
template <typename T> concept CFloatingPoint = NAMESPACE_STD::is_floating_point_v<T>;
template <typename T> concept CArray = NAMESPACE_STD::is_array_v<T>;
template <typename T> concept CPointer = NAMESPACE_STD::is_pointer_v<T>;
template <typename T> concept CLValueReference = NAMESPACE_STD::is_lvalue_reference_v<T>;
template <typename T> concept CRValueReference = NAMESPACE_STD::is_rvalue_reference_v<T>;
template <typename T> concept CMemberObjectPointer = NAMESPACE_STD::is_member_object_pointer_v<T>;
template <typename T> concept CMemberFunctionPointer = NAMESPACE_STD::is_member_function_pointer_v<T>;
template <typename T> concept CEnum = NAMESPACE_STD::is_enum_v<T>;
template <typename T> concept CUnion = NAMESPACE_STD::is_union_v<T>;
template <typename T> concept CClass = NAMESPACE_STD::is_class_v<T>;
template <typename T> concept CFunction = NAMESPACE_STD::is_function_v<T>;
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)

View File

@ -27,7 +27,7 @@ template <typename T> struct TIsBoundedArray : TBoolConstant<NAM
template <typename T> struct TIsUnboundedArray : TBoolConstant<NAMESPACE_STD::is_unbounded_array_v<T>> { };
template <typename T>
struct TIsScopedEnum : TBoolConstant<TIsEnum<T>::Value && !TIsConvertible<T, int64>::Value> { };
struct TIsScopedEnum : TBoolConstant<CEnum<T> && !TIsConvertible<T, int64>::Value> { };
NAMESPACE_MODULE_END(Utility)
NAMESPACE_MODULE_END(Redcraft)