diff --git a/Redcraft.Utility/Source/Public/Templates/Variant.h b/Redcraft.Utility/Source/Public/Templates/Variant.h index fe953f9..1650ecb 100644 --- a/Redcraft.Utility/Source/Public/Templates/Variant.h +++ b/Redcraft.Utility/Source/Public/Templates/Variant.h @@ -13,14 +13,18 @@ NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) -template requires (true && ... && CDestructible) +template requires (sizeof...(Ts) > 0 && (true && ... && CDestructible)) class TVariant; NAMESPACE_PRIVATE_BEGIN -template struct TIsTVariant : FFalse { }; +template struct TIsTVariant : FFalse { }; template struct TIsTVariant> : FTrue { }; +// This class is to avoid conflicting with sizeof...(Ts) > 0 constraints when using TVariant<> in tool templates +template +struct TVariantProxy { }; + template struct TVariantNumImpl; @@ -40,19 +44,22 @@ template struct TVariantIndexImpl; template -struct TVariantIndexImpl> : TConstant>::Value + 1> +struct TVariantIndexImpl> : TConstant>::Value + 1> { static_assert(sizeof...(Ts) != 0, "Non-existent types in variant"); }; template -struct TVariantIndexImpl> : TConstant +struct TVariantIndexImpl> : TConstant { static_assert((true && ... && !CSameAs), "Duplicate type in variant"); }; template -struct TVariantIndexImpl> : TConstant { }; +struct TVariantIndexImpl> : TConstant { }; + +template +struct TVariantIndexImpl> : TVariantIndexImpl> { }; template struct TVariantIndexImpl> : TVariantIndexImpl> { }; @@ -67,20 +74,23 @@ template struct TVariantAlternativeImpl; template -struct TVariantAlternativeImpl> +struct TVariantAlternativeImpl> { static_assert(I < sizeof...(Ts) + 1, "Invalid index in variant"); - using Type = TVariantAlternativeImpl>::Type; + using Type = TVariantAlternativeImpl>::Type; }; template -struct TVariantAlternativeImpl<0, TVariant> { using Type = T; }; +struct TVariantAlternativeImpl<0, TVariantProxy> { using Type = T; }; template -struct TVariantAlternativeImpl> { }; +struct TVariantAlternativeImpl> { }; template <> -struct TVariantAlternativeImpl<0, TVariant<>> { }; +struct TVariantAlternativeImpl<0, TVariantProxy<>> { }; + +template +struct TVariantAlternativeImpl> : TVariantAlternativeImpl> { }; template struct TVariantAlternativeImpl> { using Type = TAddConst>::Type>; }; @@ -138,7 +148,7 @@ inline constexpr size_t TVariantIndex = NAMESPACE_PRIVATE::TVariantIndexImpl using TVariantAlternative = typename NAMESPACE_PRIVATE::TVariantAlternativeImpl::Type; -template requires (true && ... && CDestructible) +template requires (sizeof...(Ts) > 0 && (true && ... && CDestructible)) class TVariant { public: