feat(templates): add TTypeSequence and meta tools

This commit is contained in:
2022-12-03 23:11:05 +08:00
parent c4c1430e46
commit 01eec5d4c0
8 changed files with 325 additions and 201 deletions

View File

@ -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