fix(templates): fix TTuple requires and implementations to avoid compilation failures

This commit is contained in:
Redstone1024 2025-01-03 01:12:39 +08:00
parent 39d12bd7e4
commit 0e7ee5cde2
2 changed files with 78 additions and 69 deletions

View File

@ -1001,13 +1001,13 @@ void TestTuple()
{
TTuple<int32, char> TempA = { 1, 'A' };
TempA.Visit([](auto&& A) { A++; });
TempA.Visit([](auto&& A) -> void { ++A; });
TempA.Visit(
[]<typename T> (T&& A)
{
if constexpr (CSameAs<T&&, int32&>) always_check(A == 2);
else if constexpr (CSameAs<T&&, char&>) always_check(A == 'B');
if constexpr (CSameAs<T&&, int32&>) always_check(A == 2 );
else if constexpr (CSameAs<T&&, char &>) always_check(A == 'B');
else always_check_no_entry();
}
);

View File

@ -278,28 +278,37 @@ struct TTTupleSynthThreeWayComparable<TTypeSequence<>, TTypeSequence<>> : FTrue
template <typename TSequence, typename USequence>
concept CTTupleSynthThreeWayComparable = TTTupleSynthThreeWayComparable<TSequence, USequence>::Value;
template <typename Ret, typename Indices>
struct TTupleVisitElementByIndex;
template <typename Ret, size_t I, size_t... Indices>
struct TTupleVisitElementByIndex<Ret, TIndexSequence<I, Indices...>>
template <typename Ret, typename F, typename TTupleType>
struct TTupleVisitElementByIndex
{
template <typename F, typename TTupleType>
FORCEINLINE static constexpr decltype(auto) Do(F&& Func, TTupleType&& Arg, size_t Index)
template <size_t Index>
struct TInvokeElement
{
if (Index == I) return InvokeResult<Ret>(Forward<F>(Func), Forward<TTupleType>(Arg).template GetValue<I>());
return TTupleVisitElementByIndex<Ret, TIndexSequence<Indices...>>::Do(Forward<F>(Func), Forward<TTupleType>(Arg), Index);
}
};
FORCEINLINE static constexpr Ret Do(F&& Func, TTupleType&& Arg)
{
return InvokeResult<Ret>(Forward<F>(Func), Forward<TTupleType>(Arg).template GetValue<Index>());
}
};
template <typename Ret>
struct TTupleVisitElementByIndex<Ret, TIndexSequence<>>
{
template <typename F, typename TTupleType>
FORCEINLINE static constexpr decltype(auto) Do(F&& Func, TTupleType&& Arg, size_t)
template <typename>
struct TInvokeTuple;
template <size_t... Indices>
struct TInvokeTuple<TIndexSequence<Indices...>>
{
checkf(false, "Read access violation. Please check Index.");
return InvokeResult<Ret>(Forward<F>(Func), Forward<TTupleType>(Arg).template GetValue<0>());
FORCEINLINE static constexpr Ret Do(F&& Func, TTupleType&& Arg, size_t Index)
{
using FInvokeImplType = Ret(*)(F&&, TTupleType&&);
constexpr FInvokeImplType InvokeImpl[] = { TInvokeElement<Indices>::Do... };
return InvokeImpl[Index](Forward<F>(Func), Forward<TTupleType>(Arg));
}
};
FORCEINLINE static constexpr Ret Do(F&& Func, TTupleType&& Arg, size_t Index)
{
return TInvokeTuple<TMakeIndexSequence<Arg.Num()>>::Do(Forward<F>(Func), Forward<TTupleType>(Arg), Index);
}
};
@ -421,64 +430,64 @@ public:
template <typename T> NODISCARD FORCEINLINE constexpr decltype(auto) GetValue() const volatile&& { return static_cast<const volatile TTuple&&>(*this).GetValue<TTupleIndex<T, TTuple>>(); }
/** Invoke the callable object 'Func' with a tuple of arguments. */
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) & { return FHelper::Apply(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const & { return FHelper::Apply(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile& { return FHelper::Apply(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile& { return FHelper::Apply(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) && { return FHelper::Apply(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const && { return FHelper::Apply(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile&& { return FHelper::Apply(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F, Ts...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile&& { return FHelper::Apply(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F&&, Ts& ...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) & { return FHelper::Apply(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (CInvocable<F&&, const Ts& ...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const & { return FHelper::Apply(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (CInvocable<F&&, volatile Ts& ...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile& { return FHelper::Apply(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F&&, const volatile Ts& ...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile& { return FHelper::Apply(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (CInvocable<F&&, Ts&&...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) && { return FHelper::Apply(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F&&, const Ts&&...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const && { return FHelper::Apply(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F&&, volatile Ts&&...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) volatile&& { return FHelper::Apply(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (CInvocable<F&&, const volatile Ts&&...>) FORCEINLINE constexpr decltype(auto) Apply(F&& Func) const volatile&& { return FHelper::Apply(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
/** Visits each element in a tuple in parallel and applies it as arguments to the function. */
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) & { VisitTuple(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) const & { VisitTuple(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) volatile& { VisitTuple(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) const volatile& { VisitTuple(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) && { VisitTuple(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) const && { VisitTuple(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) volatile&& { VisitTuple(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && CInvocable<F, Ts>) FORCEINLINE constexpr void Visit(F&& Func) const volatile&& { VisitTuple(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, Ts& >) FORCEINLINE constexpr void Visit(F&& Func) & { VisitTuple(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, const Ts& >) FORCEINLINE constexpr void Visit(F&& Func) const & { VisitTuple(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, volatile Ts& >) FORCEINLINE constexpr void Visit(F&& Func) volatile& { VisitTuple(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, const volatile Ts& >) FORCEINLINE constexpr void Visit(F&& Func) const volatile& { VisitTuple(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, Ts&&>) FORCEINLINE constexpr void Visit(F&& Func) && { VisitTuple(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, const Ts&&>) FORCEINLINE constexpr void Visit(F&& Func) const && { VisitTuple(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, volatile Ts&&>) FORCEINLINE constexpr void Visit(F&& Func) volatile&& { VisitTuple(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && CInvocable<F&&, const volatile Ts&&>) FORCEINLINE constexpr void Visit(F&& Func) const volatile&& { VisitTuple(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
/** Visits specified element in a tuple and applies it as arguments to the function. */
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) & { return static_cast< TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const & { return static_cast<const TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) volatile& { return static_cast< volatile TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const volatile& { return static_cast<const volatile TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) && { return static_cast< TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const && { return static_cast<const TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) volatile&& { return static_cast< volatile TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires ((sizeof...(Ts) >= 1 && CCommonReference<TInvokeResult<F, Ts>...>) && ... && (CInvocable<F, Ts>)) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const volatile&& { return static_cast<const volatile TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F, Ts>...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, Ts& >) && CCommonReference<TInvokeResult<F&&, Ts& >...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) & { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast< TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F&&, Ts& >...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, const Ts& >) && CCommonReference<TInvokeResult<F&&, const Ts& >...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const & { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast<const TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F&&, const Ts& >...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, volatile Ts& >) && CCommonReference<TInvokeResult<F&&, volatile Ts& >...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) volatile& { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast< volatile TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F&&, volatile Ts& >...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, const volatile Ts& >) && CCommonReference<TInvokeResult<F&&, const volatile Ts& >...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const volatile& { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast<const volatile TTuple& >(*this).Visit<TCommonReference<TInvokeResult<F&&, const volatile Ts& >...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, Ts&&>) && CCommonReference<TInvokeResult<F&&, Ts&&>...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) && { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast< TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F&&, Ts&&>...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, const Ts&&>) && CCommonReference<TInvokeResult<F&&, const Ts&&>...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const && { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast<const TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F&&, const Ts&&>...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, volatile Ts&&>) && CCommonReference<TInvokeResult<F&&, volatile Ts&&>...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) volatile&& { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast< volatile TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F&&, volatile Ts&&>...>>(Forward<F>(Func), Index); }
template <typename F> requires (((sizeof...(Ts) >= 1) && ... && CInvocable<F&&, const volatile Ts&&>) && CCommonReference<TInvokeResult<F&&, const volatile Ts&&>...>) FORCEINLINE constexpr decltype(auto) Visit(F&& Func, size_t Index) const volatile&& { checkf(Index < Num(), "Read access violation. Please check Index."); return static_cast<const volatile TTuple&&>(*this).Visit<TCommonReference<TInvokeResult<F&&, const volatile Ts&&>...>>(Forward<F>(Func), Index); }
/** Visits specified element in a tuple and applies it as arguments to the function. */
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) & { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast< TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const & { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast<const TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) volatile& { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast< volatile TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const volatile& { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast<const volatile TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) && { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast< TTuple&&>(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const && { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast<const TTuple&&>(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) volatile&& { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast< volatile TTuple&&>(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F, Ts>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const volatile&& { return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, TMakeIndexSequence<sizeof...(Ts)>>::Do(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, Ts& >) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) & { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, TTuple& >::Do(Forward<F>(Func), static_cast< TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, const Ts& >) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const & { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, const TTuple& >::Do(Forward<F>(Func), static_cast<const TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, volatile Ts& >) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) volatile& { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, volatile TTuple& >::Do(Forward<F>(Func), static_cast< volatile TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, const volatile Ts& >) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const volatile& { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, const volatile TTuple& >::Do(Forward<F>(Func), static_cast<const volatile TTuple& >(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, Ts&&>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) && { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, TTuple&&>::Do(Forward<F>(Func), static_cast< TTuple&&>(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, const Ts&&>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const && { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, const TTuple&&>::Do(Forward<F>(Func), static_cast<const TTuple&&>(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, volatile Ts&&>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) volatile&& { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, volatile TTuple&&>::Do(Forward<F>(Func), static_cast< volatile TTuple&&>(*this), Index); }
template <typename Ret, typename F> requires ((sizeof...(Ts) >= 1) && ... && CInvocableResult<Ret, F&&, const volatile Ts&&>) FORCEINLINE constexpr Ret Visit(F&& Func, size_t Index) const volatile&& { checkf(Index < Num(), "Read access violation. Please check Index."); return NAMESPACE_PRIVATE::TTupleVisitElementByIndex<Ret, F, const volatile TTuple&&>::Do(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this), Index); }
/** Transform a tuple into another tuple using the given function. */
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) & { return FHelper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const & { return FHelper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile& { return FHelper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile& { return FHelper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) && { return FHelper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const && { return FHelper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile&& { return FHelper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F, Ts> && !CSameAs<void, TInvokeResult<F, Ts>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile&& { return FHelper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, Ts& > && !CSameAs<void, TInvokeResult<F&&, Ts& >>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) & { return FHelper::Transform(Forward<F>(Func), static_cast< TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, const Ts& > && !CSameAs<void, TInvokeResult<F&&, const Ts& >>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const & { return FHelper::Transform(Forward<F>(Func), static_cast<const TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, volatile Ts& > && !CSameAs<void, TInvokeResult<F&&, volatile Ts& >>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile& { return FHelper::Transform(Forward<F>(Func), static_cast< volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, const volatile Ts& > && !CSameAs<void, TInvokeResult<F&&, const volatile Ts& >>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile& { return FHelper::Transform(Forward<F>(Func), static_cast<const volatile TTuple& >(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, Ts&&> && !CSameAs<void, TInvokeResult<F&&, Ts&&>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) && { return FHelper::Transform(Forward<F>(Func), static_cast< TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, const Ts&&> && !CSameAs<void, TInvokeResult<F&&, const Ts&&>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const && { return FHelper::Transform(Forward<F>(Func), static_cast<const TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, volatile Ts&&> && !CSameAs<void, TInvokeResult<F&&, volatile Ts&&>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) volatile&& { return FHelper::Transform(Forward<F>(Func), static_cast< volatile TTuple&&>(*this)); }
template <typename F> requires (true && ... && (CInvocable<F&&, const volatile Ts&&> && !CSameAs<void, TInvokeResult<F&&, const volatile Ts&&>>)) NODISCARD FORCEINLINE constexpr decltype(auto) Transform(F&& Func) const volatile&& { return FHelper::Transform(Forward<F>(Func), static_cast<const volatile TTuple&&>(*this)); }
/** Constructs an object of type T with a tuple as an argument. */
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() & { return FHelper::template Construct<T>(static_cast< TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const & { return FHelper::template Construct<T>(static_cast<const TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() volatile& { return FHelper::template Construct<T>(static_cast< volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile& { return FHelper::template Construct<T>(static_cast<const volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() && { return FHelper::template Construct<T>(static_cast< TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const && { return FHelper::template Construct<T>(static_cast<const TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() volatile&& { return FHelper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile&& { return FHelper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts& ...>) NODISCARD FORCEINLINE constexpr T Construct() & { return FHelper::template Construct<T>(static_cast< TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, const Ts& ...>) NODISCARD FORCEINLINE constexpr T Construct() const & { return FHelper::template Construct<T>(static_cast<const TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, volatile Ts& ...>) NODISCARD FORCEINLINE constexpr T Construct() volatile& { return FHelper::template Construct<T>(static_cast< volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, const volatile Ts& ...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile& { return FHelper::template Construct<T>(static_cast<const volatile TTuple& >(*this)); }
template <typename T> requires (CConstructibleFrom<T, Ts&&...>) NODISCARD FORCEINLINE constexpr T Construct() && { return FHelper::template Construct<T>(static_cast< TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, const Ts&&...>) NODISCARD FORCEINLINE constexpr T Construct() const && { return FHelper::template Construct<T>(static_cast<const TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, volatile Ts&&...>) NODISCARD FORCEINLINE constexpr T Construct() volatile&& { return FHelper::template Construct<T>(static_cast< volatile TTuple&&>(*this)); }
template <typename T> requires (CConstructibleFrom<T, const volatile Ts&&...>) NODISCARD FORCEINLINE constexpr T Construct() const volatile&& { return FHelper::template Construct<T>(static_cast<const volatile TTuple&&>(*this)); }
/** @return The number of elements in the tuple. */
NODISCARD static FORCEINLINE constexpr size_t Num() { return sizeof...(Ts); }