refactor(*): replaces template class type traits with C++20 at all
This commit is contained in:
parent
8e31a82a1f
commit
f1d4d99ecf
@ -188,9 +188,9 @@ void TestCompare()
|
|||||||
always_check((FTestStrongOrdering( 0) == FTestStrongOrdering( 0)));
|
always_check((FTestStrongOrdering( 0) == FTestStrongOrdering( 0)));
|
||||||
always_check((FTestStrongOrdering( 0) > FTestStrongOrdering(-1)));
|
always_check((FTestStrongOrdering( 0) > FTestStrongOrdering(-1)));
|
||||||
|
|
||||||
always_check((CSameAs<TCommonComparisonCategory<strong_ordering >::Type, strong_ordering >));
|
always_check((CSameAs<TCommonComparisonCategory<strong_ordering >, strong_ordering >));
|
||||||
always_check((CSameAs<TCommonComparisonCategory<strong_ordering, weak_ordering >::Type, weak_ordering >));
|
always_check((CSameAs<TCommonComparisonCategory<strong_ordering, weak_ordering >, weak_ordering >));
|
||||||
always_check((CSameAs<TCommonComparisonCategory<strong_ordering, weak_ordering, partial_ordering>::Type, partial_ordering>));
|
always_check((CSameAs<TCommonComparisonCategory<strong_ordering, weak_ordering, partial_ordering>, partial_ordering>));
|
||||||
|
|
||||||
always_check(CThreeWayComparable<int32>);
|
always_check(CThreeWayComparable<int32>);
|
||||||
always_check(CThreeWayComparable<FTestPartialOrdering>);
|
always_check(CThreeWayComparable<FTestPartialOrdering>);
|
||||||
@ -200,11 +200,11 @@ void TestCompare()
|
|||||||
always_check((CThreeWayComparable<bool, bool>));
|
always_check((CThreeWayComparable<bool, bool>));
|
||||||
always_check((CThreeWayComparable<int16, int32>));
|
always_check((CThreeWayComparable<int16, int32>));
|
||||||
|
|
||||||
always_check((CSameAs<TCompareThreeWayResult<int32 >::Type, strong_ordering >));
|
always_check((CSameAs<TCompareThreeWayResult<int32 >, strong_ordering >));
|
||||||
always_check((CSameAs<TCompareThreeWayResult<float >::Type, partial_ordering>));
|
always_check((CSameAs<TCompareThreeWayResult<float >, partial_ordering>));
|
||||||
always_check((CSameAs<TCompareThreeWayResult<FTestPartialOrdering>::Type, partial_ordering>));
|
always_check((CSameAs<TCompareThreeWayResult<FTestPartialOrdering>, partial_ordering>));
|
||||||
always_check((CSameAs<TCompareThreeWayResult<FTestWeakOrdering >::Type, weak_ordering >));
|
always_check((CSameAs<TCompareThreeWayResult<FTestWeakOrdering >, weak_ordering >));
|
||||||
always_check((CSameAs<TCompareThreeWayResult<FTestStrongOrdering >::Type, strong_ordering >));
|
always_check((CSameAs<TCompareThreeWayResult<FTestStrongOrdering >, strong_ordering >));
|
||||||
|
|
||||||
always_check((SynthThreeWayCompare(0, 0) == strong_ordering::equal));
|
always_check((SynthThreeWayCompare(0, 0) == strong_ordering::equal));
|
||||||
always_check((SynthThreeWayCompare(0, 0.0) == strong_ordering::equal));
|
always_check((SynthThreeWayCompare(0, 0.0) == strong_ordering::equal));
|
||||||
|
@ -79,8 +79,8 @@ void TestReferenceWrapper()
|
|||||||
always_check(ArrayA[1] == 4);
|
always_check(ArrayA[1] == 4);
|
||||||
always_check(ArrayA[2] == 6);
|
always_check(ArrayA[2] == 6);
|
||||||
|
|
||||||
always_check((CSameAs<int32, TUnwrapRefDecay<int32>::Type>));
|
always_check((CSameAs<int32, TUnwrapRefDecay<int32>>));
|
||||||
always_check((CSameAs<int32&, TUnwrapRefDecay<TReferenceWrapper<int32>>::Type>));
|
always_check((CSameAs<int32&, TUnwrapRefDecay<TReferenceWrapper<int32>>>));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestOptional()
|
void TestOptional()
|
||||||
@ -255,12 +255,12 @@ void TestVariant()
|
|||||||
TempZ = TVariant<FTracker>();
|
TempZ = TVariant<FTracker>();
|
||||||
TempZ = FTracker();
|
TempZ = FTracker();
|
||||||
|
|
||||||
always_check((CSameAs<int32, TVariantAlternativeType<0, TVariant<int32, float>>::Type>));
|
always_check((CSameAs<int32, TVariantAlternative<0, TVariant<int32, float>>>));
|
||||||
always_check((CSameAs<float, TVariantAlternativeType<1, TVariant<int32, float>>::Type>));
|
always_check((CSameAs<float, TVariantAlternative<1, TVariant<int32, float>>>));
|
||||||
always_check((CSameAs<const int32, TVariantAlternativeType<0, const TVariant<int32, float>>::Type>));
|
always_check((CSameAs<const int32, TVariantAlternative<0, const TVariant<int32, float>>>));
|
||||||
|
|
||||||
always_check((TVariantAlternativeIndex<int32, TVariant<int32, float>>::Value == 0));
|
always_check((TVariantIndex<int32, TVariant<int32, float>> == 0));
|
||||||
always_check((TVariantAlternativeIndex<float, TVariant<int32, float>>::Value == 1));
|
always_check((TVariantIndex<float, TVariant<int32, float>> == 1));
|
||||||
|
|
||||||
bool bIsConst;
|
bool bIsConst;
|
||||||
bool bIsLValue;
|
bool bIsLValue;
|
||||||
@ -686,39 +686,37 @@ void TestTuple()
|
|||||||
always_check((CSameAs<decltype(DeclVal<const volatile TTuple< volatile int32&&, char>&&>().GetValue<0>()), volatile int32&&>));
|
always_check((CSameAs<decltype(DeclVal<const volatile TTuple< volatile int32&&, char>&&>().GetValue<0>()), volatile int32&&>));
|
||||||
always_check((CSameAs<decltype(DeclVal<const volatile TTuple<const volatile int32&&, char>&&>().GetValue<0>()), const volatile int32&&>));
|
always_check((CSameAs<decltype(DeclVal<const volatile TTuple<const volatile int32&&, char>&&>().GetValue<0>()), const volatile int32&&>));
|
||||||
|
|
||||||
always_check((CSameAs<TTupleElementType<0, TTuple<double, float&, char&&>>::Type, double>));
|
always_check((CSameAs<TTupleElement<0, TTuple<double, float&, char&&>>, double>));
|
||||||
always_check((CSameAs<TTupleElementType<1, TTuple<double, float&, char&&>>::Type, float&>));
|
always_check((CSameAs<TTupleElement<1, TTuple<double, float&, char&&>>, float&>));
|
||||||
always_check((CSameAs<TTupleElementType<2, TTuple<double, float&, char&&>>::Type, char&&>));
|
always_check((CSameAs<TTupleElement<2, TTuple<double, float&, char&&>>, char&&>));
|
||||||
always_check((CSameAs<TTupleElementType<0, const TTuple<double, float&, char&&>>::Type, const double>));
|
always_check((CSameAs<TTupleElement<0, const TTuple<double, float&, char&&>>, const double>));
|
||||||
always_check((CSameAs<TTupleElementType<1, const TTuple<double, float&, char&&>>::Type, const float&>));
|
always_check((CSameAs<TTupleElement<1, const TTuple<double, float&, char&&>>, float&>));
|
||||||
always_check((CSameAs<TTupleElementType<2, const TTuple<double, float&, char&&>>::Type, const char&&>));
|
always_check((CSameAs<TTupleElement<2, const TTuple<double, float&, char&&>>, char&&>));
|
||||||
always_check((CSameAs<TTupleElementType<0, volatile TTuple<double, float&, char&&>>::Type, volatile double>));
|
always_check((CSameAs<TTupleElement<0, volatile TTuple<double, float&, char&&>>, volatile double>));
|
||||||
always_check((CSameAs<TTupleElementType<1, volatile TTuple<double, float&, char&&>>::Type, volatile float&>));
|
always_check((CSameAs<TTupleElement<1, volatile TTuple<double, float&, char&&>>, float&>));
|
||||||
always_check((CSameAs<TTupleElementType<2, volatile TTuple<double, float&, char&&>>::Type, volatile char&&>));
|
always_check((CSameAs<TTupleElement<2, volatile TTuple<double, float&, char&&>>, char&&>));
|
||||||
always_check((CSameAs<TTupleElementType<0, const volatile TTuple<double, float&, char&&>>::Type, const volatile double>));
|
always_check((CSameAs<TTupleElement<0, const volatile TTuple<double, float&, char&&>>, const volatile double>));
|
||||||
always_check((CSameAs<TTupleElementType<1, const volatile TTuple<double, float&, char&&>>::Type, const volatile float&>));
|
always_check((CSameAs<TTupleElement<1, const volatile TTuple<double, float&, char&&>>, float&>));
|
||||||
always_check((CSameAs<TTupleElementType<2, const volatile TTuple<double, float&, char&&>>::Type, const volatile char&&>));
|
always_check((CSameAs<TTupleElement<2, const volatile TTuple<double, float&, char&&>>, char&&>));
|
||||||
|
|
||||||
always_check((TTupleElementIndex<double, TTuple<double, float&, char&&>>::Value == 0));
|
always_check((TTupleIndex<double, TTuple<double, float&, char&&>> == 0));
|
||||||
always_check((TTupleElementIndex<float&, TTuple<double, float&, char&&>>::Value == 1));
|
always_check((TTupleIndex<float&, TTuple<double, float&, char&&>> == 1));
|
||||||
always_check((TTupleElementIndex<char&&, TTuple<double, float&, char&&>>::Value == 2));
|
always_check((TTupleIndex<char&&, TTuple<double, float&, char&&>> == 2));
|
||||||
always_check((TTupleElementIndex<double, const TTuple<double, float&, char&&>>::Value == 0));
|
always_check((TTupleIndex<double, const TTuple<double, float&, char&&>> == 0));
|
||||||
always_check((TTupleElementIndex<float&, const TTuple<double, float&, char&&>>::Value == 1));
|
always_check((TTupleIndex<float&, const TTuple<double, float&, char&&>> == 1));
|
||||||
always_check((TTupleElementIndex<char&&, const TTuple<double, float&, char&&>>::Value == 2));
|
always_check((TTupleIndex<char&&, const TTuple<double, float&, char&&>> == 2));
|
||||||
always_check((TTupleElementIndex<double, volatile TTuple<double, float&, char&&>>::Value == 0));
|
always_check((TTupleIndex<double, volatile TTuple<double, float&, char&&>> == 0));
|
||||||
always_check((TTupleElementIndex<float&, volatile TTuple<double, float&, char&&>>::Value == 1));
|
always_check((TTupleIndex<float&, volatile TTuple<double, float&, char&&>> == 1));
|
||||||
always_check((TTupleElementIndex<char&&, volatile TTuple<double, float&, char&&>>::Value == 2));
|
always_check((TTupleIndex<char&&, volatile TTuple<double, float&, char&&>> == 2));
|
||||||
always_check((TTupleElementIndex<double, const volatile TTuple<double, float&, char&&>>::Value == 0));
|
always_check((TTupleIndex<double, const volatile TTuple<double, float&, char&&>> == 0));
|
||||||
always_check((TTupleElementIndex<float&, const volatile TTuple<double, float&, char&&>>::Value == 1));
|
always_check((TTupleIndex<float&, const volatile TTuple<double, float&, char&&>> == 1));
|
||||||
always_check((TTupleElementIndex<char&&, const volatile TTuple<double, float&, char&&>>::Value == 2));
|
always_check((TTupleIndex<char&&, const volatile TTuple<double, float&, char&&>> == 2));
|
||||||
|
|
||||||
always_check((TTupleElementIndex<int32, TTuple<double, float&, char&&>>::Value == INDEX_NONE));
|
// always_check((CSameAs<TTupleElement<0, int32>, double>));
|
||||||
|
|
||||||
// always_check((CSameAs<TTupleElementType<0, int32>::Type, double>));
|
// always_check((TTupleIndex<int32, int32> == 0));
|
||||||
|
|
||||||
// always_check((TTupleElementIndex<int32, int32>::Value == 0));
|
// always_check((CSameAs<TTupleElement<4, TTuple<double, float&, char&&>>, double>));
|
||||||
|
|
||||||
// always_check((CSameAs<TTupleElementType<4, TTuple<double, float&, char&&>>::Type, double>));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
using Type = TTuple<int8, uint8, int16, uint16, int32, uint32, int64, uint64, int8, uint8, int16, uint16, int32, uint32, int64, uint64,
|
using Type = TTuple<int8, uint8, int16, uint16, int32, uint32, int64, uint64, int8, uint8, int16, uint16, int32, uint32, int64, uint64,
|
||||||
@ -802,7 +800,7 @@ void TestTuple()
|
|||||||
always_check(TempE.GetValue<double>() == 3.14);
|
always_check(TempE.GetValue<double>() == 3.14);
|
||||||
always_check(TempE.GetValue<float>() == 1.42f);
|
always_check(TempE.GetValue<float>() == 1.42f);
|
||||||
always_check((CSameAs<decltype(TempE), TTuple<int32, FTracker, double, FTracker, float, FTracker>>));
|
always_check((CSameAs<decltype(TempE), TTuple<int32, FTracker, double, FTracker, float, FTracker>>));
|
||||||
always_check((CSameAs<decltype(TempE), typename TTupleCatResult<TTuple<int32, FTracker>, TTuple<double, FTracker>, TTuple<float, FTracker>>::Type>));
|
always_check((CSameAs<decltype(TempE), TTupleCatResult<TTuple<int32, FTracker>, TTuple<double, FTracker>, TTuple<float, FTracker>>>));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -827,7 +825,7 @@ void TestTuple()
|
|||||||
always_check(TempG.GetValue<0>() == 10);
|
always_check(TempG.GetValue<0>() == 10);
|
||||||
always_check(TempG.GetValue<2>() == 10);
|
always_check(TempG.GetValue<2>() == 10);
|
||||||
always_check((CSameAs<decltype(TempG), TTuple<int32, double&, int16&, FTracker&&>>));
|
always_check((CSameAs<decltype(TempG), TTuple<int32, double&, int16&, FTracker&&>>));
|
||||||
always_check((CSameAs<decltype(TempG), typename TTupleCatResult<TTuple<int32, double&>, TTuple<int16&, FTracker&&>>::Type>));
|
always_check((CSameAs<decltype(TempG), TTupleCatResult<TTuple<int32, double&>, TTuple<int16&, FTracker&&>>>));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -301,13 +301,13 @@ void TestTypeTraits()
|
|||||||
|
|
||||||
// Miscellaneous.h
|
// Miscellaneous.h
|
||||||
|
|
||||||
always_check(ArrayRank<int32[1][2][3]> == 3);
|
always_check(TRank<int32[1][2][3]> == 3);
|
||||||
always_check(ArrayRank<int32[1][2][3][4]> == 4);
|
always_check(TRank<int32[1][2][3][4]> == 4);
|
||||||
always_check(ArrayRank<int32> == 0);
|
always_check(TRank<int32> == 0);
|
||||||
|
|
||||||
always_check(ArrayExtent<int32[1][2][3]> == 1);
|
always_check(TExtent<int32[1][2][3]> == 1);
|
||||||
always_check((ArrayExtent<int32[1][2][3][4], 1> == 2));
|
always_check((TExtent<int32[1][2][3][4], 1> == 2));
|
||||||
always_check(ArrayExtent<int32[]> == 0);
|
always_check(TExtent<int32[]> == 0);
|
||||||
|
|
||||||
always_check(!(CSameAs<int32, int64>));
|
always_check(!(CSameAs<int32, int64>));
|
||||||
always_check((CSameAs<int32, int32>));
|
always_check((CSameAs<int32, int32>));
|
||||||
|
@ -18,17 +18,15 @@ typedef NAMESPACE_STD::strong_ordering strong_ordering;
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
template<int32> struct TCommonComparisonCategory { using Type = void; };
|
template<int32> struct TCommonComparisonCategoryBasic { };
|
||||||
template<> struct TCommonComparisonCategory<0> { using Type = strong_ordering; };
|
template<> struct TCommonComparisonCategoryBasic<0> { using Type = strong_ordering; };
|
||||||
template<> struct TCommonComparisonCategory<2> { using Type = partial_ordering; };
|
template<> struct TCommonComparisonCategoryBasic<2> { using Type = partial_ordering; };
|
||||||
template<> struct TCommonComparisonCategory<4> { using Type = weak_ordering; };
|
template<> struct TCommonComparisonCategoryBasic<4> { using Type = weak_ordering; };
|
||||||
template<> struct TCommonComparisonCategory<6> { using Type = partial_ordering; };
|
template<> struct TCommonComparisonCategoryBasic<6> { using Type = partial_ordering; };
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
|
||||||
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
struct TCommonComparisonCategory
|
struct TCommonComparisonCategoryImpl
|
||||||
: NAMESPACE_PRIVATE::TCommonComparisonCategory<(0u | ... |
|
: TCommonComparisonCategoryBasic <(0u | ... |
|
||||||
(
|
(
|
||||||
CSameAs<Types, strong_ordering > ? 0u :
|
CSameAs<Types, strong_ordering > ? 0u :
|
||||||
CSameAs<Types, weak_ordering > ? 4u :
|
CSameAs<Types, weak_ordering > ? 4u :
|
||||||
@ -37,8 +35,13 @@ struct TCommonComparisonCategory
|
|||||||
)>
|
)>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
using TCommonComparisonCategory = typename NAMESPACE_PRIVATE::TCommonComparisonCategoryImpl<Types...>::Type;
|
||||||
|
|
||||||
template <typename T, typename OrderingType>
|
template <typename T, typename OrderingType>
|
||||||
concept CThreeWayComparesAs = CSameAs<typename TCommonComparisonCategory<T, OrderingType>::Type, OrderingType>;
|
concept CThreeWayComparesAs = CSameAs<TCommonComparisonCategory<T, OrderingType>, OrderingType>;
|
||||||
|
|
||||||
template <typename T, typename U = T, typename OrderingType = partial_ordering>
|
template <typename T, typename U = T, typename OrderingType = partial_ordering>
|
||||||
concept CThreeWayComparable = CWeaklyEqualityComparable<T, U> && CPartiallyOrdered<T, U>
|
concept CThreeWayComparable = CWeaklyEqualityComparable<T, U> && CPartiallyOrdered<T, U>
|
||||||
@ -54,10 +57,7 @@ concept CThreeWayComparable = CWeaklyEqualityComparable<T, U> && CPartiallyOrder
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename U = T> requires CThreeWayComparable<T, U>
|
template <typename T, typename U = T> requires CThreeWayComparable<T, U>
|
||||||
struct TCompareThreeWayResult
|
using TCompareThreeWayResult = decltype(DeclVal<const TRemoveReference<T>&>() <=> DeclVal<const TRemoveReference<U>&>());
|
||||||
{
|
|
||||||
using Type = decltype(DeclVal<const TRemoveReference<T>&>() <=> DeclVal<const TRemoveReference<U>&>());
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename U = T, typename OrderingType = partial_ordering>
|
template <typename T, typename U = T, typename OrderingType = partial_ordering>
|
||||||
concept CSynthThreeWayComparable = CThreeWayComparable<T, U> || CTotallyOrdered<T, U>;
|
concept CSynthThreeWayComparable = CThreeWayComparable<T, U> || CTotallyOrdered<T, U>;
|
||||||
@ -75,11 +75,8 @@ constexpr decltype(auto) SynthThreeWayCompare(T&& LHS, U&& RHS)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U = T>
|
template <typename T, typename U = T> requires CSynthThreeWayComparable<T, U>
|
||||||
struct TSynthThreeWayResult
|
using TSynthThreeWayResult = decltype(SynthThreeWayCompare(DeclVal<const TRemoveReference<T>&>(), DeclVal<const TRemoveReference<U>&>()));
|
||||||
{
|
|
||||||
using Type = decltype(SynthThreeWayCompare(DeclVal<const TRemoveReference<T>&>(), DeclVal<const TRemoveReference<U>&>()));
|
|
||||||
};
|
|
||||||
|
|
||||||
NAMESPACE_MODULE_END(Utility)
|
NAMESPACE_MODULE_END(Utility)
|
||||||
NAMESPACE_MODULE_END(Redcraft)
|
NAMESPACE_MODULE_END(Redcraft)
|
||||||
|
@ -437,7 +437,8 @@ template <size_t InlineSize, size_t InlineAlignment> struct TIsTAny<TAny<InlineS
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
template <typename T> concept CTAny = NAMESPACE_PRIVATE::TIsTAny<T>::Value;
|
template <typename T>
|
||||||
|
concept CTAny = NAMESPACE_PRIVATE::TIsTAny<T>::Value;
|
||||||
|
|
||||||
using FAny = TAny<ANY_DEFAULT_INLINE_SIZE>;
|
using FAny = TAny<ANY_DEFAULT_INLINE_SIZE>;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ NAMESPACE_PRIVATE_BEGIN
|
|||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
template <unsigned N, typename T>
|
template <unsigned N, typename T>
|
||||||
struct TMakeIntegerSequence
|
struct TMakeIntegerSequenceImpl
|
||||||
{
|
{
|
||||||
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
||||||
};
|
};
|
||||||
@ -26,7 +26,7 @@ struct TMakeIntegerSequence
|
|||||||
#elif __has_builtin(__make_integer_seq)
|
#elif __has_builtin(__make_integer_seq)
|
||||||
|
|
||||||
template <unsigned N, typename T>
|
template <unsigned N, typename T>
|
||||||
struct TMakeIntegerSequence
|
struct TMakeIntegerSequenceImpl
|
||||||
{
|
{
|
||||||
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
using Type = typename __make_integer_seq<TIntegerSequence, T, N>;
|
||||||
};
|
};
|
||||||
@ -34,13 +34,13 @@ struct TMakeIntegerSequence
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
template <unsigned N, typename T, T... Ints>
|
template <unsigned N, typename T, T... Ints>
|
||||||
struct TMakeIntegerSequence
|
struct TMakeIntegerSequenceImpl
|
||||||
{
|
{
|
||||||
using Type = typename TMakeIntegerSequence<N - 1, T, T(N - 1), Ints...>::Type;
|
using Type = typename TMakeIntegerSequenceImpl<N - 1, T, T(N - 1), Ints...>::Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, T... Ints>
|
template <typename T, T... Ints>
|
||||||
struct TMakeIntegerSequence<0, T, Ints...>
|
struct TMakeIntegerSequenceImpl<0, T, Ints...>
|
||||||
{
|
{
|
||||||
using Type = TIntegerSequence<T, Ints...>;
|
using Type = TIntegerSequence<T, Ints...>;
|
||||||
};
|
};
|
||||||
@ -53,7 +53,7 @@ template <size_t... Ints>
|
|||||||
using TIndexSequence = TIntegerSequence<size_t, Ints...>;
|
using TIndexSequence = TIntegerSequence<size_t, Ints...>;
|
||||||
|
|
||||||
template<typename T, T N>
|
template<typename T, T N>
|
||||||
using TMakeIntegerSequence = typename NAMESPACE_PRIVATE::TMakeIntegerSequence<N, T>::Type;
|
using TMakeIntegerSequence = typename NAMESPACE_PRIVATE::TMakeIntegerSequenceImpl<N, T>::Type;
|
||||||
|
|
||||||
template<size_t N>
|
template<size_t N>
|
||||||
using TMakeIndexSequence = TMakeIntegerSequence<size_t, N>;
|
using TMakeIndexSequence = TMakeIntegerSequence<size_t, N>;
|
||||||
|
@ -124,7 +124,8 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&> && CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value
|
template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&>
|
||||||
|
&& CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value
|
||||||
constexpr TOptional& operator=(const TOptional<T>& InValue)
|
constexpr TOptional& operator=(const TOptional<T>& InValue)
|
||||||
{
|
{
|
||||||
if (!InValue.IsValid())
|
if (!InValue.IsValid())
|
||||||
@ -143,7 +144,8 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&> && CAssignableFrom<OptionalType&, T&&> && TAllowUnwrapping<T>::Value
|
template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, T&&>
|
||||||
|
&& CAssignableFrom<OptionalType&, T&&> && TAllowUnwrapping<T>::Value
|
||||||
constexpr TOptional& operator=(TOptional<T>&& InValue)
|
constexpr TOptional& operator=(TOptional<T>&& InValue)
|
||||||
{
|
{
|
||||||
if (!InValue.IsValid())
|
if (!InValue.IsValid())
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
constexpr ReferencedType& Get() const { return *Pointer; }
|
constexpr ReferencedType& Get() const { return *Pointer; }
|
||||||
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
constexpr TInvokeResult<ReferencedType&, Types...>::Type operator()(Types&&... Args) const
|
constexpr TInvokeResult<ReferencedType&, Types...> operator()(Types&&... Args) const
|
||||||
{
|
{
|
||||||
return Invoke(Get(), Forward<Types>(Args)...);
|
return Invoke(Get(), Forward<Types>(Args)...);
|
||||||
}
|
}
|
||||||
@ -101,17 +101,24 @@ constexpr TReferenceWrapper<const T> Ref(TReferenceWrapper<T> InValue)
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
template <typename T> struct TIsTReferenceWrapper : FFalse { };
|
template <typename T> struct TIsTReferenceWrapperImpl : FFalse { };
|
||||||
template <typename T> struct TIsTReferenceWrapper<TReferenceWrapper<T>> : FTrue { };
|
template <typename T> struct TIsTReferenceWrapperImpl<TReferenceWrapper<T>> : FTrue { };
|
||||||
|
|
||||||
|
template <typename T> struct TUnwrapReferenceImpl { using Type = T; };
|
||||||
|
template <typename T> struct TUnwrapReferenceImpl<TReferenceWrapper<T>> { using Type = T&; };
|
||||||
|
|
||||||
|
template <typename T> struct TUnwrapRefDecayImpl { using Type = typename TUnwrapReferenceImpl<TDecay<T>>::Type; };
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
template <typename T> concept CTReferenceWrapper = NAMESPACE_PRIVATE::TIsTReferenceWrapper<T>::Value;
|
template <typename T>
|
||||||
|
concept CTReferenceWrapper = NAMESPACE_PRIVATE::TIsTReferenceWrapperImpl<T>::Value;
|
||||||
|
|
||||||
template <typename T> struct TUnwrapReference { using Type = T; };
|
template <typename T>
|
||||||
template <typename T> struct TUnwrapReference<TReferenceWrapper<T>> { using Type = T&; };
|
using TUnwrapReference = typename NAMESPACE_PRIVATE::TUnwrapReferenceImpl<T>::Type;
|
||||||
|
|
||||||
template <typename T> struct TUnwrapRefDecay { using Type = typename TUnwrapReference<TDecay<T>>::Type; };
|
template <typename T>
|
||||||
|
using TUnwrapRefDecay = typename NAMESPACE_PRIVATE::TUnwrapRefDecayImpl<T>::Type;
|
||||||
|
|
||||||
template <typename ReferencedType>
|
template <typename ReferencedType>
|
||||||
struct TOptional<TReferenceWrapper<ReferencedType>>
|
struct TOptional<TReferenceWrapper<ReferencedType>>
|
||||||
@ -168,7 +175,8 @@ public:
|
|||||||
TOptional& operator=(const TOptional& InValue) = default;
|
TOptional& operator=(const TOptional& InValue) = default;
|
||||||
TOptional& operator=(TOptional&& InValue) = default;
|
TOptional& operator=(TOptional&& InValue) = default;
|
||||||
|
|
||||||
template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&> && CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value
|
template <typename T = OptionalType> requires CConstructibleFrom<OptionalType, const T&>
|
||||||
|
&& CAssignableFrom<OptionalType&, const T&> && TAllowUnwrapping<T>::Value
|
||||||
constexpr TOptional& operator=(const TOptional<T>& InValue)
|
constexpr TOptional& operator=(const TOptional<T>& InValue)
|
||||||
{
|
{
|
||||||
Reference = InValue.Reference;
|
Reference = InValue.Reference;
|
||||||
|
@ -21,42 +21,107 @@ struct TTuple;
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
|
template <typename T > struct TIsTTuple : FFalse { };
|
||||||
|
template <typename... Types> struct TIsTTuple<TTuple<Types...>> : FTrue { };
|
||||||
|
|
||||||
struct FForwardingConstructor { explicit FForwardingConstructor() = default; };
|
struct FForwardingConstructor { explicit FForwardingConstructor() = default; };
|
||||||
struct FOtherTupleConstructor { explicit FOtherTupleConstructor() = default; };
|
struct FOtherTupleConstructor { explicit FOtherTupleConstructor() = default; };
|
||||||
|
|
||||||
inline constexpr FForwardingConstructor ForwardingConstructor{ };
|
inline constexpr FForwardingConstructor ForwardingConstructor{ };
|
||||||
inline constexpr FOtherTupleConstructor OtherTupleConstructor{ };
|
inline constexpr FOtherTupleConstructor OtherTupleConstructor{ };
|
||||||
|
|
||||||
template <typename T, typename... Types>
|
template <typename TupleType>
|
||||||
struct TTupleElementIndex;
|
struct TTupleArityImpl;
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TTupleArityImpl<TTuple<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TTupleArityImpl<const TTuple<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TTupleArityImpl<volatile TTuple<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TTupleArityImpl<const volatile TTuple<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename T, typename TupleType>
|
||||||
|
struct TTupleIndexImpl;
|
||||||
|
|
||||||
template <typename T, typename U, typename... Types>
|
template <typename T, typename U, typename... Types>
|
||||||
struct TTupleElementIndex<T, U, Types...>
|
struct TTupleIndexImpl<T, TTuple<U, Types...>> : TConstant<size_t, TTupleIndexImpl<T, TTuple<Types...>>::Value + 1>
|
||||||
: TConstant<size_t, CSameAs<T, U> ? 0 : (TTupleElementIndex<T, Types...>::Value == INDEX_NONE
|
|
||||||
? INDEX_NONE : TTupleElementIndex<T, Types...>::Value + 1)>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct TTupleElementIndex<T> : TConstant<size_t, INDEX_NONE> { };
|
|
||||||
|
|
||||||
template <size_t I, typename... Types>
|
|
||||||
struct TTupleElementType;
|
|
||||||
|
|
||||||
template <size_t I, typename T, typename... Types>
|
|
||||||
struct TTupleElementType<I, T, Types...>
|
|
||||||
{
|
{
|
||||||
static_assert(I < sizeof...(Types) + 1, "Tuple type index is invalid");
|
static_assert(sizeof...(Types) != 0, "Non-existent types in tuple");
|
||||||
using Type = TTupleElementType<I - 1, Types...>::Type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Types>
|
template <typename T, typename... Types>
|
||||||
struct TTupleElementType<0, T, Types...> { using Type = T; };
|
struct TTupleIndexImpl<T, TTuple<T, Types...>> : TConstant<size_t, 0>
|
||||||
|
{
|
||||||
|
static_assert((true && ... && !CSameAs<T, Types>), "Duplicate type in tuple");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct TTupleIndexImpl<T, TTuple<>> : TConstant<size_t, INDEX_NONE> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TTupleIndexImpl<T, const TTuple<Types...>> : TTupleIndexImpl<T, TTuple<Types...>> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TTupleIndexImpl<T, volatile TTuple<Types...>> : TTupleIndexImpl<T, TTuple<Types...>> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TTupleIndexImpl<T, const volatile TTuple<Types...>> : TTupleIndexImpl<T, TTuple<Types...>> { };
|
||||||
|
|
||||||
|
template <size_t I, typename TupleType>
|
||||||
|
struct TTupleElementImpl;
|
||||||
|
|
||||||
|
template <size_t I, typename T, typename... Types>
|
||||||
|
struct TTupleElementImpl<I, TTuple<T, Types...>>
|
||||||
|
{
|
||||||
|
static_assert(I < sizeof...(Types) + 1, "Invalid index in tuple");
|
||||||
|
using Type = TTupleElementImpl<I - 1, TTuple<Types...>>::Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TTupleElementImpl<0, TTuple<T, Types...>> { using Type = T; };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TTupleElementImpl<I, TTuple<Types...>> { };
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct TTupleElementType<0> { };
|
struct TTupleElementImpl<0, TTuple<>> { };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TTupleElementImpl<I, const TTuple<Types...>> { using Type = TAddConst<typename TTupleElementImpl<I, TTuple<Types...>>::Type>; };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TTupleElementImpl<I, volatile TTuple<Types...>> { using Type = TAddVolatile<typename TTupleElementImpl<I, TTuple<Types...>>::Type>; };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TTupleElementImpl<I, const volatile TTuple<Types...>> { using Type = TAddCV<typename TTupleElementImpl<I, TTuple<Types...>>::Type>; };
|
||||||
|
|
||||||
|
template <bool bTrue, typename... Types>
|
||||||
|
struct TTupleConvertCopy : FTrue { };
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct TTupleConvertCopy<false, T, U>
|
||||||
|
: TBoolConstant<!(CConvertibleTo<const TTuple<U>&, T>
|
||||||
|
|| CConstructibleFrom<T, const TTuple<U>&>
|
||||||
|
|| CSameAs<T, U>)>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template <bool bTrue, typename... Types>
|
||||||
|
struct TTupleConvertMove : FTrue { };
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct TTupleConvertMove<false, T, U>
|
||||||
|
: TBoolConstant<!(CConvertibleTo<TTuple<U>&&, T>
|
||||||
|
|| CConstructibleFrom<T, TTuple<U>&&>
|
||||||
|
|| CSameAs<T, U>)>
|
||||||
|
{ };
|
||||||
|
|
||||||
template <typename T, size_t Index>
|
template <typename T, size_t Index>
|
||||||
struct TTupleElement
|
struct TTupleBasicElement
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -66,15 +131,15 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
constexpr TTupleElement(Type&& Arg)
|
constexpr TTupleBasicElement(Type&& Arg)
|
||||||
: Value(Forward<Type>(Arg))
|
: Value(Forward<Type>(Arg))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
TTupleElement() = default;
|
TTupleBasicElement() = default;
|
||||||
TTupleElement(TTupleElement&&) = default;
|
TTupleBasicElement(TTupleBasicElement&&) = default;
|
||||||
TTupleElement(const TTupleElement&) = default;
|
TTupleBasicElement(const TTupleBasicElement&) = default;
|
||||||
TTupleElement& operator=(TTupleElement&&) = default;
|
TTupleBasicElement& operator=(TTupleBasicElement&&) = default;
|
||||||
TTupleElement& operator=(const TTupleElement&) = default;
|
TTupleBasicElement& operator=(const TTupleBasicElement&) = default;
|
||||||
|
|
||||||
constexpr T& GetValue() & { return static_cast< T& >(Value); }
|
constexpr T& GetValue() & { return static_cast< T& >(Value); }
|
||||||
constexpr const T& GetValue() const & { return static_cast<const T& >(Value); }
|
constexpr const T& GetValue() const & { return static_cast<const T& >(Value); }
|
||||||
@ -88,23 +153,23 @@ public:
|
|||||||
|
|
||||||
#if RS_TUPLE_ELEMENT_STATIC_ALIAS
|
#if RS_TUPLE_ELEMENT_STATIC_ALIAS
|
||||||
|
|
||||||
#define DEFINE_TTupleElement(Index, Name) \
|
#define DEFINE_TTupleBasicElement(Index, Name) \
|
||||||
template <typename T> \
|
template <typename T> \
|
||||||
struct TTupleElement<T, Index> \
|
struct TTupleBasicElement<T, Index> \
|
||||||
{ \
|
{ \
|
||||||
using Name##Type = T; \
|
using Name##Type = T; \
|
||||||
Name##Type Name; \
|
Name##Type Name; \
|
||||||
\
|
\
|
||||||
template <typename Type> \
|
template <typename Type> \
|
||||||
constexpr TTupleElement(Type&& Arg) \
|
constexpr TTupleBasicElement(Type&& Arg) \
|
||||||
: Name(Forward<Type>(Arg)) \
|
: Name(Forward<Type>(Arg)) \
|
||||||
{ } \
|
{ } \
|
||||||
\
|
\
|
||||||
TTupleElement() = default; \
|
TTupleBasicElement() = default; \
|
||||||
TTupleElement(TTupleElement&&) = default; \
|
TTupleBasicElement(TTupleBasicElement&&) = default; \
|
||||||
TTupleElement(const TTupleElement&) = default; \
|
TTupleBasicElement(const TTupleBasicElement&) = default; \
|
||||||
TTupleElement& operator=(TTupleElement&&) = default; \
|
TTupleBasicElement& operator=(TTupleBasicElement&&) = default; \
|
||||||
TTupleElement& operator=(const TTupleElement&) = default; \
|
TTupleBasicElement& operator=(const TTupleBasicElement&) = default; \
|
||||||
\
|
\
|
||||||
constexpr T& GetValue() & { return static_cast< T& >(Name); } \
|
constexpr T& GetValue() & { return static_cast< T& >(Name); } \
|
||||||
constexpr const T& GetValue() const & { return static_cast<const T& >(Name); } \
|
constexpr const T& GetValue() const & { return static_cast<const T& >(Name); } \
|
||||||
@ -116,38 +181,38 @@ public:
|
|||||||
constexpr const volatile T&& GetValue() const volatile&& { return static_cast<const volatile T&&>(Name); } \
|
constexpr const volatile T&& GetValue() const volatile&& { return static_cast<const volatile T&&>(Name); } \
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_TTupleElement(0x0, First);
|
DEFINE_TTupleBasicElement(0x0, First);
|
||||||
DEFINE_TTupleElement(0x1, Second);
|
DEFINE_TTupleBasicElement(0x1, Second);
|
||||||
DEFINE_TTupleElement(0x2, Third);
|
DEFINE_TTupleBasicElement(0x2, Third);
|
||||||
DEFINE_TTupleElement(0x3, Fourth);
|
DEFINE_TTupleBasicElement(0x3, Fourth);
|
||||||
DEFINE_TTupleElement(0x4, Fifth);
|
DEFINE_TTupleBasicElement(0x4, Fifth);
|
||||||
DEFINE_TTupleElement(0x5, Sixth);
|
DEFINE_TTupleBasicElement(0x5, Sixth);
|
||||||
DEFINE_TTupleElement(0x6, Seventh);
|
DEFINE_TTupleBasicElement(0x6, Seventh);
|
||||||
DEFINE_TTupleElement(0x7, Eighth);
|
DEFINE_TTupleBasicElement(0x7, Eighth);
|
||||||
DEFINE_TTupleElement(0x8, Ninth);
|
DEFINE_TTupleBasicElement(0x8, Ninth);
|
||||||
DEFINE_TTupleElement(0x9, Tenth);
|
DEFINE_TTupleBasicElement(0x9, Tenth);
|
||||||
DEFINE_TTupleElement(0xA, Eleventh);
|
DEFINE_TTupleBasicElement(0xA, Eleventh);
|
||||||
DEFINE_TTupleElement(0xB, Twelfth);
|
DEFINE_TTupleBasicElement(0xB, Twelfth);
|
||||||
DEFINE_TTupleElement(0xC, Thirteenth);
|
DEFINE_TTupleBasicElement(0xC, Thirteenth);
|
||||||
DEFINE_TTupleElement(0xD, Fourteenth);
|
DEFINE_TTupleBasicElement(0xD, Fourteenth);
|
||||||
DEFINE_TTupleElement(0xE, Fifteenth);
|
DEFINE_TTupleBasicElement(0xE, Fifteenth);
|
||||||
DEFINE_TTupleElement(0xF, Sixteenth);
|
DEFINE_TTupleBasicElement(0xF, Sixteenth);
|
||||||
|
|
||||||
#undef DEFINE_TTupleElement
|
#undef DEFINE_TTupleBasicElement
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
constexpr TTuple<typename TUnwrapRefDecay<Types>::Type...> MakeTupleImpl(Types&&... Args)
|
constexpr TTuple<TUnwrapRefDecay<Types>...> MakeTupleImpl(Types&&... Args)
|
||||||
{
|
{
|
||||||
return TTuple<typename TUnwrapRefDecay<Types>::Type...>(Forward<Types>(Args)...);
|
return TTuple<TUnwrapRefDecay<Types>...>(Forward<Types>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Indices, typename... Types>
|
template <typename Indices, typename... Types>
|
||||||
struct TTupleImpl;
|
struct TTupleImpl;
|
||||||
|
|
||||||
template <size_t... Indices, typename... Types>
|
template <size_t... Indices, typename... Types>
|
||||||
struct TTupleImpl<TIndexSequence<Indices...>, Types...> : TTupleElement<Types, Indices>...
|
struct TTupleImpl<TIndexSequence<Indices...>, Types...> : TTupleBasicElement<Types, Indices>...
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -155,12 +220,12 @@ protected:
|
|||||||
|
|
||||||
template <typename... ArgTypes>
|
template <typename... ArgTypes>
|
||||||
explicit TTupleImpl(FForwardingConstructor, ArgTypes&&... Args)
|
explicit TTupleImpl(FForwardingConstructor, ArgTypes&&... Args)
|
||||||
: TTupleElement<Types, Indices>(Forward<ArgTypes>(Args))...
|
: TTupleBasicElement<Types, Indices>(Forward<ArgTypes>(Args))...
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename TupleType>
|
template <typename TupleType>
|
||||||
explicit TTupleImpl(FOtherTupleConstructor, TupleType&& InValue)
|
explicit TTupleImpl(FOtherTupleConstructor, TupleType&& InValue)
|
||||||
: TTupleElement<Types, Indices>(Forward<TupleType>(InValue).template GetValue<Indices>())...
|
: TTupleBasicElement<Types, Indices>(Forward<TupleType>(InValue).template GetValue<Indices>())...
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
TTupleImpl(const TTupleImpl&) = default;
|
TTupleImpl(const TTupleImpl&) = default;
|
||||||
@ -180,7 +245,10 @@ struct TTupleHelper<TIndexSequence<Indices...>>
|
|||||||
template <typename LHSTupleType, typename RHSTupleType>
|
template <typename LHSTupleType, typename RHSTupleType>
|
||||||
static constexpr void Assign(LHSTupleType& LHS, RHSTupleType&& RHS)
|
static constexpr void Assign(LHSTupleType& LHS, RHSTupleType&& RHS)
|
||||||
{
|
{
|
||||||
static_assert(sizeof...(Indices) == LHS.ElementSize && LHS.ElementSize == RHS.ElementSize, "Cannot assign tuple from different size");
|
static_assert(sizeof...(Indices) == TTupleArityImpl<TRemoveReference<LHSTupleType>>::Value
|
||||||
|
&& TTupleArityImpl<TRemoveReference<LHSTupleType>>::Value == TTupleArityImpl<TRemoveReference<RHSTupleType>>::Value,
|
||||||
|
"Cannot assign tuple from different size");
|
||||||
|
|
||||||
((LHS.template GetValue<Indices>() = Forward<RHSTupleType>(RHS).template GetValue<Indices>()), ...);
|
((LHS.template GetValue<Indices>() = Forward<RHSTupleType>(RHS).template GetValue<Indices>()), ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,6 +286,18 @@ struct TTupleHelper<TIndexSequence<Indices...>>
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept CTTuple = NAMESPACE_PRIVATE::TIsTTuple<T>::Value;
|
||||||
|
|
||||||
|
template <typename TupleType>
|
||||||
|
inline constexpr size_t TTupleArity = NAMESPACE_PRIVATE::TTupleArityImpl<TupleType>::Value;
|
||||||
|
|
||||||
|
template <typename T, typename TupleType>
|
||||||
|
inline constexpr size_t TTupleIndex = NAMESPACE_PRIVATE::TTupleIndexImpl<T, TupleType>::Value;
|
||||||
|
|
||||||
|
template <size_t I, typename TupleType>
|
||||||
|
using TTupleElement = typename NAMESPACE_PRIVATE::TTupleElementImpl<I, TupleType>::Type;
|
||||||
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
struct TTuple : NAMESPACE_PRIVATE::TTupleImpl<TIndexSequenceFor<Types...>, Types...>
|
struct TTuple : NAMESPACE_PRIVATE::TTupleImpl<TIndexSequenceFor<Types...>, Types...>
|
||||||
{
|
{
|
||||||
@ -228,71 +308,32 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static constexpr size_t ElementSize = sizeof...(Types);
|
|
||||||
|
|
||||||
template <size_t I> struct TElementType : NAMESPACE_PRIVATE::TTupleElementType<I, Types...> { };
|
|
||||||
template <typename T> struct TElementIndex : NAMESPACE_PRIVATE::TTupleElementIndex<T, Types...> { };
|
|
||||||
|
|
||||||
TTuple() = default;
|
TTuple() = default;
|
||||||
|
|
||||||
template <typename... ArgTypes> requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize)
|
template <typename... ArgTypes> requires (sizeof...(Types) >= 1) && (sizeof...(ArgTypes) == sizeof...(Types))
|
||||||
&& (true && ... && CConstructibleFrom<Types, ArgTypes&&>)
|
&& (true && ... && CConstructibleFrom<Types, ArgTypes&&>)
|
||||||
&& (true && ... && CConvertibleTo<ArgTypes&&, Types>)
|
constexpr explicit (!(true && ... && CConvertibleTo<ArgTypes&&, Types>)) TTuple(ArgTypes&&... Args)
|
||||||
constexpr TTuple(ArgTypes&&... Args)
|
|
||||||
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <typename... ArgTypes> requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize)
|
|
||||||
&& (true && ... && CConstructibleFrom<Types, ArgTypes&&>)
|
|
||||||
&& (!(true && ... && CConvertibleTo<ArgTypes&&, Types>))
|
|
||||||
constexpr explicit TTuple(ArgTypes&&... Args)
|
|
||||||
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
|
: Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward<ArgTypes>(Args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
|
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Types))
|
||||||
&& (true && ... && CConstructibleFrom<Types, const OtherTypes&>)
|
&& (true && ... && CConstructibleFrom<Types, const OtherTypes&>)
|
||||||
&& ((ElementSize != 1) || !(CConvertibleTo<const TTuple<OtherTypes...>&, typename TElementType<0>::Type>
|
&& NAMESPACE_PRIVATE::TTupleConvertCopy<sizeof...(Types) != 1, Types..., OtherTypes...>::Value
|
||||||
|| CConstructibleFrom<typename TElementType<0>::Type, const TTuple<OtherTypes...>&>
|
constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Types>)) TTuple(const TTuple<OtherTypes...>& InValue)
|
||||||
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
|
|
||||||
&& (true && ... && CConvertibleTo<OtherTypes&&, Types>)
|
|
||||||
constexpr TTuple(const TTuple<OtherTypes...>& InValue)
|
|
||||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
|
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
|
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Types))
|
||||||
&& (true && ... && CConstructibleFrom<Types, const OtherTypes&>)
|
|
||||||
&& ((ElementSize != 1) || !(CConvertibleTo<const TTuple<OtherTypes...>&, typename TElementType<0>::Type>
|
|
||||||
|| CConstructibleFrom<typename TElementType<0>::Type, const TTuple<OtherTypes...>&>
|
|
||||||
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
|
|
||||||
&& (!(true && ... && CConvertibleTo<OtherTypes&&, Types>))
|
|
||||||
constexpr explicit TTuple(const TTuple<OtherTypes...>& InValue)
|
|
||||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
|
|
||||||
&& (true && ... && CConstructibleFrom<Types, OtherTypes&&>)
|
&& (true && ... && CConstructibleFrom<Types, OtherTypes&&>)
|
||||||
&& ((ElementSize != 1) || !(CConvertibleTo<TTuple<OtherTypes...>&&, typename TElementType<0>::Type>
|
&& NAMESPACE_PRIVATE::TTupleConvertMove<sizeof...(Types) != 1, Types..., OtherTypes...>::Value
|
||||||
|| CConstructibleFrom<typename TElementType<0>::Type, TTuple<OtherTypes...>&&>
|
constexpr explicit (!(true && ... && CConvertibleTo<OtherTypes&&, Types>)) TTuple(TTuple<OtherTypes...>&& InValue)
|
||||||
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
|
|
||||||
&& (true && ... && CConvertibleTo<OtherTypes&&, Types>)
|
|
||||||
constexpr TTuple(TTuple<OtherTypes...>&& InValue)
|
|
||||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
|
|
||||||
{ }
|
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
|
|
||||||
&& (true && ... && CConstructibleFrom<Types, OtherTypes&&>)
|
|
||||||
&& ((ElementSize != 1) || !(CConvertibleTo<TTuple<OtherTypes...>&&, typename TElementType<0>::Type>
|
|
||||||
|| CConstructibleFrom<typename TElementType<0>::Type, TTuple<OtherTypes...>&&>
|
|
||||||
|| CSameAs<typename TElementType<0>::Type, typename TTuple<OtherTypes...>::template TElementType<0>::Type>))
|
|
||||||
&& (!(true && ... && CConvertibleTo<OtherTypes&&, Types>))
|
|
||||||
constexpr explicit TTuple(TTuple<OtherTypes...>&& InValue)
|
|
||||||
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
|
: Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
TTuple(const TTuple&) = default;
|
TTuple(const TTuple&) = default;
|
||||||
TTuple(TTuple&&) = default;
|
TTuple(TTuple&&) = default;
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
|
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Types))
|
||||||
&& (true && ... && CAssignableFrom<Types&, const OtherTypes&>)
|
&& (true && ... && CAssignableFrom<Types&, const OtherTypes&>)
|
||||||
constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue)
|
constexpr TTuple& operator=(const TTuple<OtherTypes...>& InValue)
|
||||||
{
|
{
|
||||||
@ -300,7 +341,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == ElementSize)
|
template <typename... OtherTypes> requires (sizeof...(OtherTypes) == sizeof...(Types))
|
||||||
&& (true && ... && CAssignableFrom<Types&, OtherTypes&&>)
|
&& (true && ... && CAssignableFrom<Types&, OtherTypes&&>)
|
||||||
constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue)
|
constexpr TTuple& operator=(TTuple<OtherTypes...>&& InValue)
|
||||||
{
|
{
|
||||||
@ -311,59 +352,59 @@ public:
|
|||||||
TTuple& operator=(const TTuple&) = default;
|
TTuple& operator=(const TTuple&) = default;
|
||||||
TTuple& operator=(TTuple&&) = default;
|
TTuple& operator=(TTuple&&) = default;
|
||||||
|
|
||||||
template <size_t I> requires (I < ElementSize) constexpr TElementType<I>::Type& GetValue() & { return static_cast< NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>& >(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() & { return static_cast< NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>& >(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < ElementSize) constexpr const TElementType<I>::Type& GetValue() const & { return static_cast<const NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>& >(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() const & { return static_cast<const NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>& >(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < ElementSize) constexpr volatile TElementType<I>::Type& GetValue() volatile& { return static_cast< volatile NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>& >(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() volatile& { return static_cast< volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>& >(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < ElementSize) constexpr const volatile TElementType<I>::Type& GetValue() const volatile& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>& >(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() const volatile& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>& >(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < ElementSize) constexpr TElementType<I>::Type&& GetValue() && { return static_cast< NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>&&>(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() && { return static_cast< NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>&&>(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < ElementSize) constexpr const TElementType<I>::Type&& GetValue() const && { return static_cast<const NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>&&>(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() const && { return static_cast<const NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>&&>(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < ElementSize) constexpr volatile TElementType<I>::Type&& GetValue() volatile&& { return static_cast< volatile NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>&&>(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() volatile&& { return static_cast< volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>&&>(*this).GetValue(); }
|
||||||
template <size_t I> requires (I < ElementSize) constexpr const volatile TElementType<I>::Type&& GetValue() const volatile&& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleElement<typename TElementType<I>::Type, I>&&>(*this).GetValue(); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile NAMESPACE_PRIVATE::TTupleBasicElement<TTupleElement<I, TTuple<Types...>>, I>&&>(*this).GetValue(); }
|
||||||
|
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr T& GetValue() & { return static_cast< TTuple& >(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() & { return static_cast< TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr const T& GetValue() const & { return static_cast<const TTuple& >(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() const & { return static_cast<const TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr volatile T& GetValue() volatile& { return static_cast< volatile TTuple& >(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() volatile& { return static_cast< volatile TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr const volatile T& GetValue() const volatile& { return static_cast<const volatile TTuple& >(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() const volatile& { return static_cast<const volatile TTuple& >(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr T&& GetValue() && { return static_cast< TTuple&&>(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() && { return static_cast< TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr const T&& GetValue() const && { return static_cast<const TTuple&&>(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() const && { return static_cast<const TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile TTuple&&>(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() volatile&& { return static_cast< volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
template <typename T> requires (TElementIndex<T>::Value != INDEX_NONE) constexpr const volatile T&& GetValue() const volatile&& { return static_cast<const volatile TTuple&&>(*this).GetValue<TElementIndex<T>::Value>(); }
|
template <typename T> constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple<Types...>>>(); }
|
||||||
|
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) & { return Helper::Apply(Forward<F>(Func), static_cast< TTuple& >(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) & { return Helper::Apply(Forward<F>(Func), static_cast< TTuple& >(*this)); }
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) const & { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) const & { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) volatile& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) volatile& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) const volatile& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) const volatile& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) && { return Helper::Apply(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) && { return Helper::Apply(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) const && { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) const && { return Helper::Apply(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) volatile&& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) volatile&& { return Helper::Apply(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
|
||||||
template <typename F> requires CInvocable<F, Types...> constexpr auto Apply(F&& Func) const volatile&& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
|
template <typename F> requires CInvocable<F, Types...> constexpr decltype(auto) Apply(F&& Func) const volatile&& { return Helper::Apply(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
|
||||||
|
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) & { return Helper::ApplyAfter(Forward<F>(Func), static_cast< TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) & { return Helper::ApplyAfter(Forward<F>(Func), static_cast< TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const & { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) const & { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) volatile& { return Helper::ApplyAfter(Forward<F>(Func), static_cast< volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) volatile& { return Helper::ApplyAfter(Forward<F>(Func), static_cast< volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const volatile& { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) const volatile& { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) && { return Helper::ApplyAfter(Forward<F>(Func), static_cast< TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) && { return Helper::ApplyAfter(Forward<F>(Func), static_cast< TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const && { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) const && { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) volatile&& { return Helper::ApplyAfter(Forward<F>(Func), static_cast< volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) volatile&& { return Helper::ApplyAfter(Forward<F>(Func), static_cast< volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const volatile&& { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, ArgTypes..., Types...> constexpr decltype(auto) ApplyAfter(F&& Func, ArgTypes&&... Args) const volatile&& { return Helper::ApplyAfter(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
|
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) & { return Helper::ApplyBefore(Forward<F>(Func), static_cast< TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) & { return Helper::ApplyBefore(Forward<F>(Func), static_cast< TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const & { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) const & { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) volatile& { return Helper::ApplyBefore(Forward<F>(Func), static_cast< volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) volatile& { return Helper::ApplyBefore(Forward<F>(Func), static_cast< volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const volatile& { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) const volatile& { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const volatile TTuple& >(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) && { return Helper::ApplyBefore(Forward<F>(Func), static_cast< TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) && { return Helper::ApplyBefore(Forward<F>(Func), static_cast< TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const && { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) const && { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) volatile&& { return Helper::ApplyBefore(Forward<F>(Func), static_cast< volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) volatile&& { return Helper::ApplyBefore(Forward<F>(Func), static_cast< volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const volatile&& { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
template <typename F, typename... ArgTypes> requires CInvocable<F, Types..., ArgTypes...> constexpr decltype(auto) ApplyBefore(F&& Func, ArgTypes&&... Args) const volatile&& { return Helper::ApplyBefore(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Forward<ArgTypes>(Args)...); }
|
||||||
|
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) & { return Helper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) & { return Helper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); }
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const & { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) const & { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) volatile& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) volatile& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const volatile& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) const volatile& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) && { return Helper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) && { return Helper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const && { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) const && { return Helper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) volatile&& { return Helper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
|
||||||
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr auto Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
|
template <typename F> requires (true && ... && (CInvocable<F, Types> && !CSameAs<void, TInvokeResult<F, Types>>)) constexpr decltype(auto) Transform(F&& Func) const volatile&& { return Helper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
|
||||||
|
|
||||||
template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); }
|
template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() & { return Helper::template Construct<T>(static_cast< TTuple& >(*this)); }
|
||||||
template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); }
|
template <typename T> requires CConstructibleFrom<T, Types...> constexpr T Construct() const & { return Helper::template Construct<T>(static_cast<const TTuple& >(*this)); }
|
||||||
@ -376,12 +417,20 @@ public:
|
|||||||
|
|
||||||
constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Types>)
|
constexpr size_t GetTypeHash() const requires (true && ... && CHashable<Types>)
|
||||||
{
|
{
|
||||||
return [this]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t { return HashCombine(NAMESPACE_REDCRAFT::GetTypeHash(GetValue<Indices>())...); } (TMakeIndexSequence<ElementSize>());
|
return [this]<size_t... Indices>(TIndexSequence<Indices...>) -> size_t
|
||||||
|
{
|
||||||
|
return HashCombine(NAMESPACE_REDCRAFT::GetTypeHash(GetValue<Indices>())...);
|
||||||
|
}
|
||||||
|
(TMakeIndexSequence<sizeof...(Types)>());
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible<Types>&& CSwappable<Types>))
|
constexpr void Swap(TTuple& InValue) requires (true && ... && (CMoveConstructible<Types>&& CSwappable<Types>))
|
||||||
{
|
{
|
||||||
[&A = *this, &B = InValue]<size_t... Indices>(TIndexSequence<Indices...>) { ((NAMESPACE_REDCRAFT::Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...); } (TMakeIndexSequence<ElementSize>());
|
[&A = *this, &B = InValue]<size_t... Indices>(TIndexSequence<Indices...>)
|
||||||
|
{
|
||||||
|
((NAMESPACE_REDCRAFT::Swap(A.template GetValue<Indices>(), B.template GetValue<Indices>())), ...);
|
||||||
|
}
|
||||||
|
(TMakeIndexSequence<sizeof...(Types)>());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -392,28 +441,10 @@ TTuple(Types...) -> TTuple<Types...>;
|
|||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
using TPair = TTuple<T, U>;
|
using TPair = TTuple<T, U>;
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
|
||||||
|
|
||||||
template <typename T > struct TIsTTuple : FFalse { };
|
|
||||||
template <typename... Types> struct TIsTTuple<TTuple<Types...>> : FTrue { };
|
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
|
||||||
|
|
||||||
template <typename T> concept CTTuple = NAMESPACE_PRIVATE::TIsTTuple<T>::Value;
|
|
||||||
|
|
||||||
template <typename TupleType> requires CTTuple<TRemoveCVRef<TupleType>>
|
|
||||||
struct TTupleElementSize : TConstant<size_t, TRemoveCVRef<TupleType>::ElementSize> { };
|
|
||||||
|
|
||||||
template <size_t I, typename TupleType> requires CTTuple<TRemoveCVRef<TupleType>>
|
|
||||||
struct TTupleElementType { using Type = TCopyCVRef<TRemoveReference<TupleType>, typename TRemoveCVRef<TupleType>::template TElementType<I>::Type>; };
|
|
||||||
|
|
||||||
template <typename T, typename TupleType> requires CTTuple<TRemoveCVRef<TupleType>>
|
|
||||||
struct TTupleElementIndex : TupleType::template TElementIndex<T> { };
|
|
||||||
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
constexpr TTuple<typename TUnwrapRefDecay<Types>::Type...> MakeTuple(Types&&... Args)
|
constexpr TTuple<TUnwrapRefDecay<Types>...> MakeTuple(Types&&... Args)
|
||||||
{
|
{
|
||||||
return TTuple<typename TUnwrapRefDecay<Types>::Type...>(Forward<Types>(Args)...);
|
return TTuple<TUnwrapRefDecay<Types>...>(Forward<Types>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Types>
|
template <typename... Types>
|
||||||
@ -476,7 +507,7 @@ template <size_t... ForwardIndices, size_t... TTupleIndices>
|
|||||||
struct TTupleCatForward<TIndexSequence<ForwardIndices...>, TIndexSequence<TTupleIndices...>>
|
struct TTupleCatForward<TIndexSequence<ForwardIndices...>, TIndexSequence<TTupleIndices...>>
|
||||||
{
|
{
|
||||||
template <typename ForwardType, typename TTupleType>
|
template <typename ForwardType, typename TTupleType>
|
||||||
static constexpr auto F(ForwardType&& ForwardTuple, TTupleType&& InValue)
|
static constexpr decltype(auto) F(ForwardType&& ForwardTuple, TTupleType&& InValue)
|
||||||
{
|
{
|
||||||
return ForwardAsTuple(Forward<ForwardType>(ForwardTuple).template GetValue<ForwardIndices>()..., Forward<TTupleType>(InValue).template GetValue<TTupleIndices>()...);
|
return ForwardAsTuple(Forward<ForwardType>(ForwardTuple).template GetValue<ForwardIndices>()..., Forward<TTupleType>(InValue).template GetValue<TTupleIndices>()...);
|
||||||
}
|
}
|
||||||
@ -486,15 +517,18 @@ template <typename R>
|
|||||||
struct TTupleCatImpl
|
struct TTupleCatImpl
|
||||||
{
|
{
|
||||||
template <typename ForwardType, typename TTupleType, typename... OtherTTupleTypes>
|
template <typename ForwardType, typename TTupleType, typename... OtherTTupleTypes>
|
||||||
static constexpr auto F(ForwardType&& ForwardTuple, TTupleType&& InValue, OtherTTupleTypes&&... OtherValue)
|
static constexpr decltype(auto) F(ForwardType&& ForwardTuple, TTupleType&& InValue, OtherTTupleTypes&&... OtherValue)
|
||||||
{
|
{
|
||||||
return F(TTupleCatForward<TMakeIndexSequence<TTupleElementSize<ForwardType>::Value>, TMakeIndexSequence<TTupleElementSize<TTupleType>::Value>>::F(Forward<ForwardType>(ForwardTuple), Forward<TTupleType>(InValue)), Forward<OtherTTupleTypes>(OtherValue)...);
|
return F(TTupleCatForward<
|
||||||
|
TMakeIndexSequence<TTupleArity<TRemoveReference<ForwardType>>>,
|
||||||
|
TMakeIndexSequence<TTupleArity<TRemoveReference<TTupleType>>>>
|
||||||
|
::F(Forward<ForwardType>(ForwardTuple), Forward<TTupleType>(InValue)), Forward<OtherTTupleTypes>(OtherValue)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ForwardType>
|
template <typename ForwardType>
|
||||||
static constexpr auto F(ForwardType&& ForwardTuple)
|
static constexpr decltype(auto) F(ForwardType&& ForwardTuple)
|
||||||
{
|
{
|
||||||
return TTupleCatMake<R, TMakeIndexSequence<TTupleElementSize<ForwardType>::Value>>::F(Forward<ForwardType>(ForwardTuple));
|
return TTupleCatMake<R, TMakeIndexSequence<TTupleArity<ForwardType>>>::F(Forward<ForwardType>(ForwardTuple));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -546,13 +580,13 @@ struct TTupleVisitImpl<TIndexSequence<>>
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
template <typename... TTupleTypes> requires (true && ... && (CTTuple<TRemoveCVRef<TTupleTypes>>))
|
template <typename... TTupleTypes> requires (true && ... && CTTuple<TRemoveCVRef<TTupleTypes>>)
|
||||||
struct TTupleCatResult { using Type = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<TRemoveReference<TTupleTypes>..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type; };
|
using TTupleCatResult = typename NAMESPACE_PRIVATE::TTupleCatResultImpl<TRemoveReference<TTupleTypes>..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type;;
|
||||||
|
|
||||||
template <typename... TTupleTypes> requires (true && ... && (CTTuple<TRemoveCVRef<TTupleTypes>>))
|
template <typename... TTupleTypes> requires (true && ... && CTTuple<TRemoveCVRef<TTupleTypes>>)
|
||||||
constexpr auto TupleCat(TTupleTypes&&... Args)
|
constexpr decltype(auto) TupleCat(TTupleTypes&&... Args)
|
||||||
{
|
{
|
||||||
using R = typename TTupleCatResult<TTupleTypes...>::Type;
|
using R = TTupleCatResult<TTupleTypes...>;
|
||||||
if constexpr (sizeof...(Args) == 0) return R();
|
if constexpr (sizeof...(Args) == 0) return R();
|
||||||
else return NAMESPACE_PRIVATE::TTupleCatImpl<R>::F(Forward<TTupleTypes>(Args)...);
|
else return NAMESPACE_PRIVATE::TTupleCatImpl<R>::F(Forward<TTupleTypes>(Args)...);
|
||||||
}
|
}
|
||||||
@ -565,9 +599,9 @@ constexpr bool operator==(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes.
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename... LHSTypes, typename... RHSTypes> requires ((sizeof...(LHSTypes) == sizeof...(RHSTypes)) && (true && ... && (CSynthThreeWayComparable<LHSTypes, RHSTypes>)))
|
template <typename... LHSTypes, typename... RHSTypes> requires ((sizeof...(LHSTypes) == sizeof...(RHSTypes)) && (true && ... && (CSynthThreeWayComparable<LHSTypes, RHSTypes>)))
|
||||||
constexpr typename TCommonComparisonCategory<typename TSynthThreeWayResult<LHSTypes, RHSTypes>::Type...>::Type operator<=>(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS)
|
constexpr TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...> operator<=>(const TTuple<LHSTypes...>& LHS, const TTuple<RHSTypes...>& RHS)
|
||||||
{
|
{
|
||||||
using R = typename TCommonComparisonCategory<typename TSynthThreeWayResult<LHSTypes, RHSTypes>::Type...>::Type;
|
using R = TCommonComparisonCategory<TSynthThreeWayResult<LHSTypes, RHSTypes>...>;
|
||||||
return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(LHSTypes)>>::F(LHS, RHS);
|
return NAMESPACE_PRIVATE::TTupleThreeWay<R, TMakeIndexSequence<sizeof...(LHSTypes)>>::F(LHS, RHS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,7 +611,8 @@ constexpr void VisitTuple(F&& Func) { }
|
|||||||
template <typename F, typename FirstTupleType, typename... TupleTypes>
|
template <typename F, typename FirstTupleType, typename... TupleTypes>
|
||||||
constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples)
|
constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples)
|
||||||
{
|
{
|
||||||
NAMESPACE_PRIVATE::TTupleVisitImpl<TMakeIndexSequence<TTupleElementSize<FirstTupleType>::Value>>::F(Forward<F>(Func), Forward<FirstTupleType>(FirstTuple), Forward<TupleTypes>(Tuples)...);
|
NAMESPACE_PRIVATE::TTupleVisitImpl<TMakeIndexSequence<TTupleArity<TRemoveReference<FirstTupleType>>>>
|
||||||
|
::F(Forward<F>(Func), Forward<FirstTupleType>(FirstTuple), Forward<TupleTypes>(Tuples)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Ts, typename... Us> requires requires { typename TTuple<TCommonType<Ts, Us>...>; }
|
template <typename... Ts, typename... Us> requires requires { typename TTuple<TCommonType<Ts, Us>...>; }
|
||||||
@ -600,8 +635,8 @@ NAMESPACE_REDCRAFT_END
|
|||||||
NAMESPACE_STD_BEGIN
|
NAMESPACE_STD_BEGIN
|
||||||
|
|
||||||
// Support structure binding, should not be directly used
|
// Support structure binding, should not be directly used
|
||||||
template <typename... Types> struct tuple_size<NAMESPACE_REDCRAFT::TTuple<Types...>> : integral_constant<size_t, NAMESPACE_REDCRAFT::TTupleElementSize<NAMESPACE_REDCRAFT::TTuple<Types...>>::Value> { };
|
template <typename... Types> struct tuple_size<NAMESPACE_REDCRAFT::TTuple<Types...>> : integral_constant<size_t, NAMESPACE_REDCRAFT::TTupleArity<NAMESPACE_REDCRAFT::TTuple<Types...>>> { };
|
||||||
template <size_t I, typename... Types> struct tuple_element<I, NAMESPACE_REDCRAFT::TTuple<Types...>> { using type = typename NAMESPACE_REDCRAFT::TTupleElementType<I, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type; };
|
template <size_t I, typename... Types> struct tuple_element<I, NAMESPACE_REDCRAFT::TTuple<Types...>> { using type = NAMESPACE_REDCRAFT::TTupleElement<I, NAMESPACE_REDCRAFT::TTuple<Types...>>; };
|
||||||
|
|
||||||
NAMESPACE_STD_END
|
NAMESPACE_STD_END
|
||||||
|
|
||||||
@ -610,14 +645,14 @@ NAMESPACE_MODULE_BEGIN(Redcraft)
|
|||||||
NAMESPACE_MODULE_BEGIN(Utility)
|
NAMESPACE_MODULE_BEGIN(Utility)
|
||||||
|
|
||||||
// Support structure binding, should not be directly used
|
// Support structure binding, should not be directly used
|
||||||
template <size_t Index, typename ...Types> constexpr typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& get( NAMESPACE_REDCRAFT::TTuple<Types...>& InValue) { return static_cast< typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& >(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get( TTuple<Types...>& InValue) { return static_cast< TTuple<Types...>& >(InValue).template GetValue<Index>(); }
|
||||||
template <size_t Index, typename ...Types> constexpr const typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& get(const NAMESPACE_REDCRAFT::TTuple<Types...>& InValue) { return static_cast<const typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& >(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get(const TTuple<Types...>& InValue) { return static_cast<const TTuple<Types...>& >(InValue).template GetValue<Index>(); }
|
||||||
template <size_t Index, typename ...Types> constexpr volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& get( volatile NAMESPACE_REDCRAFT::TTuple<Types...>& InValue) { return static_cast< volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& >(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get( volatile TTuple<Types...>& InValue) { return static_cast< volatile TTuple<Types...>& >(InValue).template GetValue<Index>(); }
|
||||||
template <size_t Index, typename ...Types> constexpr const volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& get(const volatile NAMESPACE_REDCRAFT::TTuple<Types...>& InValue) { return static_cast<const volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type& >(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get(const volatile TTuple<Types...>& InValue) { return static_cast<const volatile TTuple<Types...>& >(InValue).template GetValue<Index>(); }
|
||||||
template <size_t Index, typename ...Types> constexpr typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&& get( NAMESPACE_REDCRAFT::TTuple<Types...>&& InValue) { return static_cast< typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&&>(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get( TTuple<Types...>&& InValue) { return static_cast< TTuple<Types...>&&>(InValue).template GetValue<Index>(); }
|
||||||
template <size_t Index, typename ...Types> constexpr const typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&& get(const NAMESPACE_REDCRAFT::TTuple<Types...>&& InValue) { return static_cast<const typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&&>(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get(const TTuple<Types...>&& InValue) { return static_cast<const TTuple<Types...>&&>(InValue).template GetValue<Index>(); }
|
||||||
template <size_t Index, typename ...Types> constexpr volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&& get( volatile NAMESPACE_REDCRAFT::TTuple<Types...>&& InValue) { return static_cast< volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&&>(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get( volatile TTuple<Types...>&& InValue) { return static_cast< volatile TTuple<Types...>&&>(InValue).template GetValue<Index>(); }
|
||||||
template <size_t Index, typename ...Types> constexpr const volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&& get(const volatile NAMESPACE_REDCRAFT::TTuple<Types...>&& InValue) { return static_cast<const volatile typename TTupleElementType<Index, NAMESPACE_REDCRAFT::TTuple<Types...>>::Type&&>(InValue.template GetValue<Index>()); }
|
template <size_t Index, typename ...Types> constexpr decltype(auto) get(const volatile TTuple<Types...>&& InValue) { return static_cast<const volatile TTuple<Types...>&&>(InValue).template GetValue<Index>(); }
|
||||||
|
|
||||||
NAMESPACE_MODULE_END(Utility)
|
NAMESPACE_MODULE_END(Utility)
|
||||||
NAMESPACE_MODULE_END(Redcraft)
|
NAMESPACE_MODULE_END(Redcraft)
|
||||||
|
@ -13,35 +13,83 @@ NAMESPACE_REDCRAFT_BEGIN
|
|||||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||||
NAMESPACE_MODULE_BEGIN(Utility)
|
NAMESPACE_MODULE_BEGIN(Utility)
|
||||||
|
|
||||||
|
template <typename... Types> requires (true && ... && CDestructible<Types>)
|
||||||
|
struct TVariant;
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
template <typename T, typename... Types>
|
template <typename T > struct TIsTVariant : FFalse { };
|
||||||
struct TVariantAlternativeIndex;
|
template <typename... Types> struct TIsTVariant<TVariant<Types...>> : FTrue { };
|
||||||
|
|
||||||
|
template <typename TupleType>
|
||||||
|
struct TVariantNumImpl;
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TVariantNumImpl<TVariant<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TVariantNumImpl<const TVariant<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TVariantNumImpl<volatile TVariant<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename... Types>
|
||||||
|
struct TVariantNumImpl<const volatile TVariant<Types...>> : TConstant<size_t, sizeof...(Types)> { };
|
||||||
|
|
||||||
|
template <typename T, typename TupleType>
|
||||||
|
struct TVariantIndexImpl;
|
||||||
|
|
||||||
template <typename T, typename U, typename... Types>
|
template <typename T, typename U, typename... Types>
|
||||||
struct TVariantAlternativeIndex<T, U, Types...>
|
struct TVariantIndexImpl<T, TVariant<U, Types...>> : TConstant<size_t, TVariantIndexImpl<T, TVariant<Types...>>::Value + 1>
|
||||||
: TConstant<size_t, CSameAs<T, U> ? 0 : (TVariantAlternativeIndex<T, Types...>::Value == INDEX_NONE
|
|
||||||
? INDEX_NONE : TVariantAlternativeIndex<T, Types...>::Value + 1)>
|
|
||||||
{ };
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct TVariantAlternativeIndex<T> : TConstant<size_t, INDEX_NONE> { };
|
|
||||||
|
|
||||||
template <size_t I, typename... Types>
|
|
||||||
struct TVariantAlternativeType;
|
|
||||||
|
|
||||||
template <size_t I, typename T, typename... Types>
|
|
||||||
struct TVariantAlternativeType<I, T, Types...>
|
|
||||||
{
|
{
|
||||||
static_assert(I < sizeof...(Types) + 1, "Variant type index is invalid");
|
static_assert(sizeof...(Types) != 0, "Non-existent types in variant");
|
||||||
using Type = TVariantAlternativeType<I - 1, Types...>::Type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Types>
|
template <typename T, typename... Types>
|
||||||
struct TVariantAlternativeType<0, T, Types...> { using Type = T; };
|
struct TVariantIndexImpl<T, TVariant<T, Types...>> : TConstant<size_t, 0>
|
||||||
|
{
|
||||||
|
static_assert((true && ... && !CSameAs<T, Types>), "Duplicate type in variant");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct TVariantIndexImpl<T, TVariant<>> : TConstant<size_t, INDEX_NONE> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TVariantIndexImpl<T, const TVariant<Types...>> : TVariantIndexImpl<T, TVariant<Types...>> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TVariantIndexImpl<T, volatile TVariant<Types...>> : TVariantIndexImpl<T, TVariant<Types...>> { };
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TVariantIndexImpl<T, const volatile TVariant<Types...>> : TVariantIndexImpl<T, TVariant<Types...>> { };
|
||||||
|
|
||||||
|
template <size_t I, typename TupleType>
|
||||||
|
struct TVariantAlternativeImpl;
|
||||||
|
|
||||||
|
template <size_t I, typename T, typename... Types>
|
||||||
|
struct TVariantAlternativeImpl<I, TVariant<T, Types...>>
|
||||||
|
{
|
||||||
|
static_assert(I < sizeof...(Types) + 1, "Invalid index in variant");
|
||||||
|
using Type = TVariantAlternativeImpl<I - 1, TVariant<Types...>>::Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename... Types>
|
||||||
|
struct TVariantAlternativeImpl<0, TVariant<T, Types...>> { using Type = T; };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TVariantAlternativeImpl<I, TVariant<Types...>> { };
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct TVariantAlternativeType<0> { };
|
struct TVariantAlternativeImpl<0, TVariant<>> { };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TVariantAlternativeImpl<I, const TVariant<Types...>> { using Type = TAddConst<typename TVariantAlternativeImpl<I, TVariant<Types...>>::Type>; };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TVariantAlternativeImpl<I, volatile TVariant<Types...>> { using Type = TAddVolatile<typename TVariantAlternativeImpl<I, TVariant<Types...>>::Type>; };
|
||||||
|
|
||||||
|
template <size_t I, typename... Types>
|
||||||
|
struct TVariantAlternativeImpl<I, const volatile TVariant<Types...>> { using Type = TAddCV<typename TVariantAlternativeImpl<I, TVariant<Types...>>::Type>; };
|
||||||
|
|
||||||
template <typename T, typename... Types>
|
template <typename T, typename... Types>
|
||||||
struct TVariantSelectedType;
|
struct TVariantSelectedType;
|
||||||
@ -78,14 +126,21 @@ struct TVariantSelectedType<T>
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
template <typename... Types> requires (true && ... && CDestructible<Types>) && (sizeof...(Types) < 0xFF)
|
template <typename T>
|
||||||
|
concept CTVariant = NAMESPACE_PRIVATE::TIsTVariant<T>::Value;
|
||||||
|
|
||||||
|
template <typename VariantType>
|
||||||
|
inline constexpr size_t TVariantNum = NAMESPACE_PRIVATE::TVariantNumImpl<VariantType>::Value;
|
||||||
|
|
||||||
|
template <typename T, typename VariantType>
|
||||||
|
inline constexpr size_t TVariantIndex = NAMESPACE_PRIVATE::TVariantIndexImpl<T, VariantType>::Value;
|
||||||
|
|
||||||
|
template <size_t I, typename VariantType>
|
||||||
|
using TVariantAlternative = typename NAMESPACE_PRIVATE::TVariantAlternativeImpl<I, VariantType>::Type;
|
||||||
|
|
||||||
|
template <typename... Types> requires (true && ... && CDestructible<Types>)
|
||||||
struct TVariant
|
struct TVariant
|
||||||
{
|
{
|
||||||
static constexpr size_t AlternativeSize = sizeof...(Types);
|
|
||||||
|
|
||||||
template <size_t I> struct TAlternativeType : NAMESPACE_PRIVATE::TVariantAlternativeType<I, Types...> { };
|
|
||||||
template <typename T> struct TAlternativeIndex : NAMESPACE_PRIVATE::TVariantAlternativeIndex<T, Types...> { };
|
|
||||||
|
|
||||||
constexpr TVariant() : TypeIndex(0xFF) { };
|
constexpr TVariant() : TypeIndex(0xFF) { };
|
||||||
|
|
||||||
constexpr TVariant(FInvalid) : TVariant() { };
|
constexpr TVariant(FInvalid) : TVariant() { };
|
||||||
@ -102,19 +157,18 @@ struct TVariant
|
|||||||
if (IsValid()) MoveConstructImpl[InValue.GetIndex()](&Value, &InValue.Value);
|
if (IsValid()) MoveConstructImpl[InValue.GetIndex()](&Value, &InValue.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t I, typename... ArgTypes> requires (I < AlternativeSize)
|
template <size_t I, typename... ArgTypes> requires (I < sizeof...(Types))
|
||||||
&& CConstructibleFrom<typename TAlternativeType<I>::Type, ArgTypes...>
|
&& CConstructibleFrom<TVariantAlternative<I, TVariant<Types...>>, ArgTypes...>
|
||||||
constexpr explicit TVariant(TInPlaceIndex<I>, ArgTypes&&... Args)
|
constexpr explicit TVariant(TInPlaceIndex<I>, ArgTypes&&... Args)
|
||||||
: TypeIndex(I)
|
: TypeIndex(I)
|
||||||
{
|
{
|
||||||
using SelectedType = typename TAlternativeType<I>::Type;
|
using SelectedType = TVariantAlternative<I, TVariant<Types...>>;
|
||||||
new(&Value) SelectedType(Forward<ArgTypes>(Args)...);
|
new(&Value) SelectedType(Forward<ArgTypes>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... ArgTypes> requires (TAlternativeIndex<T>::Value != INDEX_NONE)
|
template <typename T, typename... ArgTypes> requires CConstructibleFrom<T, ArgTypes...>
|
||||||
&& CConstructibleFrom<typename TAlternativeType<TAlternativeIndex<T>::Value>::Type, ArgTypes...>
|
|
||||||
constexpr explicit TVariant(TInPlaceType<T>, ArgTypes&&... Args)
|
constexpr explicit TVariant(TInPlaceType<T>, ArgTypes&&... Args)
|
||||||
: TVariant(InPlaceIndex<TAlternativeIndex<T>::Value>, Forward<ArgTypes>(Args)...)
|
: TVariant(InPlaceIndex<TVariantIndex<T, TVariant<Types...>>>, Forward<ArgTypes>(Args)...)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
template <typename T> requires NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Types...>::Value
|
template <typename T> requires NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Types...>::Value
|
||||||
@ -175,35 +229,34 @@ struct TVariant
|
|||||||
{
|
{
|
||||||
using SelectedType = typename NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Types...>::Type;
|
using SelectedType = typename NAMESPACE_PRIVATE::TVariantSelectedType<TRemoveReference<T>, Types...>::Type;
|
||||||
|
|
||||||
if (GetIndex() == TAlternativeIndex<SelectedType>::Value) GetValue<SelectedType>() = Forward<T>(InValue);
|
if (GetIndex() == TVariantIndex<SelectedType, TVariant<Types...>>) GetValue<SelectedType>() = Forward<T>(InValue);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
new(&Value) SelectedType(Forward<T>(InValue));
|
new(&Value) SelectedType(Forward<T>(InValue));
|
||||||
TypeIndex = TAlternativeIndex<SelectedType>::Value;
|
TypeIndex = TVariantIndex<SelectedType, TVariant<Types...>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t I, typename... ArgTypes> requires (I < AlternativeSize)
|
template <size_t I, typename... ArgTypes> requires (I < sizeof...(Types))
|
||||||
&& CConstructibleFrom<typename TAlternativeType<I>::Type, ArgTypes...>
|
&& CConstructibleFrom<TVariantAlternative<I, TVariant<Types...>>, ArgTypes...>
|
||||||
constexpr typename TAlternativeType<I>::Type& Emplace(ArgTypes&&... Args)
|
constexpr TVariantAlternative<I, TVariant<Types...>>& Emplace(ArgTypes&&... Args)
|
||||||
{
|
{
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
using SelectedType = typename TAlternativeType<I>::Type;
|
using SelectedType = TVariantAlternative<I, TVariant<Types...>>;
|
||||||
SelectedType* Result = new(&Value) SelectedType(Forward<ArgTypes>(Args)...);
|
SelectedType* Result = new(&Value) SelectedType(Forward<ArgTypes>(Args)...);
|
||||||
TypeIndex = I;
|
TypeIndex = I;
|
||||||
|
|
||||||
return *Result;
|
return *Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... ArgTypes> requires (TAlternativeIndex<T>::Value != INDEX_NONE)
|
template <typename T, typename... ArgTypes> requires CConstructibleFrom<T, ArgTypes...>
|
||||||
&& CConstructibleFrom<typename TAlternativeType<TAlternativeIndex<T>::Value>::Type, ArgTypes...>
|
|
||||||
constexpr T& Emplace(ArgTypes&&... Args)
|
constexpr T& Emplace(ArgTypes&&... Args)
|
||||||
{
|
{
|
||||||
return Emplace<TAlternativeIndex<T>::Value>(Forward<ArgTypes>(Args)...);
|
return Emplace<TVariantIndex<T, TVariant<Types...>>>(Forward<ArgTypes>(Args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr const type_info& GetTypeInfo() const { return IsValid() ? *TypeInfos[GetIndex()] : typeid(void); }
|
constexpr const type_info& GetTypeInfo() const { return IsValid() ? *TypeInfos[GetIndex()] : typeid(void); }
|
||||||
@ -212,24 +265,24 @@ struct TVariant
|
|||||||
constexpr bool IsValid() const { return TypeIndex != 0xFF; }
|
constexpr bool IsValid() const { return TypeIndex != 0xFF; }
|
||||||
constexpr explicit operator bool() const { return TypeIndex != 0xFF; }
|
constexpr explicit operator bool() const { return TypeIndex != 0xFF; }
|
||||||
|
|
||||||
template <size_t I> constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == I : false; }
|
template <size_t I> constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == I : false; }
|
||||||
template <typename T> constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == TAlternativeIndex<T>::Value : false; }
|
template <typename T> constexpr bool HoldsAlternative() const { return IsValid() ? GetIndex() == TVariantIndex<T, TVariant<Types...>> : false; }
|
||||||
|
|
||||||
template <size_t I> requires (I < AlternativeSize) constexpr typename TAlternativeType<I>::Type& GetValue() & { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< TAlternativeType<I>::Type*>(&Value); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() & { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< TVariantAlternative<I, TVariant<Types...>>*>(&Value); }
|
||||||
template <size_t I> requires (I < AlternativeSize) constexpr typename TAlternativeType<I>::Type&& GetValue() && { checkf(HoldsAlternative<I>(), 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< TAlternativeType<I>::Type*>(&Value)); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() && { checkf(HoldsAlternative<I>(), 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< TVariantAlternative<I, TVariant<Types...>>*>(&Value)); }
|
||||||
template <size_t I> requires (I < AlternativeSize) constexpr const typename TAlternativeType<I>::Type& GetValue() const& { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const TAlternativeType<I>::Type*>(&Value); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() const& { checkf(HoldsAlternative<I>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const TVariantAlternative<I, TVariant<Types...>>*>(&Value); }
|
||||||
template <size_t I> requires (I < AlternativeSize) constexpr const typename TAlternativeType<I>::Type&& GetValue() const&& { checkf(HoldsAlternative<I>(), 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<const TAlternativeType<I>::Type*>(&Value)); }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) GetValue() const&& { checkf(HoldsAlternative<I>(), 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<const TVariantAlternative<I, TVariant<Types...>>*>(&Value)); }
|
||||||
|
|
||||||
template <typename T> requires (TAlternativeIndex<T>::Value != INDEX_NONE) constexpr T& GetValue() & { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< T*>(&Value); }
|
template <typename T> constexpr decltype(auto) GetValue() & { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast< T*>(&Value); }
|
||||||
template <typename T> requires (TAlternativeIndex<T>::Value != INDEX_NONE) constexpr T&& GetValue() && { checkf(HoldsAlternative<T>(), 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< T*>(&Value)); }
|
template <typename T> constexpr decltype(auto) GetValue() && { checkf(HoldsAlternative<T>(), 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< T*>(&Value)); }
|
||||||
template <typename T> requires (TAlternativeIndex<T>::Value != INDEX_NONE) constexpr const T& GetValue() const& { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const T*>(&Value); }
|
template <typename T> constexpr decltype(auto) GetValue() const& { checkf(HoldsAlternative<T>(), TEXT("It is an error to call GetValue() on an wrong TVariant. Please either check HoldsAlternative() or use Get(DefaultValue) instead.")); return *reinterpret_cast<const T*>(&Value); }
|
||||||
template <typename T> requires (TAlternativeIndex<T>::Value != INDEX_NONE) constexpr const T&& GetValue() const&& { checkf(HoldsAlternative<T>(), 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<const T*>(&Value)); }
|
template <typename T> constexpr decltype(auto) GetValue() const&& { checkf(HoldsAlternative<T>(), 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<const T*>(&Value)); }
|
||||||
|
|
||||||
template <size_t I> requires (I < AlternativeSize) constexpr typename TAlternativeType<I>::Type& Get( typename TAlternativeType<I>::Type& DefaultValue) & { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) Get( TVariantAlternative<I, TVariant<Types...>>& DefaultValue) & { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; }
|
||||||
template <size_t I> requires (I < AlternativeSize) constexpr const typename TAlternativeType<I>::Type& Get(const typename TAlternativeType<I>::Type& DefaultValue) const& { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; }
|
template <size_t I> requires (I < sizeof...(Types)) constexpr decltype(auto) Get(const TVariantAlternative<I, TVariant<Types...>>& DefaultValue) const& { return HoldsAlternative<I>() ? GetValue<I>() : DefaultValue; }
|
||||||
|
|
||||||
template <typename T> requires (TAlternativeIndex<T>::Value != INDEX_NONE) constexpr T& Get(T& DefaultValue)& { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; }
|
template <typename T> constexpr decltype(auto) Get( T& DefaultValue) & { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; }
|
||||||
template <typename T> requires (TAlternativeIndex<T>::Value != INDEX_NONE) constexpr const T& Get(const T& DefaultValue) const& { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; }
|
template <typename T> constexpr decltype(auto) Get(const T& DefaultValue) const& { return HoldsAlternative<T>() ? GetValue<T>() : DefaultValue; }
|
||||||
|
|
||||||
template <typename F> requires (true && ... && CInvocable<F, Types>)
|
template <typename F> requires (true && ... && CInvocable<F, Types>)
|
||||||
FORCEINLINE decltype(auto) Visit(F&& Func) &
|
FORCEINLINE decltype(auto) Visit(F&& Func) &
|
||||||
@ -409,24 +462,6 @@ constexpr bool operator==(const TVariant<Types...>& LHS, FInvalid)
|
|||||||
return !LHS.IsValid();
|
return !LHS.IsValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_BEGIN
|
|
||||||
|
|
||||||
template <typename T > struct TIsTVariant : FFalse { };
|
|
||||||
template <typename... Types> struct TIsTVariant<TVariant<Types...>> : FTrue { };
|
|
||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
|
||||||
|
|
||||||
template <typename T> concept CTVariant = NAMESPACE_PRIVATE::TIsTVariant<T>::Value;
|
|
||||||
|
|
||||||
template <typename VariantType> requires CTVariant<TRemoveCVRef<VariantType>>
|
|
||||||
struct TVariantAlternativeSize : TConstant<size_t, VariantType::AlternativeSize> { };
|
|
||||||
|
|
||||||
template <size_t I, typename VariantType> requires CTVariant<TRemoveCVRef<VariantType>>
|
|
||||||
struct TVariantAlternativeType { using Type = TCopyCV<TRemoveReference<VariantType>, typename TRemoveCVRef<VariantType>::template TAlternativeType<I>::Type>; };
|
|
||||||
|
|
||||||
template <typename T, typename VariantType> requires CTVariant<TRemoveCVRef<VariantType>>
|
|
||||||
struct TVariantAlternativeIndex : VariantType::template TAlternativeIndex<T> { };
|
|
||||||
|
|
||||||
NAMESPACE_MODULE_END(Utility)
|
NAMESPACE_MODULE_END(Utility)
|
||||||
NAMESPACE_MODULE_END(Redcraft)
|
NAMESPACE_MODULE_END(Redcraft)
|
||||||
NAMESPACE_REDCRAFT_END
|
NAMESPACE_REDCRAFT_END
|
||||||
|
@ -25,8 +25,8 @@ struct TMaximum<First, Second, Others...> : TMaximum<(First < Second ? Second :
|
|||||||
|
|
||||||
NAMESPACE_PRIVATE_END
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
template <typename T> inline constexpr size_t ArrayRank = NAMESPACE_STD::rank_v<T>;
|
template <typename T> inline constexpr size_t TRank = NAMESPACE_STD::rank_v<T>;
|
||||||
template <typename T, size_t I = 0> inline constexpr size_t ArrayExtent = NAMESPACE_STD::extent_v<T, I>;
|
template <typename T, size_t I = 0> inline constexpr size_t TExtent = NAMESPACE_STD::extent_v<T, I>;
|
||||||
|
|
||||||
template <typename T, typename U> concept CSameAs = NAMESPACE_STD::is_same_v<T, U>;
|
template <typename T, typename U> concept CSameAs = NAMESPACE_STD::is_same_v<T, U>;
|
||||||
template <typename T, typename U> concept CBaseOf = NAMESPACE_STD::is_base_of_v<T, U>;
|
template <typename T, typename U> concept CBaseOf = NAMESPACE_STD::is_base_of_v<T, U>;
|
||||||
|
Loading…
Reference in New Issue
Block a user