refactor(templates): add sizeof...(Ts) > 0 constraint to TVariant

This commit is contained in:
_Redstone_c_ 2022-11-17 18:48:20 +08:00
parent 3f56a2beca
commit 9a3c957b38

View File

@ -13,14 +13,18 @@ NAMESPACE_REDCRAFT_BEGIN
NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Redcraft)
NAMESPACE_MODULE_BEGIN(Utility) NAMESPACE_MODULE_BEGIN(Utility)
template <typename... Ts> requires (true && ... && CDestructible<Ts>) template <typename... Ts> requires (sizeof...(Ts) > 0 && (true && ... && CDestructible<Ts>))
class TVariant; class TVariant;
NAMESPACE_PRIVATE_BEGIN NAMESPACE_PRIVATE_BEGIN
template <typename T > struct TIsTVariant : FFalse { }; template <typename T > struct TIsTVariant : FFalse { };
template <typename... Ts> struct TIsTVariant<TVariant<Ts...>> : FTrue { }; 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 TupleType>
struct TVariantNumImpl; struct TVariantNumImpl;
@ -40,19 +44,22 @@ template <typename T, typename TupleType>
struct TVariantIndexImpl; struct TVariantIndexImpl;
template <typename T, typename U, typename... Ts> template <typename T, typename U, typename... Ts>
struct TVariantIndexImpl<T, TVariant<U, Ts...>> : TConstant<size_t, TVariantIndexImpl<T, TVariant<Ts...>>::Value + 1> 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"); static_assert(sizeof...(Ts) != 0, "Non-existent types in variant");
}; };
template <typename T, typename... Ts> template <typename T, typename... Ts>
struct TVariantIndexImpl<T, TVariant<T, Ts...>> : TConstant<size_t, 0> struct TVariantIndexImpl<T, TVariantProxy<T, Ts...>> : TConstant<size_t, 0>
{ {
static_assert((true && ... && !CSameAs<T, Ts>), "Duplicate type in variant"); static_assert((true && ... && !CSameAs<T, Ts>), "Duplicate type in variant");
}; };
template <typename T> template <typename T>
struct TVariantIndexImpl<T, TVariant<>> : TConstant<size_t, INDEX_NONE> { }; 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> template <typename T, typename... Ts>
struct TVariantIndexImpl<T, const TVariant<Ts...>> : TVariantIndexImpl<T, TVariant<Ts...>> { }; struct TVariantIndexImpl<T, const TVariant<Ts...>> : TVariantIndexImpl<T, TVariant<Ts...>> { };
@ -67,20 +74,23 @@ template <size_t I, typename TupleType>
struct TVariantAlternativeImpl; struct TVariantAlternativeImpl;
template <size_t I, typename T, typename... Ts> template <size_t I, typename T, typename... Ts>
struct TVariantAlternativeImpl<I, TVariant<T, Ts...>> struct TVariantAlternativeImpl<I, TVariantProxy<T, Ts...>>
{ {
static_assert(I < sizeof...(Ts) + 1, "Invalid index in variant"); static_assert(I < sizeof...(Ts) + 1, "Invalid index in variant");
using Type = TVariantAlternativeImpl<I - 1, TVariant<Ts...>>::Type; using Type = TVariantAlternativeImpl<I - 1, TVariantProxy<Ts...>>::Type;
}; };
template <typename T, typename... Ts> template <typename T, typename... Ts>
struct TVariantAlternativeImpl<0, TVariant<T, Ts...>> { using Type = T; }; struct TVariantAlternativeImpl<0, TVariantProxy<T, Ts...>> { using Type = T; };
template <size_t I, typename... Ts> template <size_t I, typename... Ts>
struct TVariantAlternativeImpl<I, TVariant<Ts...>> { }; struct TVariantAlternativeImpl<I, TVariantProxy<Ts...>> { };
template <> template <>
struct TVariantAlternativeImpl<0, TVariant<>> { }; 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> template <size_t I, typename... Ts>
struct TVariantAlternativeImpl<I, const TVariant<Ts...>> { using Type = TAddConst<typename TVariantAlternativeImpl<I, TVariant<Ts...>>::Type>; }; struct TVariantAlternativeImpl<I, const TVariant<Ts...>> { using Type = TAddConst<typename TVariantAlternativeImpl<I, TVariant<Ts...>>::Type>; };
@ -138,7 +148,7 @@ inline constexpr size_t TVariantIndex = NAMESPACE_PRIVATE::TVariantIndexImpl<T,
template <size_t I, typename VariantType> template <size_t I, typename VariantType>
using TVariantAlternative = typename NAMESPACE_PRIVATE::TVariantAlternativeImpl<I, VariantType>::Type; using TVariantAlternative = typename NAMESPACE_PRIVATE::TVariantAlternativeImpl<I, VariantType>::Type;
template <typename... Ts> requires (true && ... && CDestructible<Ts>) template <typename... Ts> requires (sizeof...(Ts) > 0 && (true && ... && CDestructible<Ts>))
class TVariant class TVariant
{ {
public: public: