#pragma once #include "CoreTypes.h" #include "Templates/Utility.h" #include "Templates/Container.h" #include "TypeTraits/TypeTraits.h" NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) template struct TIntegerSequence { using ValueType = T; FORCEINLINE static constexpr size_t Num() { return sizeof...(Ints); } FORCEINLINE static constexpr const T* GetData() { return NAMESPACE_REDCRAFT::GetData({ Ints... }); } }; NAMESPACE_PRIVATE_BEGIN #ifdef _MSC_VER template struct TMakeIntegerSequenceImpl { using Type = typename __make_integer_seq; }; #elif __has_builtin(__make_integer_seq) template struct TMakeIntegerSequenceImpl { using Type = typename __make_integer_seq; }; #else template struct TMakeIntegerSequenceImpl { using Type = typename TMakeIntegerSequenceImpl::Type; }; template struct TMakeIntegerSequenceImpl<0, T, Ints...> { using Type = TIntegerSequence; }; #endif NAMESPACE_PRIVATE_END template using TIndexSequence = TIntegerSequence; template using TMakeIntegerSequence = typename NAMESPACE_PRIVATE::TMakeIntegerSequenceImpl::Type; template using TMakeIndexSequence = TMakeIntegerSequence; template using TIndexSequenceFor = TMakeIndexSequence; template struct TTypeSequence { }; NAMESPACE_PRIVATE_BEGIN template struct TIsTIntegerSequence : FFalse { }; template struct TIsTIntegerSequence> : FTrue { }; template struct TIsTIndexSequence : FFalse { }; template struct TIsTIndexSequence> : FTrue { }; template struct TIsTTypeSequence : FFalse { }; template struct TIsTTypeSequence> : FTrue { }; NAMESPACE_PRIVATE_END // Unlike other places such as CTTuple, cv-qualifiers are not ignored here // This is done to simplify the logic and make it easier to use it template concept CTIntegerSequence = NAMESPACE_PRIVATE::TIsTIntegerSequence::Value; template concept CTIndexSequence = NAMESPACE_PRIVATE::TIsTIndexSequence::Value; template concept CTTypeSequence = NAMESPACE_PRIVATE::TIsTTypeSequence::Value; NAMESPACE_BEGIN(Meta) NAMESPACE_PRIVATE_BEGIN template struct TFrontImpl; template struct TFrontImpl> { using Type = T; }; template struct TPopImpl; template struct TPopImpl> { using Type = TTypeSequence; }; template struct TPushImpl; template struct TPushImpl> { using Type = TTypeSequence; }; NAMESPACE_PRIVATE_END template using TFront = typename NAMESPACE_PRIVATE::TFrontImpl::Type; template using TPop = typename NAMESPACE_PRIVATE::TPopImpl::Type; template using TPush = typename NAMESPACE_PRIVATE::TPushImpl::Type; NAMESPACE_PRIVATE_BEGIN template struct TTypeCountImpl { static constexpr size_t Value = (CSameAs> ? 1 : 0) + TTypeCountImpl>::Value; }; template struct TTypeCountImpl> { static constexpr size_t Value = 0; }; NAMESPACE_PRIVATE_END template inline constexpr size_t TTypeCount = NAMESPACE_PRIVATE::TTypeCountImpl::Value; template concept CExistentType = CTTypeSequence && TTypeCount > 0; template concept CDuplicateType = CTTypeSequence && TTypeCount > 1; NAMESPACE_PRIVATE_BEGIN template struct TSizeImpl; template struct TSizeImpl> { static constexpr size_t Value = sizeof...(Ts); }; template struct TIndexImpl { static constexpr size_t Value = CSameAs> ? I : TIndexImpl>::Value; }; template struct TIndexImpl> { static constexpr size_t Value = INDEX_NONE; }; template struct TIndexAssert { static_assert( Meta::CExistentType< T, TSequence>, "T is non-existent types in type sequence"); static_assert(!Meta::CDuplicateType, "T is duplicate type in type sequence" ); static constexpr size_t Value = TIndexImpl<0, T, TSequence>::Value; }; template struct TTypeImpl { using Type = typename TTypeImpl>::Type; }; template struct TTypeImpl<0, TSequence> { using Type = TFront; }; template struct TTypeImpl { using Type = void; }; template struct TTypeAssert { static_assert(I < TSizeImpl::Value, "I is invalid index in type sequence"); static constexpr size_t SafeIndex = I < TSizeImpl::Value ? I : INDEX_NONE; using Type = TCopyCV::Type>; }; NAMESPACE_PRIVATE_END template inline constexpr size_t TSize = NAMESPACE_PRIVATE::TSizeImpl::Value; template inline constexpr size_t TIndex = NAMESPACE_PRIVATE::TIndexAssert::Value; template using TType = typename NAMESPACE_PRIVATE::TTypeAssert::Type; NAMESPACE_PRIVATE_BEGIN template struct TUniqueTypeSequenceImpl { using FrontType = TFront; using NextSequence = TPop; using NextUniqueSequence = typename TUniqueTypeSequenceImpl::Type; using Type = TConditional, TPush, NextUniqueSequence>; }; template <> struct TUniqueTypeSequenceImpl> { using Type = TTypeSequence<>; }; NAMESPACE_PRIVATE_END template using TUniqueTypeSequence = typename NAMESPACE_PRIVATE::TUniqueTypeSequenceImpl::Type; NAMESPACE_PRIVATE_BEGIN template struct TOverload { using F = T(*)(T); operator F() const { return nullptr; } }; template struct TOverloadSetImpl; template struct TOverloadSetImpl> : public TOverload... { }; template struct TOverloadSet : public TOverloadSetImpl> { }; NAMESPACE_PRIVATE_END template using TOverloadResolution = decltype(DeclVal>()(DeclVal())); NAMESPACE_END(Meta) NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END