File indexing completed on 2025-08-02 08:28:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #pragma once
0021
0022 #include "PTL/ConsumeParameters.hh"
0023
0024 #include <cstddef>
0025 #include <tuple>
0026 #include <type_traits>
0027 #include <utility>
0028
0029
0030
0031 namespace PTL
0032 {
0033
0034 template <typename T>
0035 using decay_t = typename std::decay<T>::type;
0036
0037 template <bool B, typename T = void>
0038 using enable_if_t = typename std::enable_if<B, T>::type;
0039
0040
0041 namespace impl
0042 {
0043
0044
0045
0046 template <size_t... Indexes>
0047 struct Index_tuple
0048 {};
0049
0050
0051 template <typename Itup1, typename Itup2>
0052 struct Itup_cat;
0053
0054 template <size_t... Ind1, size_t... Ind2>
0055 struct Itup_cat<Index_tuple<Ind1...>, Index_tuple<Ind2...>>
0056 {
0057 using __type = Index_tuple<Ind1..., (Ind2 + sizeof...(Ind1))...>;
0058 };
0059
0060
0061 template <size_t NumT>
0062 struct Build_index_tuple
0063 : Itup_cat<typename Build_index_tuple<NumT / 2>::__type,
0064 typename Build_index_tuple<NumT - NumT / 2>::__type>
0065 {};
0066
0067 template <>
0068 struct Build_index_tuple<1>
0069 {
0070 using __type = Index_tuple<0>;
0071 };
0072
0073 template <>
0074 struct Build_index_tuple<0>
0075 {
0076 using __type = Index_tuple<>;
0077 };
0078
0079
0080 template <typename Tp, Tp... Idx>
0081 struct integer_sequence
0082 {
0083 using value_type = Tp;
0084 static constexpr size_t size() noexcept { return sizeof...(Idx); }
0085 };
0086
0087 template <typename Tp, Tp NumT, typename ISeq = typename Build_index_tuple<NumT>::__type>
0088 struct Make_integer_sequence;
0089
0090 template <typename Tp, Tp NumT, size_t... Idx>
0091 struct Make_integer_sequence<Tp, NumT, Index_tuple<Idx...>>
0092 {
0093 static_assert(NumT >= 0, "Cannot make integer sequence of negative length");
0094
0095 using __type = integer_sequence<Tp, static_cast<Tp>(Idx)...>;
0096 };
0097
0098
0099 template <typename Tp, Tp NumT>
0100 using make_integer_sequence = typename Make_integer_sequence<Tp, NumT>::__type;
0101
0102
0103 template <size_t... Idx>
0104 using index_sequence = integer_sequence<size_t, Idx...>;
0105
0106
0107 template <size_t NumT>
0108 using make_index_sequence = make_integer_sequence<size_t, NumT>;
0109
0110 template <typename FnT, typename TupleT, size_t... Idx>
0111 static inline auto
0112 apply(FnT&& _func, TupleT _args, impl::index_sequence<Idx...>)
0113 -> decltype(std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...))
0114 {
0115
0116 #if defined(__GNUC__) && (__GNUC__ < 6)
0117 if(sizeof...(Idx) == 0)
0118 {
0119 ConsumeParameters(_args);
0120 }
0121 #endif
0122 return std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...);
0123 }
0124
0125
0126
0127 }
0128
0129
0130
0131 template <typename FnT, typename TupleT>
0132 static inline void
0133 apply(FnT&& _func, TupleT&& _args)
0134 {
0135 using tuple_type = decay_t<TupleT>;
0136 constexpr auto N = std::tuple_size<tuple_type>::value;
0137 impl::apply(std::forward<FnT>(_func), std::forward<TupleT>(_args),
0138 impl::make_index_sequence<N>{});
0139 }
0140
0141 }