fix(templates): fix the type selection of TVariant's converting constructor
This commit is contained in:
parent
01eec5d4c0
commit
797386f3d6
@ -180,8 +180,8 @@ void TestVariant()
|
|||||||
TVariant<int32> TempB(Invalid);
|
TVariant<int32> TempB(Invalid);
|
||||||
TVariant<int32> TempC(InPlaceType<int32>, 0);
|
TVariant<int32> TempC(InPlaceType<int32>, 0);
|
||||||
TVariant<int32> TempD(0);
|
TVariant<int32> TempD(0);
|
||||||
TVariant<int32> TempE(0l);
|
// TVariant<int32> TempE(0ll);
|
||||||
TVariant<int32> TempF(0.0);
|
// TVariant<int32> TempF(0.0);
|
||||||
TVariant<int32> TempG(TempA);
|
TVariant<int32> TempG(TempA);
|
||||||
TVariant<int32> TempH(TempD);
|
TVariant<int32> TempH(TempD);
|
||||||
TVariant<int32> TempI(TVariant<int32>(0));
|
TVariant<int32> TempI(TVariant<int32>(0));
|
||||||
@ -240,7 +240,13 @@ void TestVariant()
|
|||||||
Swap(TempW, TempX);
|
Swap(TempW, TempX);
|
||||||
Swap(TempW, TempX);
|
Swap(TempW, TempX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// TVariant<bool> TempA = false;
|
||||||
|
// TempA.Visit([](auto& A) { A = true; });
|
||||||
|
// always_check(TempA.GetValue<bool>());
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct FTracker
|
struct FTracker
|
||||||
{
|
{
|
||||||
|
@ -43,39 +43,28 @@ struct TVariantAlternativeImpl<I, TVariant<Ts...>>
|
|||||||
using Type = Meta::TType<I, TTypeSequence<Ts...>>;
|
using Type = Meta::TType<I, TTypeSequence<Ts...>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Ts>
|
template <typename T, typename TSequence>
|
||||||
struct TVariantSelectedType;
|
struct TVariantOverloadType
|
||||||
|
|
||||||
template <typename T, typename U, typename... Ts>
|
|
||||||
struct TVariantSelectedType<T, U, Ts...>
|
|
||||||
{
|
{
|
||||||
using TypeAlternativeA = TConditional<CConstructibleFrom<U, T&&>, U, void>;
|
using FrontType = Meta::TFront<TSequence>;
|
||||||
using TypeAlternativeB = typename TVariantSelectedType<T, Ts...>::Type;
|
using NextSequence = Meta::TPop<TSequence>;
|
||||||
|
using NextUniqueSequence = typename TVariantOverloadType<T, NextSequence>::Type;
|
||||||
|
|
||||||
using Type = TConditional<CSameAs<TRemoveCVRef<TypeAlternativeA>, void>, TypeAlternativeB,
|
// T_i x[] = { Forward<T>(t) };
|
||||||
TConditional<CSameAs<TRemoveCVRef<TypeAlternativeB>, void>, TypeAlternativeA,
|
static constexpr bool bConditional = requires { DeclVal<void(FrontType(&&)[1])>()({ DeclVal<T>() }); };
|
||||||
TConditional<CSameAs<TRemoveCVRef<TypeAlternativeB>, TRemoveCVRef<T>>, TypeAlternativeB, TypeAlternativeA>>>;
|
|
||||||
|
|
||||||
// 0 - Type not found
|
|
||||||
// 1 - Same type found
|
|
||||||
// 2 - Multiple types found
|
|
||||||
// 3 - The type found
|
|
||||||
static constexpr uint8 Flag = CSameAs<TRemoveCVRef<Type>, void> ? 0 :
|
|
||||||
CSameAs<TRemoveCVRef<TypeAlternativeA>, TRemoveCVRef<TypeAlternativeB>> ? 2 :
|
|
||||||
CSameAs<TRemoveCVRef< Type>, TRemoveCVRef< T>> ? 1 :
|
|
||||||
!CSameAs<TRemoveCVRef<TypeAlternativeA>, void> && !CSameAs<TypeAlternativeB, void> ? 2 : 3;
|
|
||||||
|
|
||||||
static constexpr bool Value = Flag & 1;
|
|
||||||
|
|
||||||
|
using Type = TConditional<bConditional, Meta::TPush<FrontType, NextUniqueSequence>, NextUniqueSequence>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TVariantSelectedType<T>
|
struct TVariantOverloadType<T, TTypeSequence<>>
|
||||||
{
|
{
|
||||||
static constexpr uint8 Flag = 0;
|
using Type = TTypeSequence<>;
|
||||||
using Type = void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename... Ts>
|
||||||
|
using TVariantSelectedType = Meta::TOverloadResolution<T, typename NAMESPACE_PRIVATE::TVariantOverloadType<T, TTypeSequence<Ts...>>::Type>;
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -129,10 +118,10 @@ public:
|
|||||||
: TVariant(InPlaceIndex<TVariantIndex<T, TVariant<Ts...>>>, Forward<ArgTypes>(Args)...)
|
: TVariant(InPlaceIndex<TVariantIndex<T, TVariant<Ts...>>>, Forward<ArgTypes>(Args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename T> requires (NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Ts...>::Value
|
template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; }
|
||||||
&& !CTInPlaceType<TRemoveCVRef<T>> && !CTInPlaceIndex<TRemoveCVRef<T>>
|
&& !CTInPlaceType<TRemoveCVRef<T>> && !CTInPlaceIndex<TRemoveCVRef<T>>
|
||||||
&& !CBaseOf<TVariant, TRemoveCVRef<T>>)
|
&& !CBaseOf<TVariant, TRemoveCVRef<T>>)
|
||||||
constexpr TVariant(T&& InValue) : TVariant(InPlaceType<typename NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Ts...>::Type>, Forward<T>(InValue))
|
constexpr TVariant(T&& InValue) : TVariant(InPlaceType<NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>>, Forward<T>(InValue))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
constexpr ~TVariant() requires (true && ... && CTriviallyDestructible<Ts>) = default;
|
constexpr ~TVariant() requires (true && ... && CTriviallyDestructible<Ts>) = default;
|
||||||
@ -190,10 +179,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> requires (NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Ts...>::Value)
|
template <typename T> requires (requires { typename NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>; })
|
||||||
constexpr TVariant& operator=(T&& InValue)
|
constexpr TVariant& operator=(T&& InValue)
|
||||||
{
|
{
|
||||||
using SelectedType = typename NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Ts...>::Type;
|
using SelectedType = NAMESPACE_PRIVATE::TVariantSelectedType<T, Ts...>;
|
||||||
|
|
||||||
if (GetIndex() == TVariantIndex<SelectedType, TVariant<Ts...>>) GetValue<SelectedType>() = Forward<T>(InValue);
|
if (GetIndex() == TVariantIndex<SelectedType, TVariant<Ts...>>) GetValue<SelectedType>() = Forward<T>(InValue);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user