#pragma once #include "CoreTypes.h" #include "Templates/Invoke.h" #include "Templates/Utility.h" #include "Templates/TypeHash.h" #include "TypeTraits/TypeTraits.h" #include "Templates/IntegerSequence.h" #include "Templates/ReferenceWrapper.h" #include NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) #define RS_TUPLE_ELEMENT_STATIC_ALIAS 1 template struct TTuple; NAMESPACE_PRIVATE_BEGIN struct FForwardingConstructor { explicit FForwardingConstructor() = default; }; struct FOtherTupleConstructor { explicit FOtherTupleConstructor() = default; }; inline constexpr FForwardingConstructor ForwardingConstructor{ }; inline constexpr FOtherTupleConstructor OtherTupleConstructor{ }; template struct TTupleElementIndex; template struct TTupleElementIndex : TConstant::Value ? 0 : (TTupleElementIndex::Value == INDEX_NONE ? INDEX_NONE : TTupleElementIndex::Value + 1)> { }; template struct TTupleElementIndex : TConstant { }; template struct TTupleElementType; template struct TTupleElementType { static_assert(I < sizeof...(Types) + 1, "Tuple type index is invalid"); using Type = TTupleElementType::Type; }; template struct TTupleElementType<0, T, Types...> { using Type = T; }; template <> struct TTupleElementType<0> { }; template struct TTupleElement { private: using ValueType = T; ValueType Value; public: template constexpr TTupleElement(Type&& Arg) : Value(Forward(Arg)) { } TTupleElement() = default; TTupleElement(TTupleElement&&) = default; TTupleElement(const TTupleElement&) = default; TTupleElement& operator=(TTupleElement&&) = default; TTupleElement& operator=(const TTupleElement&) = default; constexpr T& GetValue() & { return static_cast< T& >(Value); } constexpr const T& GetValue() const & { return static_cast(Value); } constexpr volatile T& GetValue() volatile& { return static_cast< volatile T& >(Value); } constexpr const volatile T& GetValue() const volatile& { return static_cast(Value); } constexpr T&& GetValue() && { return static_cast< T&&>(Value); } constexpr const T&& GetValue() const && { return static_cast(Value); } constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile T&&>(Value); } constexpr const volatile T&& GetValue() const volatile&& { return static_cast(Value); } }; #if RS_TUPLE_ELEMENT_STATIC_ALIAS #define DEFINE_TTupleElement(Index, Name) \ template \ struct TTupleElement \ { \ using Name##Type = T; \ Name##Type Name; \ \ template \ constexpr TTupleElement(Type&& Arg) \ : Name(Forward(Arg)) \ { } \ \ TTupleElement() = default; \ TTupleElement(TTupleElement&&) = default; \ TTupleElement(const TTupleElement&) = default; \ TTupleElement& operator=(TTupleElement&&) = default; \ TTupleElement& operator=(const TTupleElement&) = default; \ \ constexpr T& GetValue() & { return static_cast< T& >(Name); } \ constexpr const T& GetValue() const & { return static_cast(Name); } \ constexpr volatile T& GetValue() volatile& { return static_cast< volatile T& >(Name); } \ constexpr const volatile T& GetValue() const volatile& { return static_cast(Name); } \ constexpr T&& GetValue() && { return static_cast< T&&>(Name); } \ constexpr const T&& GetValue() const && { return static_cast(Name); } \ constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile T&&>(Name); } \ constexpr const volatile T&& GetValue() const volatile&& { return static_cast(Name); } \ } DEFINE_TTupleElement(0x0, First); DEFINE_TTupleElement(0x1, Second); DEFINE_TTupleElement(0x2, Third); DEFINE_TTupleElement(0x3, Fourth); DEFINE_TTupleElement(0x4, Fifth); DEFINE_TTupleElement(0x5, Sixth); DEFINE_TTupleElement(0x6, Seventh); DEFINE_TTupleElement(0x7, Eighth); DEFINE_TTupleElement(0x8, Ninth); DEFINE_TTupleElement(0x9, Tenth); DEFINE_TTupleElement(0xA, Eleventh); DEFINE_TTupleElement(0xB, Twelfth); DEFINE_TTupleElement(0xC, Thirteenth); DEFINE_TTupleElement(0xD, Fourteenth); DEFINE_TTupleElement(0xE, Fifteenth); DEFINE_TTupleElement(0xF, Sixteenth); #undef DEFINE_TTupleElement #endif template constexpr TTuple::Type...> MakeTupleImpl(Types&&... Args) { return TTuple::Type...>(Forward(Args)...); } template struct TTupleImpl; template struct TTupleImpl, Types...> : TTupleElement... { protected: TTupleImpl() = default; template explicit TTupleImpl(FForwardingConstructor, ArgTypes&&... Args) : TTupleElement(Forward(Args))... { } template explicit TTupleImpl(FOtherTupleConstructor, TupleType&& InValue) : TTupleElement(Forward(InValue).template GetValue())... { } TTupleImpl(const TTupleImpl&) = default; TTupleImpl(TTupleImpl&&) = default; TTupleImpl& operator=(const TTupleImpl&) = default; TTupleImpl& operator=(TTupleImpl&&) = default; }; template struct TTupleHelper; template struct TTupleHelper> { template static constexpr void Assign(LHSTupleType& LHS, RHSTupleType&& RHS) { static_assert(sizeof...(Indices) == LHS.ElementSize && LHS.ElementSize == RHS.ElementSize, "Cannot assign tuple from different size"); ((LHS.template GetValue() = Forward(RHS).template GetValue()), ...); } template static constexpr auto Apply(F&& Func, TTupleType&& Arg) { return Invoke(Forward(Func), Forward(Arg).template GetValue()...); } template static constexpr auto ApplyAfter(F&& Func, TTupleType&& Arg, ArgTypes&&... OtherArgs) { return Invoke(Forward(Func), Forward(OtherArgs)..., Forward(Arg).template GetValue()...); } template static constexpr auto ApplyBefore(F&& Func, TTupleType&& Arg, ArgTypes&&... OtherArgs) { return Invoke(Forward(Func), Forward(Arg).template GetValue()..., Forward(OtherArgs)...); } template static constexpr auto Transform(F&& Func, TTupleType&& Arg) { return MakeTupleImpl(Invoke(Forward(Func), Forward(Arg).template GetValue())...); } template static constexpr T Construct(TTupleType&& Arg) { return T(Forward(Arg).template GetValue()...); } }; NAMESPACE_PRIVATE_END template struct TTuple : NAMESPACE_PRIVATE::TTupleImpl, Types...> { private: using Super = NAMESPACE_PRIVATE::TTupleImpl, Types...>; using Helper = NAMESPACE_PRIVATE::TTupleHelper>; public: static constexpr size_t ElementSize = sizeof...(Types); template struct TElementType : NAMESPACE_PRIVATE::TTupleElementType { }; template struct TElementIndex : NAMESPACE_PRIVATE::TTupleElementIndex { }; TTuple() = default; template requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize) && (true && ... && TIsConstructible::Value) && (true && ... && TIsConvertible::Value) constexpr TTuple(ArgTypes&&... Args) : Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward(Args)...) { } template requires (ElementSize > 0) && (sizeof...(ArgTypes) == ElementSize) && (true && ... && TIsConstructible::Value) && (!(true && ... && TIsConvertible::Value)) constexpr explicit TTuple(ArgTypes&&... Args) : Super(NAMESPACE_PRIVATE::ForwardingConstructor, Forward(Args)...) { } template requires (sizeof...(OtherTypes) == ElementSize) && (true && ... && TIsConstructible::Value) && ((ElementSize != 1) || !(TIsConvertible&, typename TElementType<0>::Type>::Value || TIsConstructible::Type, const TTuple&>::Value || TIsSame::Type, typename TTuple::template TElementType<0>::Type>::Value)) && (true && ... && TIsConvertible::Value) constexpr TTuple(const TTuple& InValue) : Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue) { } template requires (sizeof...(OtherTypes) == ElementSize) && (true && ... && TIsConstructible::Value) && ((ElementSize != 1) || !(TIsConvertible&, typename TElementType<0>::Type>::Value || TIsConstructible::Type, const TTuple&>::Value || TIsSame::Type, typename TTuple::template TElementType<0>::Type>::Value)) && (!(true && ... && TIsConvertible::Value)) constexpr explicit TTuple(const TTuple& InValue) : Super(NAMESPACE_PRIVATE::OtherTupleConstructor, InValue) { } template requires (sizeof...(OtherTypes) == ElementSize) && (true && ... && TIsConstructible::Value) && ((ElementSize != 1) || !(TIsConvertible&&, typename TElementType<0>::Type>::Value || TIsConstructible::Type, TTuple&&>::Value || TIsSame::Type, typename TTuple::template TElementType<0>::Type>::Value)) && (true && ... && TIsConvertible::Value) constexpr TTuple(TTuple&& InValue) : Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue)) { } template requires (sizeof...(OtherTypes) == ElementSize) && (true && ... && TIsConstructible::Value) && ((ElementSize != 1) || !(TIsConvertible&&, typename TElementType<0>::Type>::Value || TIsConstructible::Type, TTuple&&>::Value || TIsSame::Type, typename TTuple::template TElementType<0>::Type>::Value)) && (!(true && ... && TIsConvertible::Value)) constexpr explicit TTuple(TTuple&& InValue) : Super(NAMESPACE_PRIVATE::OtherTupleConstructor, MoveTemp(InValue)) { } TTuple(const TTuple&) = default; TTuple(TTuple&&) = default; template requires (sizeof...(OtherTypes) == ElementSize) && (true && ... && TIsAssignable::Value) constexpr TTuple& operator=(const TTuple& InValue) { Helper::Assign(*this, InValue); return *this; } template requires (sizeof...(OtherTypes) == ElementSize) && (true && ... && TIsAssignable::Value) constexpr TTuple& operator=(TTuple&& InValue) { Helper::Assign(*this, MoveTemp(InValue)); return *this; } TTuple& operator=(const TTuple&) = default; TTuple& operator=(TTuple&&) = default; template requires (I < ElementSize) constexpr TElementType::Type& GetValue() & { return static_cast< NAMESPACE_PRIVATE::TTupleElement::Type, I>& >(*this).GetValue(); } template requires (I < ElementSize) constexpr const TElementType::Type& GetValue() const & { return static_cast::Type, I>& >(*this).GetValue(); } template requires (I < ElementSize) constexpr volatile TElementType::Type& GetValue() volatile& { return static_cast< volatile NAMESPACE_PRIVATE::TTupleElement::Type, I>& >(*this).GetValue(); } template requires (I < ElementSize) constexpr const volatile TElementType::Type& GetValue() const volatile& { return static_cast::Type, I>& >(*this).GetValue(); } template requires (I < ElementSize) constexpr TElementType::Type&& GetValue() && { return static_cast< NAMESPACE_PRIVATE::TTupleElement::Type, I>&&>(*this).GetValue(); } template requires (I < ElementSize) constexpr const TElementType::Type&& GetValue() const && { return static_cast::Type, I>&&>(*this).GetValue(); } template requires (I < ElementSize) constexpr volatile TElementType::Type&& GetValue() volatile&& { return static_cast< volatile NAMESPACE_PRIVATE::TTupleElement::Type, I>&&>(*this).GetValue(); } template requires (I < ElementSize) constexpr const volatile TElementType::Type&& GetValue() const volatile&& { return static_cast::Type, I>&&>(*this).GetValue(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr T& GetValue() & { return static_cast< TTuple& >(*this).GetValue::Value>(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr const T& GetValue() const & { return static_cast(*this).GetValue::Value>(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr volatile T& GetValue() volatile& { return static_cast< volatile TTuple& >(*this).GetValue::Value>(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr const volatile T& GetValue() const volatile& { return static_cast(*this).GetValue::Value>(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr T&& GetValue() && { return static_cast< TTuple&&>(*this).GetValue::Value>(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr const T&& GetValue() const && { return static_cast(*this).GetValue::Value>(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr volatile T&& GetValue() volatile&& { return static_cast< volatile TTuple&&>(*this).GetValue::Value>(); } template requires (TElementIndex::Value != INDEX_NONE) constexpr const volatile T&& GetValue() const volatile&& { return static_cast(*this).GetValue::Value>(); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) & { return Helper::Apply(Forward(Func), static_cast< TTuple& >(*this)); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) const & { return Helper::Apply(Forward(Func), static_cast(*this)); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) volatile& { return Helper::Apply(Forward(Func), static_cast< volatile TTuple& >(*this)); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) const volatile& { return Helper::Apply(Forward(Func), static_cast(*this)); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) && { return Helper::Apply(Forward(Func), static_cast< TTuple&&>(*this)); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) const && { return Helper::Apply(Forward(Func), static_cast(*this)); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) volatile&& { return Helper::Apply(Forward(Func), static_cast< volatile TTuple&&>(*this)); } template requires TIsInvocable::Value constexpr auto Apply(F&& Func) const volatile&& { return Helper::Apply(Forward(Func), static_cast(*this)); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) & { return Helper::ApplyAfter(Forward(Func), static_cast< TTuple& >(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const & { return Helper::ApplyAfter(Forward(Func), static_cast(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) volatile& { return Helper::ApplyAfter(Forward(Func), static_cast< volatile TTuple& >(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const volatile& { return Helper::ApplyAfter(Forward(Func), static_cast(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) && { return Helper::ApplyAfter(Forward(Func), static_cast< TTuple&&>(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const && { return Helper::ApplyAfter(Forward(Func), static_cast(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) volatile&& { return Helper::ApplyAfter(Forward(Func), static_cast< volatile TTuple&&>(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyAfter(F&& Func, ArgTypes&&... Args) const volatile&& { return Helper::ApplyAfter(Forward(Func), static_cast(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) & { return Helper::ApplyBefore(Forward(Func), static_cast< TTuple& >(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const & { return Helper::ApplyBefore(Forward(Func), static_cast(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) volatile& { return Helper::ApplyBefore(Forward(Func), static_cast< volatile TTuple& >(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const volatile& { return Helper::ApplyBefore(Forward(Func), static_cast(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) && { return Helper::ApplyBefore(Forward(Func), static_cast< TTuple&&>(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const && { return Helper::ApplyBefore(Forward(Func), static_cast(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) volatile&& { return Helper::ApplyBefore(Forward(Func), static_cast< volatile TTuple&&>(*this), Forward(Args)...); } template requires TIsInvocable::Value constexpr auto ApplyBefore(F&& Func, ArgTypes&&... Args) const volatile&& { return Helper::ApplyBefore(Forward(Func), static_cast(*this), Forward(Args)...); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) & { return Helper::Transform(Forward(Func), static_cast< TTuple& >(*this)); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) const & { return Helper::Transform(Forward(Func), static_cast(*this)); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) volatile& { return Helper::Transform(Forward(Func), static_cast< volatile TTuple& >(*this)); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) const volatile& { return Helper::Transform(Forward(Func), static_cast(*this)); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) && { return Helper::Transform(Forward(Func), static_cast< TTuple&&>(*this)); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) const && { return Helper::Transform(Forward(Func), static_cast(*this)); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) volatile&& { return Helper::Transform(Forward(Func), static_cast< volatile TTuple&&>(*this)); } template requires (true && ... && (TIsInvocable::Value && !TIsSame::Type>::Value)) constexpr auto Transform(F&& Func) const volatile&& { return Helper::Transform(Forward(Func), static_cast(*this)); } template requires TIsConstructible::Value constexpr T Construct() & { return Helper::template Construct(static_cast< TTuple& >(*this)); } template requires TIsConstructible::Value constexpr T Construct() const & { return Helper::template Construct(static_cast(*this)); } template requires TIsConstructible::Value constexpr T Construct() volatile& { return Helper::template Construct(static_cast< volatile TTuple& >(*this)); } template requires TIsConstructible::Value constexpr T Construct() const volatile& { return Helper::template Construct(static_cast(*this)); } template requires TIsConstructible::Value constexpr T Construct() && { return Helper::template Construct(static_cast< TTuple&&>(*this)); } template requires TIsConstructible::Value constexpr T Construct() const && { return Helper::template Construct(static_cast(*this)); } template requires TIsConstructible::Value constexpr T Construct() volatile&& { return Helper::template Construct(static_cast< volatile TTuple&&>(*this)); } template requires TIsConstructible::Value constexpr T Construct() const volatile&& { return Helper::template Construct(static_cast(*this)); } constexpr size_t GetTypeHash() const requires (true && ... && CHashable) { return [this](TIndexSequence) -> size_t { return HashCombine(NAMESPACE_REDCRAFT::GetTypeHash(GetValue())...); } (TMakeIndexSequence()); } constexpr void Swap(TTuple& InValue) requires (true && ... && (TIsMoveConstructible::Value&& TIsSwappable::Value)) { [&A = *this, &B = InValue](TIndexSequence) { ((NAMESPACE_REDCRAFT::Swap(A.template GetValue(), B.template GetValue())), ...); } (TMakeIndexSequence()); } }; template TTuple(Types...) -> TTuple; template using TPair = TTuple; template struct TIsTTuple : FFalse { }; template struct TIsTTuple> : FTrue { }; template requires TIsTTuple::Type>::Value struct TTupleElementSize : TConstant::Type::ElementSize> { }; template requires TIsTTuple::Type>::Value struct TTupleElementType { using Type = typename TCopyCVRef::Type, typename TRemoveCVRef::Type::template TElementType::Type>::Type; }; template requires TIsTTuple::Type>::Value struct TTupleElementIndex : TupleType::template TElementIndex { }; template constexpr TTuple::Type...> MakeTuple(Types&&... Args) { return TTuple::Type...>(Forward(Args)...); } template constexpr TTuple Tie(Types&... Args) { return TTuple(Args...); } template constexpr TTuple ForwardAsTuple(Types&&... Args) { return TTuple(Forward(Args)...); } NAMESPACE_PRIVATE_BEGIN struct FTupleEndFlag { }; template struct TTupleCatResultImpl; template struct TTupleCatResultImpl, TTupleTypes...> { using Type = typename TTupleCatResultImpl::Type; }; template struct TTupleCatResultImpl { using Type = TTuple; }; template struct TTupleCatMake; template struct TTupleCatMake, TIndexSequence> { template struct ForwardType { using Type = typename TConditional::Value, typename TRemoveReference::Type&&, U>::Type; }; template static constexpr TTuple F(TTupleType&& InValue) { return TTuple ( static_cast(InValue).template GetValue())>::Type> ( Forward(InValue).template GetValue() )... ); } }; template struct TTupleCatForward; template struct TTupleCatForward, TIndexSequence> { template static constexpr auto F(ForwardType&& ForwardTuple, TTupleType&& InValue) { return ForwardAsTuple(Forward(ForwardTuple).template GetValue()..., Forward(InValue).template GetValue()...); } }; template struct TTupleCatImpl { template static constexpr auto F(ForwardType&& ForwardTuple, TTupleType&& InValue, OtherTTupleTypes&&... OtherValue) { return F(TTupleCatForward::Value>, TMakeIndexSequence::Value>>::F(Forward(ForwardTuple), Forward(InValue)), Forward(OtherValue)...); } template static constexpr auto F(ForwardType&& ForwardTuple) { return TTupleCatMake::Value>>::F(Forward(ForwardTuple)); } }; template struct TTupleThreeWay; template struct TTupleThreeWay> { template static constexpr R F(const LHSTupleType& LHS, const RHSTupleType& RHS) { auto Result = SynthThreeWayCompare(LHS.template GetValue(), RHS.template GetValue()); if (Result != 0) return Result; return TTupleThreeWay>::F(LHS, RHS); } }; template struct TTupleThreeWay> { template static constexpr R F(const LHSTupleType& LHS, const RHSTupleType& RHS) { return R::equivalent; } }; template struct TTupleVisitImpl; template struct TTupleVisitImpl> { template static constexpr void F(G&& Func, TupleTypes&&... Tuples) { Invoke(Forward(Func), Forward(Tuples).template GetValue()...); TTupleVisitImpl>::F(Forward(Func), Forward(Tuples)...); } }; template <> struct TTupleVisitImpl> { template static constexpr void F(TupleTypes&&... Tuples) { } }; NAMESPACE_PRIVATE_END template requires (true && ... && (TIsTTuple::Type>::Value)) struct TTupleCatResult { using Type = typename NAMESPACE_PRIVATE::TTupleCatResultImpl::Type..., NAMESPACE_PRIVATE::FTupleEndFlag>::Type; }; template requires (true && ... && (TIsTTuple::Type>::Value)) constexpr auto TupleCat(TTupleTypes&&... Args) { using R = typename TTupleCatResult::Type; if constexpr (sizeof...(Args) == 0) return R(); else return NAMESPACE_PRIVATE::TTupleCatImpl::F(Forward(Args)...); } template requires ((sizeof...(LHSTypes) != sizeof...(RHSTypes)) || (true && ... && CWeaklyEqualityComparableWith)) constexpr bool operator==(const TTuple& LHS, const TTuple& RHS) { if constexpr (sizeof...(LHSTypes) != sizeof...(RHSTypes)) return false; return[&LHS, &RHS](TIndexSequence) -> bool { return (true && ... && (LHS.template GetValue() == RHS.template GetValue())); } (TMakeIndexSequence()); } template requires ((sizeof...(LHSTypes) == sizeof...(RHSTypes)) && (true && ... && (CSynthThreeWayComparableWith))) constexpr typename TCommonComparisonCategory::Type...>::Type operator<=>(const TTuple& LHS, const TTuple& RHS) { using R = typename TCommonComparisonCategory::Type...>::Type; return NAMESPACE_PRIVATE::TTupleThreeWay>::F(LHS, RHS); } template requires TIsInvocable::Value constexpr void VisitTuple(F&& Func) { } template constexpr void VisitTuple(F&& Func, FirstTupleType&& FirstTuple, TupleTypes&&... Tuples) { NAMESPACE_PRIVATE::TTupleVisitImpl::Value>>::F(Forward(Func), Forward(FirstTuple), Forward(Tuples)...); } NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END NAMESPACE_STD_BEGIN // Support structure binding, should not be directly used template struct tuple_size> : integral_constant>::Value> { }; template struct tuple_element> { using type = typename NAMESPACE_REDCRAFT::TTupleElementType>::Type; }; NAMESPACE_STD_END NAMESPACE_REDCRAFT_BEGIN NAMESPACE_MODULE_BEGIN(Redcraft) NAMESPACE_MODULE_BEGIN(Utility) // Support structure binding, should not be directly used template constexpr typename TTupleElementType>::Type& get( NAMESPACE_REDCRAFT::TTuple& InValue) { return static_cast< typename TTupleElementType>::Type& >(InValue.template GetValue()); } template constexpr const typename TTupleElementType>::Type& get(const NAMESPACE_REDCRAFT::TTuple& InValue) { return static_cast>::Type& >(InValue.template GetValue()); } template constexpr volatile typename TTupleElementType>::Type& get( volatile NAMESPACE_REDCRAFT::TTuple& InValue) { return static_cast< volatile typename TTupleElementType>::Type& >(InValue.template GetValue()); } template constexpr const volatile typename TTupleElementType>::Type& get(const volatile NAMESPACE_REDCRAFT::TTuple& InValue) { return static_cast>::Type& >(InValue.template GetValue()); } template constexpr typename TTupleElementType>::Type&& get( NAMESPACE_REDCRAFT::TTuple&& InValue) { return static_cast< typename TTupleElementType>::Type&&>(InValue.template GetValue()); } template constexpr const typename TTupleElementType>::Type&& get(const NAMESPACE_REDCRAFT::TTuple&& InValue) { return static_cast>::Type&&>(InValue.template GetValue()); } template constexpr volatile typename TTupleElementType>::Type&& get( volatile NAMESPACE_REDCRAFT::TTuple&& InValue) { return static_cast< volatile typename TTupleElementType>::Type&&>(InValue.template GetValue()); } template constexpr const volatile typename TTupleElementType>::Type&& get(const volatile NAMESPACE_REDCRAFT::TTuple&& InValue) { return static_cast>::Type&&>(InValue.template GetValue()); } NAMESPACE_MODULE_END(Utility) NAMESPACE_MODULE_END(Redcraft) NAMESPACE_REDCRAFT_END