diff --git a/Redcraft.Utility/Source/Public/Templates/Variant.h b/Redcraft.Utility/Source/Public/Templates/Variant.h index 92cd43c..9c662e0 100644 --- a/Redcraft.Utility/Source/Public/Templates/Variant.h +++ b/Redcraft.Utility/Source/Public/Templates/Variant.h @@ -37,6 +37,9 @@ struct TVariantAlternativeType template struct TVariantAlternativeType<0, T, Types...> { using Type = T; }; +template <> +struct TVariantAlternativeType<0> { }; + template struct TVariantSelectedType; @@ -46,17 +49,18 @@ struct TVariantSelectedType using TypeAlternativeA = typename TConditional::Value, U, void>::Type; using TypeAlternativeB = typename TVariantSelectedType::Type; - using Type = typename TConditional::Value, TypeAlternativeB, - typename TConditional::Value, TypeAlternativeA, - typename TConditional::Value, TypeAlternativeB, TypeAlternativeA>::Type>::Type>::Type; + using Type = typename TConditional::Type, void>::Value, TypeAlternativeB, + typename TConditional::Type, void>::Value, TypeAlternativeA, + typename TConditional::Type, typename TRemoveCVRef::Type>::Value, TypeAlternativeB, TypeAlternativeA>::Type>::Type>::Type; // 0 - Type not found // 1 - Same type found // 2 - Multiple types found // 3 - The type found - static constexpr uint8 Flag = TIsSame::Value ? 0 : - TIsSame::Value ? 1 : - !TIsSame::Value && !TIsSame::Value ? 2 : 3; + static constexpr uint8 Flag = TIsSame::Type, void>::Value ? 0 : + TIsSame::Type, typename TRemoveCVRef::Type>::Value ? 2 : + TIsSame::Type, typename TRemoveCVRef< T>::Type>::Value ? 1 : + !TIsSame::Type, void>::Value && !TIsSame::Value ? 2 : 3; static constexpr bool Value = Flag & 1; @@ -348,10 +352,10 @@ struct TVariant template requires (TAlternativeIndex::Value != INDEX_NONE) constexpr const T& GetValue() const& { checkf(HoldsAlternative(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast(&Value); } template requires (TAlternativeIndex::Value != INDEX_NONE) constexpr const T&& GetValue() const&& { checkf(HoldsAlternative(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return MoveTemp(*reinterpret_cast(&Value)); } - template requires (I < AlternativeSize) constexpr typename TAlternativeType::Type& Get(typename TAlternativeType::Type& DefaultValue)& { return HoldsAlternative() ? GetValue() : DefaultValue; } + template requires (I < AlternativeSize) constexpr typename TAlternativeType::Type& Get( typename TAlternativeType::Type& DefaultValue) & { return HoldsAlternative() ? GetValue() : DefaultValue; } template requires (I < AlternativeSize) constexpr const typename TAlternativeType::Type& Get(const typename TAlternativeType::Type& DefaultValue) const& { return HoldsAlternative() ? GetValue() : DefaultValue; } - template requires (TAlternativeIndex::Value != INDEX_NONE) constexpr T& Get(T& DefaultValue)& { return HoldsAlternative() ? GetValue() : DefaultValue; } + template requires (TAlternativeIndex::Value != INDEX_NONE) constexpr T& Get(T& DefaultValue)& { return HoldsAlternative() ? GetValue() : DefaultValue; } template requires (TAlternativeIndex::Value != INDEX_NONE) constexpr const T& Get(const T& DefaultValue) const& { return HoldsAlternative() ? GetValue() : DefaultValue; } template requires (true && ... && TIsInvocable::Value) @@ -524,6 +528,9 @@ constexpr void Swap(TVariant& A, TVariant& B) template struct TIsVariantSpecialization : FFalse { }; template struct TIsVariantSpecialization> : FTrue { }; +template requires TIsVariantSpecialization::Type>::Value +struct TVariantAlternativeSize : TConstant { }; + template requires TIsVariantSpecialization::Type>::Value struct TVariantAlternativeType { using Type = typename TCopyCV::Type, typename TRemoveCVRef::Type::template TAlternativeType::Type>::Type; };