feat(templates): add TTypeSequence and meta tools
This commit is contained in:
parent
c4c1430e46
commit
01eec5d4c0
@ -2,7 +2,7 @@
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Any.h"
|
||||
#include "Templates/Tuple.h"
|
||||
#include "Templates/Meta.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Memory/Alignment.h"
|
||||
#include "Templates/Utility.h"
|
||||
@ -88,7 +88,7 @@ class TFunctionImpl<Ret(Ts...), CVRef, bIsRef>
|
||||
public:
|
||||
|
||||
using ResultType = Ret;
|
||||
using ArgumentType = TTuple<Ts...>;
|
||||
using ArgumentType = TTypeSequence<Ts...>;
|
||||
|
||||
TFunctionImpl() = default;
|
||||
TFunctionImpl(const TFunctionImpl&) = default;
|
||||
|
@ -1,66 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
template <typename T, T... Ints>
|
||||
struct TIntegerSequence
|
||||
{
|
||||
using ValueType = T;
|
||||
static constexpr size_t Size() { return sizeof...(Ints); }
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
template <unsigned N, typename T>
|
||||
struct TMakeIntegerSequenceImpl
|
||||
{
|
||||
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
||||
};
|
||||
|
||||
#elif __has_builtin(__make_integer_seq)
|
||||
|
||||
template <unsigned N, typename T>
|
||||
struct TMakeIntegerSequenceImpl
|
||||
{
|
||||
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <unsigned N, typename T, T... Ints>
|
||||
struct TMakeIntegerSequenceImpl
|
||||
{
|
||||
using Type = typename TMakeIntegerSequenceImpl<N - 1, T, T(N - 1), Ints...>::Type;
|
||||
};
|
||||
|
||||
template <typename T, T... Ints>
|
||||
struct TMakeIntegerSequenceImpl<0, T, Ints...>
|
||||
{
|
||||
using Type = TIntegerSequence<T, Ints...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <size_t... Ints>
|
||||
using TIndexSequence = TIntegerSequence<size_t, Ints...>;
|
||||
|
||||
template<typename T, T N>
|
||||
using TMakeIntegerSequence = typename NAMESPACE_PRIVATE::TMakeIntegerSequenceImpl<N, T>::Type;
|
||||
|
||||
template<size_t N>
|
||||
using TMakeIndexSequence = TMakeIntegerSequence<size_t, N>;
|
||||
|
||||
template<typename... T>
|
||||
using TIndexSequenceFor = TMakeIndexSequence<sizeof...(T)>;
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
280
Redcraft.Utility/Source/Public/Templates/Meta.h
Normal file
280
Redcraft.Utility/Source/Public/Templates/Meta.h
Normal file
@ -0,0 +1,280 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/Container.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
|
||||
NAMESPACE_REDCRAFT_BEGIN
|
||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||
NAMESPACE_MODULE_BEGIN(Utility)
|
||||
|
||||
template <typename T, T... Ints>
|
||||
struct TIntegerSequence
|
||||
{
|
||||
using ValueType = T;
|
||||
static constexpr size_t Num() { return sizeof...(Ints); }
|
||||
static constexpr const T* GetData() { return NAMESPACE_REDCRAFT::GetData({ Ints... }); }
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
template <unsigned N, typename T>
|
||||
struct TMakeIntegerSequenceImpl
|
||||
{
|
||||
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
||||
};
|
||||
|
||||
#elif __has_builtin(__make_integer_seq)
|
||||
|
||||
template <unsigned N, typename T>
|
||||
struct TMakeIntegerSequenceImpl
|
||||
{
|
||||
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template <unsigned N, typename T, T... Ints>
|
||||
struct TMakeIntegerSequenceImpl
|
||||
{
|
||||
using Type = typename TMakeIntegerSequenceImpl<N - 1, T, T(N - 1), Ints...>::Type;
|
||||
};
|
||||
|
||||
template <typename T, T... Ints>
|
||||
struct TMakeIntegerSequenceImpl<0, T, Ints...>
|
||||
{
|
||||
using Type = TIntegerSequence<T, Ints...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <size_t... Ints>
|
||||
using TIndexSequence = TIntegerSequence<size_t, Ints...>;
|
||||
|
||||
template <typename T, T N>
|
||||
using TMakeIntegerSequence = typename NAMESPACE_PRIVATE::TMakeIntegerSequenceImpl<N, T>::Type;
|
||||
|
||||
template <size_t N>
|
||||
using TMakeIndexSequence = TMakeIntegerSequence<size_t, N>;
|
||||
|
||||
template <typename... Ts>
|
||||
using TIndexSequenceFor = TMakeIndexSequence<sizeof...(Ts)>;
|
||||
|
||||
template <typename... Ts>
|
||||
struct TTypeSequence { };
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename T > struct TIsTIntegerSequence : FFalse { };
|
||||
template <typename T, T... Ints> struct TIsTIntegerSequence<TIntegerSequence<T, Ints...>> : FTrue { };
|
||||
|
||||
template <typename T > struct TIsTIndexSequence : FFalse { };
|
||||
template <size_t... Ints> struct TIsTIndexSequence<TIndexSequence<Ints...>> : FTrue { };
|
||||
|
||||
template <typename T > struct TIsTTypeSequence : FFalse { };
|
||||
template <typename... Ts> struct TIsTTypeSequence<TTypeSequence<Ts...>> : FTrue { };
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
// Unlike other places such as CTTuple, cv-qualifiers are not ignored here
|
||||
// This is done to simplify the logic and make it easier to use it
|
||||
|
||||
template <typename T>
|
||||
concept CTIntegerSequence = NAMESPACE_PRIVATE::TIsTIntegerSequence<T>::Value;
|
||||
|
||||
template <typename T>
|
||||
concept CTIndexSequence = NAMESPACE_PRIVATE::TIsTIndexSequence<T>::Value;
|
||||
|
||||
template <typename T>
|
||||
concept CTTypeSequence = NAMESPACE_PRIVATE::TIsTTypeSequence<T>::Value;
|
||||
|
||||
NAMESPACE_BEGIN(Meta)
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename TSequence>
|
||||
struct TFrontImpl;
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TFrontImpl<TTypeSequence<T, Ts...>>
|
||||
{
|
||||
using Type = T;
|
||||
};
|
||||
|
||||
template <typename TSequence>
|
||||
struct TPopImpl;
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TPopImpl<TTypeSequence<T, Ts...>>
|
||||
{
|
||||
using Type = TTypeSequence<Ts...>;
|
||||
};
|
||||
|
||||
template <typename T, typename TSequence>
|
||||
struct TPushImpl;
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TPushImpl<T, TTypeSequence<Ts...>>
|
||||
{
|
||||
using Type = TTypeSequence<T, Ts...>;
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <CTTypeSequence TSequence>
|
||||
using TFront = typename NAMESPACE_PRIVATE::TFrontImpl<TSequence>::Type;
|
||||
|
||||
template <CTTypeSequence TSequence>
|
||||
using TPop = typename NAMESPACE_PRIVATE::TPopImpl<TSequence>::Type;
|
||||
|
||||
template <typename T, typename TSequence>
|
||||
using TPush = typename NAMESPACE_PRIVATE::TPushImpl<T, TSequence>::Type;
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename T, typename TSequence>
|
||||
struct TTypeCountImpl
|
||||
{
|
||||
static constexpr size_t Value = (CSameAs<T, TFront<TSequence>> ? 1 : 0) + TTypeCountImpl<T, TPop<TSequence>>::Value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TTypeCountImpl<T, TTypeSequence<>>
|
||||
{
|
||||
static constexpr size_t Value = 0;
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <typename T, CTTypeSequence TSequence>
|
||||
inline constexpr size_t TTypeCount = NAMESPACE_PRIVATE::TTypeCountImpl<T, TSequence>::Value;
|
||||
|
||||
template <typename T, typename TSequence>
|
||||
concept CExistentType = CTTypeSequence<TSequence> && TTypeCount<T, TSequence> > 0;
|
||||
|
||||
template <typename T, typename TSequence>
|
||||
concept CDuplicateType = CTTypeSequence<TSequence> && TTypeCount<T, TSequence> > 1;
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename TSequence>
|
||||
struct TSizeImpl;
|
||||
|
||||
template <typename... Ts>
|
||||
struct TSizeImpl<TTypeSequence<Ts...>>
|
||||
{
|
||||
static constexpr size_t Value = sizeof...(Ts);
|
||||
};
|
||||
|
||||
template <size_t I, typename T, typename TSequence>
|
||||
struct TIndexImpl
|
||||
{
|
||||
static constexpr size_t Value = CSameAs<T, TFront<TSequence>> ? I : TIndexImpl<I + 1, T, TPop<TSequence>>::Value;
|
||||
};
|
||||
|
||||
template <size_t I, typename T>
|
||||
struct TIndexImpl<I, T, TTypeSequence<>>
|
||||
{
|
||||
static constexpr size_t Value = INDEX_NONE;
|
||||
};
|
||||
|
||||
template <typename T, typename TSequence>
|
||||
struct TIndexAssert
|
||||
{
|
||||
static_assert( Meta::CExistentType< T, TSequence>, "T is non-existent types in type sequence");
|
||||
static_assert(!Meta::CDuplicateType<T, TSequence>, "T is duplicate type in type sequence" );
|
||||
static constexpr size_t Value = TIndexImpl<0, T, TSequence>::Value;
|
||||
};
|
||||
|
||||
template <size_t I, typename TSequence>
|
||||
struct TTypeImpl
|
||||
{
|
||||
using Type = typename TTypeImpl<I - 1, TPop<TSequence>>::Type;
|
||||
};
|
||||
|
||||
template <typename TSequence>
|
||||
struct TTypeImpl<0, TSequence>
|
||||
{
|
||||
using Type = TFront<TSequence>;
|
||||
};
|
||||
|
||||
template <typename TSequence>
|
||||
struct TTypeImpl<INDEX_NONE, TSequence>
|
||||
{
|
||||
using Type = void;
|
||||
};
|
||||
|
||||
template <size_t I, typename TSequence>
|
||||
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>;
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <CTTypeSequence TSequence>
|
||||
inline constexpr size_t TSize = NAMESPACE_PRIVATE::TSizeImpl<TSequence>::Value;
|
||||
|
||||
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;
|
||||
|
||||
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>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct TUniqueTypeSequenceImpl<TTypeSequence<>>
|
||||
{
|
||||
using Type = TTypeSequence<>;
|
||||
};
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <CTTypeSequence TSequence>
|
||||
using TUniqueTypeSequence = typename NAMESPACE_PRIVATE::TUniqueTypeSequenceImpl<TSequence>::Type;
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename T>
|
||||
struct TOverload
|
||||
{
|
||||
using F = T(*)(T);
|
||||
operator F() const { return nullptr; }
|
||||
};
|
||||
|
||||
template <typename TSequence>
|
||||
struct TOverloadSetImpl;
|
||||
|
||||
template <typename... Ts>
|
||||
struct TOverloadSetImpl<TTypeSequence<Ts...>> : public TOverload<Ts>... { };
|
||||
|
||||
template <typename TSequence>
|
||||
struct TOverloadSet : public TOverloadSetImpl<TUniqueTypeSequence<TSequence>> { };
|
||||
|
||||
NAMESPACE_PRIVATE_END
|
||||
|
||||
template <typename T, typename TSequence>
|
||||
using TOverloadResolution = decltype(DeclVal<NAMESPACE_PRIVATE::TOverloadSet<TSequence>>()(DeclVal<T>()));
|
||||
|
||||
NAMESPACE_END(Meta)
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
@ -9,7 +9,7 @@
|
||||
#include "Templates/Optional.h"
|
||||
#include "Templates/Variant.h"
|
||||
#include "Templates/Any.h"
|
||||
#include "Templates/IntegerSequence.h"
|
||||
#include "Templates/Meta.h"
|
||||
#include "Templates/Tuple.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "Templates/Function.h"
|
||||
|
@ -1,11 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreTypes.h"
|
||||
#include "Templates/Meta.h"
|
||||
#include "Templates/Invoke.h"
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Templates/IntegerSequence.h"
|
||||
#include "Templates/ReferenceWrapper.h"
|
||||
|
||||
#include <tuple>
|
||||
@ -21,7 +21,7 @@ class TTuple;
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
template <typename T > struct TIsTTuple : FFalse { };
|
||||
template <typename T > struct TIsTTuple : FFalse { };
|
||||
template <typename... Ts> struct TIsTTuple<TTuple<Ts...>> : FTrue { };
|
||||
|
||||
struct FForwardingConstructor { explicit FForwardingConstructor() = default; };
|
||||
@ -34,72 +34,23 @@ template <typename TupleType>
|
||||
struct TTupleArityImpl;
|
||||
|
||||
template <typename... Ts>
|
||||
struct TTupleArityImpl<TTuple<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
|
||||
template <typename... Ts>
|
||||
struct TTupleArityImpl<const TTuple<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
|
||||
template <typename... Ts>
|
||||
struct TTupleArityImpl<volatile TTuple<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
|
||||
template <typename... Ts>
|
||||
struct TTupleArityImpl<const volatile TTuple<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
struct TTupleArityImpl<TTuple<Ts...>> : TConstant<size_t, Meta::TSize<TTypeSequence<Ts...>>> { };
|
||||
|
||||
template <typename T, typename TupleType>
|
||||
struct TTupleIndexImpl;
|
||||
|
||||
template <typename T, typename U, typename... Ts>
|
||||
struct TTupleIndexImpl<T, TTuple<U, Ts...>> : TConstant<size_t, TTupleIndexImpl<T, TTuple<Ts...>>::Value + 1>
|
||||
{
|
||||
static_assert(sizeof...(Ts) != 0, "Non-existent types in tuple");
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TTupleIndexImpl<T, TTuple<T, Ts...>> : TConstant<size_t, 0>
|
||||
{
|
||||
static_assert((true && ... && !CSameAs<T, Ts>), "Duplicate type in tuple");
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TTupleIndexImpl<T, TTuple<>> : TConstant<size_t, INDEX_NONE> { };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TTupleIndexImpl<T, const TTuple<Ts...>> : TTupleIndexImpl<T, TTuple<Ts...>> { };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TTupleIndexImpl<T, volatile TTuple<Ts...>> : TTupleIndexImpl<T, TTuple<Ts...>> { };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TTupleIndexImpl<T, const volatile TTuple<Ts...>> : TTupleIndexImpl<T, TTuple<Ts...>> { };
|
||||
struct TTupleIndexImpl<T, TTuple<Ts...>> : TConstant<size_t, Meta::TIndex<T, TTypeSequence<Ts...>>> { };
|
||||
|
||||
template <size_t I, typename TupleType>
|
||||
struct TTupleElementImpl;
|
||||
|
||||
template <size_t I, typename T, typename... Ts>
|
||||
struct TTupleElementImpl<I, TTuple<T, Ts...>>
|
||||
template <size_t I, typename... Ts>
|
||||
struct TTupleElementImpl<I, TTuple<Ts...>>
|
||||
{
|
||||
static_assert(I < sizeof...(Ts) + 1, "Invalid index in tuple");
|
||||
using Type = TTupleElementImpl<I - 1, TTuple<Ts...>>::Type;
|
||||
using Type = Meta::TType<I, TTypeSequence<Ts...>>;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TTupleElementImpl<0, TTuple<T, Ts...>> { using Type = T; };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TTupleElementImpl<I, TTuple<Ts...>> { };
|
||||
|
||||
template <>
|
||||
struct TTupleElementImpl<0, TTuple<>> { };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TTupleElementImpl<I, const TTuple<Ts...>> { using Type = TAddConst<typename TTupleElementImpl<I, TTuple<Ts...>>::Type>; };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TTupleElementImpl<I, volatile TTuple<Ts...>> { using Type = TAddVolatile<typename TTupleElementImpl<I, TTuple<Ts...>>::Type>; };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TTupleElementImpl<I, const volatile TTuple<Ts...>> { using Type = TAddCV<typename TTupleElementImpl<I, TTuple<Ts...>>::Type>; };
|
||||
|
||||
template <bool bTrue, typename... Ts>
|
||||
struct TTupleConvertCopy : FTrue { };
|
||||
|
||||
@ -247,8 +198,8 @@ public:
|
||||
template <typename LHSTupleType, typename RHSTupleType>
|
||||
static constexpr void Assign(LHSTupleType& LHS, RHSTupleType&& RHS)
|
||||
{
|
||||
static_assert(sizeof...(Indices) == TTupleArityImpl<TRemoveReference<LHSTupleType>>::Value
|
||||
&& TTupleArityImpl<TRemoveReference<LHSTupleType>>::Value == TTupleArityImpl<TRemoveReference<RHSTupleType>>::Value,
|
||||
static_assert(sizeof...(Indices) == TTupleArityImpl<TRemoveCVRef<LHSTupleType>>::Value
|
||||
&& TTupleArityImpl<TRemoveCVRef<LHSTupleType>>::Value == TTupleArityImpl<TRemoveCVRef<RHSTupleType>>::Value,
|
||||
"Cannot assign tuple from different size");
|
||||
|
||||
((LHS.template GetValue<Indices>() = Forward<RHSTupleType>(RHS).template GetValue<Indices>()), ...);
|
||||
@ -292,13 +243,13 @@ template <typename T>
|
||||
concept CTTuple = NAMESPACE_PRIVATE::TIsTTuple<TRemoveCV<T>>::Value;
|
||||
|
||||
template <CTTuple T>
|
||||
inline constexpr size_t TTupleArity = NAMESPACE_PRIVATE::TTupleArityImpl<T>::Value;
|
||||
inline constexpr size_t TTupleArity = NAMESPACE_PRIVATE::TTupleArityImpl<TRemoveCV<T>>::Value;
|
||||
|
||||
template <typename T, CTTuple U>
|
||||
inline constexpr size_t TTupleIndex = NAMESPACE_PRIVATE::TTupleIndexImpl<T, U>::Value;
|
||||
inline constexpr size_t TTupleIndex = NAMESPACE_PRIVATE::TTupleIndexImpl<T, TRemoveCV<U>>::Value;
|
||||
|
||||
template <size_t I, CTTuple U>
|
||||
using TTupleElement = typename NAMESPACE_PRIVATE::TTupleElementImpl<I, U>::Type;
|
||||
using TTupleElement = TCopyCV<U, typename NAMESPACE_PRIVATE::TTupleElementImpl<I, TRemoveCV<U>>::Type>;
|
||||
|
||||
template <typename... Ts>
|
||||
class TTuple : public NAMESPACE_PRIVATE::TTupleImpl<TIndexSequenceFor<Ts...>, Ts...>
|
||||
|
@ -117,6 +117,23 @@ inline constexpr FIgnore Ignore;
|
||||
\
|
||||
}
|
||||
|
||||
// TOverloaded Usage Example
|
||||
//
|
||||
// Visit(TOverloaded {
|
||||
// [](auto A) { ... },
|
||||
// [](double A) { ... },
|
||||
// [](const FString& A) { ... },
|
||||
// }, Target);
|
||||
//
|
||||
template <typename... Ts>
|
||||
struct TOverloaded : Ts...
|
||||
{
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
template <typename... Ts>
|
||||
TOverloaded(Ts...) -> TOverloaded<Ts...>;
|
||||
|
||||
NAMESPACE_MODULE_END(Utility)
|
||||
NAMESPACE_MODULE_END(Redcraft)
|
||||
NAMESPACE_REDCRAFT_END
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "Templates/Utility.h"
|
||||
#include "Templates/TypeHash.h"
|
||||
#include "TypeTraits/TypeTraits.h"
|
||||
#include "Templates/Meta.h"
|
||||
#include "Memory/MemoryOperator.h"
|
||||
#include "Miscellaneous/Compare.h"
|
||||
#include "Miscellaneous/AssertionMacros.h"
|
||||
@ -21,86 +22,27 @@ NAMESPACE_PRIVATE_BEGIN
|
||||
template <typename T > struct TIsTVariant : FFalse { };
|
||||
template <typename... Ts> struct TIsTVariant<TVariant<Ts...>> : FTrue { };
|
||||
|
||||
// This class is to avoid conflicting with sizeof...(Ts) > 0 constraints when using TVariant<> in tool templates
|
||||
template <typename... Ts>
|
||||
struct TVariantProxy { };
|
||||
|
||||
template <typename TupleType>
|
||||
template <typename VariantType>
|
||||
struct TVariantNumImpl;
|
||||
|
||||
template <typename... Ts>
|
||||
struct TVariantNumImpl<TVariant<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
struct TVariantNumImpl<TVariant<Ts...>> : TConstant<size_t, Meta::TSize<TTypeSequence<Ts...>>> { };
|
||||
|
||||
template <typename... Ts>
|
||||
struct TVariantNumImpl<const TVariant<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
|
||||
template <typename... Ts>
|
||||
struct TVariantNumImpl<volatile TVariant<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
|
||||
template <typename... Ts>
|
||||
struct TVariantNumImpl<const volatile TVariant<Ts...>> : TConstant<size_t, sizeof...(Ts)> { };
|
||||
|
||||
template <typename T, typename TupleType>
|
||||
template <typename T, typename VariantType>
|
||||
struct TVariantIndexImpl;
|
||||
|
||||
template <typename T, typename U, typename... Ts>
|
||||
struct TVariantIndexImpl<T, TVariantProxy<U, Ts...>> : TConstant<size_t, TVariantIndexImpl<T, TVariantProxy<Ts...>>::Value + 1>
|
||||
{
|
||||
static_assert(sizeof...(Ts) != 0, "Non-existent types in variant");
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TVariantIndexImpl<T, TVariantProxy<T, Ts...>> : TConstant<size_t, 0>
|
||||
{
|
||||
static_assert((true && ... && !CSameAs<T, Ts>), "Duplicate type in variant");
|
||||
};
|
||||
struct TVariantIndexImpl<T, TVariant<Ts...>> : TConstant<size_t, Meta::TIndex<T, TTypeSequence<Ts...>>> { };
|
||||
|
||||
template <typename T>
|
||||
struct TVariantIndexImpl<T, TVariantProxy<>> : TConstant<size_t, INDEX_NONE> { };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TVariantIndexImpl<T, TVariant<Ts...>> : TVariantIndexImpl<T, TVariantProxy<Ts...>> { };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TVariantIndexImpl<T, const TVariant<Ts...>> : TVariantIndexImpl<T, TVariant<Ts...>> { };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TVariantIndexImpl<T, volatile TVariant<Ts...>> : TVariantIndexImpl<T, TVariant<Ts...>> { };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TVariantIndexImpl<T, const volatile TVariant<Ts...>> : TVariantIndexImpl<T, TVariant<Ts...>> { };
|
||||
|
||||
template <size_t I, typename TupleType>
|
||||
template <size_t I, typename VariantType>
|
||||
struct TVariantAlternativeImpl;
|
||||
|
||||
template <size_t I, typename T, typename... Ts>
|
||||
struct TVariantAlternativeImpl<I, TVariantProxy<T, Ts...>>
|
||||
template <size_t I, typename... Ts>
|
||||
struct TVariantAlternativeImpl<I, TVariant<Ts...>>
|
||||
{
|
||||
static_assert(I < sizeof...(Ts) + 1, "Invalid index in variant");
|
||||
using Type = TVariantAlternativeImpl<I - 1, TVariantProxy<Ts...>>::Type;
|
||||
using Type = Meta::TType<I, TTypeSequence<Ts...>>;
|
||||
};
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TVariantAlternativeImpl<0, TVariantProxy<T, Ts...>> { using Type = T; };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TVariantAlternativeImpl<I, TVariantProxy<Ts...>> { };
|
||||
|
||||
template <>
|
||||
struct TVariantAlternativeImpl<0, TVariantProxy<>> { };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TVariantAlternativeImpl<I, TVariant<Ts...>> : TVariantAlternativeImpl<I, TVariantProxy<Ts...>> { };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TVariantAlternativeImpl<I, const TVariant<Ts...>> { using Type = TAddConst<typename TVariantAlternativeImpl<I, TVariant<Ts...>>::Type>; };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TVariantAlternativeImpl<I, volatile TVariant<Ts...>> { using Type = TAddVolatile<typename TVariantAlternativeImpl<I, TVariant<Ts...>>::Type>; };
|
||||
|
||||
template <size_t I, typename... Ts>
|
||||
struct TVariantAlternativeImpl<I, const volatile TVariant<Ts...>> { using Type = TAddCV<typename TVariantAlternativeImpl<I, TVariant<Ts...>>::Type>; };
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
struct TVariantSelectedType;
|
||||
|
||||
@ -140,13 +82,13 @@ template <typename T>
|
||||
concept CTVariant = NAMESPACE_PRIVATE::TIsTVariant<TRemoveCV<T>>::Value;
|
||||
|
||||
template <CTVariant T>
|
||||
inline constexpr size_t TVariantNum = NAMESPACE_PRIVATE::TVariantNumImpl<T>::Value;
|
||||
inline constexpr size_t TVariantNum = NAMESPACE_PRIVATE::TVariantNumImpl<TRemoveCV<T>>::Value;
|
||||
|
||||
template <typename T, CTVariant U>
|
||||
inline constexpr size_t TVariantIndex = NAMESPACE_PRIVATE::TVariantIndexImpl<T, U>::Value;
|
||||
inline constexpr size_t TVariantIndex = NAMESPACE_PRIVATE::TVariantIndexImpl<T, TRemoveCV<U>>::Value;
|
||||
|
||||
template <size_t I, CTVariant U>
|
||||
using TVariantAlternative = typename NAMESPACE_PRIVATE::TVariantAlternativeImpl<I, U>::Type;
|
||||
using TVariantAlternative = TCopyCV<U, typename NAMESPACE_PRIVATE::TVariantAlternativeImpl<I, TRemoveCV<U>>::Type>;
|
||||
|
||||
template <typename... Ts> requires (sizeof...(Ts) > 0 && (true && ... && CDestructible<Ts>))
|
||||
class TVariant
|
||||
|
@ -16,7 +16,7 @@ NAMESPACE_MODULE_BEGIN(Utility)
|
||||
template <typename T, typename U> struct TBasicCommonType { };
|
||||
|
||||
// The class template is a customization point that allows users to influence the result of TCommonReference for user
|
||||
template <typename T, typename U, template<typename> typename TQualifiers, template<typename> typename UQualifiers> struct TBasicCommonReference { };
|
||||
template <typename T, typename U, template <typename> typename TQualifiers, template <typename> typename UQualifiers> struct TBasicCommonReference { };
|
||||
|
||||
NAMESPACE_PRIVATE_BEGIN
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user