File indexing completed on 2025-01-18 09:57:46
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 <algorithm> // Retrieve definitions of min/max
0023
0024
0025 #include "PTL/Types.hh"
0026
0027
0028 #include "PTL/Utility.hh"
0029
0030 #include <initializer_list>
0031 #include <tuple>
0032 #include <type_traits>
0033 #include <utility>
0034
0035 #if !defined(PTL_NO_SANITIZE_THREAD)
0036
0037 # if defined(__has_attribute)
0038 # if __has_attribute(no_sanitize)
0039 # define PTL_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread")))
0040 # else
0041 # define PTL_NO_SANITIZE_THREAD
0042 # endif
0043 # elif defined(__clang__) || defined(__GNUC__)
0044 # define PTL_NO_SANITIZE_THREAD __attribute__((no_sanitize("thread")))
0045 # else
0046
0047 # define PTL_NO_SANITIZE_THREAD
0048 # endif
0049 #endif
0050
0051 namespace PTL
0052 {
0053 template <typename T>
0054 using decay_t = typename std::decay<T>::type;
0055
0056 template <bool B, typename T = void>
0057 using enable_if_t = typename std::enable_if<B, T>::type;
0058
0059
0060 namespace mpl
0061 {
0062
0063
0064 namespace impl
0065 {
0066
0067
0068
0069 template <size_t... Indexes>
0070 struct Index_tuple
0071 {};
0072
0073
0074 template <typename Itup1, typename Itup2>
0075 struct Itup_cat;
0076
0077 template <size_t... Ind1, size_t... Ind2>
0078 struct Itup_cat<Index_tuple<Ind1...>, Index_tuple<Ind2...>>
0079 {
0080 using __type = Index_tuple<Ind1..., (Ind2 + sizeof...(Ind1))...>;
0081 };
0082
0083
0084 template <size_t NumT>
0085 struct Build_index_tuple
0086 : Itup_cat<typename Build_index_tuple<NumT / 2>::__type,
0087 typename Build_index_tuple<NumT - NumT / 2>::__type>
0088 {};
0089
0090 template <>
0091 struct Build_index_tuple<1>
0092 {
0093 using __type = Index_tuple<0>;
0094 };
0095
0096 template <>
0097 struct Build_index_tuple<0>
0098 {
0099 using __type = Index_tuple<>;
0100 };
0101
0102
0103 template <typename Tp, Tp... Idx>
0104 struct integer_sequence
0105 {
0106 using value_type = Tp;
0107 static constexpr size_t size() noexcept { return sizeof...(Idx); }
0108 };
0109
0110 template <typename Tp, Tp NumT, typename ISeq = typename Build_index_tuple<NumT>::__type>
0111 struct Make_integer_sequence;
0112
0113 template <typename Tp, Tp NumT, size_t... Idx>
0114 struct Make_integer_sequence<Tp, NumT, Index_tuple<Idx...>>
0115 {
0116 static_assert(NumT >= 0, "Cannot make integer sequence of negative length");
0117
0118 using __type = integer_sequence<Tp, static_cast<Tp>(Idx)...>;
0119 };
0120
0121
0122 template <typename Tp, Tp NumT>
0123 using make_integer_sequence = typename Make_integer_sequence<Tp, NumT>::__type;
0124
0125
0126 template <size_t... Idx>
0127 using index_sequence = integer_sequence<size_t, Idx...>;
0128
0129
0130 template <size_t NumT>
0131 using make_index_sequence = make_integer_sequence<size_t, NumT>;
0132
0133
0134 template <typename... Types>
0135 using index_sequence_for = make_index_sequence<sizeof...(Types)>;
0136
0137 template <size_t Idx, typename Tup>
0138 using index_type_t = decay_t<decltype(std::get<Idx>(std::declval<Tup>()))>;
0139
0140 template <typename FnT, typename TupleT, size_t... Idx>
0141 static inline auto
0142 apply(FnT&& _func, TupleT _args, impl::index_sequence<Idx...>)
0143 -> decltype(std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...))
0144 {
0145
0146 #if defined(__GNUC__) && (__GNUC__ < 6)
0147 if(sizeof...(Idx) == 0)
0148 {
0149 ConsumeParameters(_args);
0150 }
0151 #endif
0152 return std::forward<FnT>(_func)(std::get<Idx>(std::move(_args))...);
0153 }
0154
0155
0156
0157 }
0158
0159
0160
0161
0162 template <size_t... Idx>
0163 using index_sequence = impl::integer_sequence<size_t, Idx...>;
0164
0165
0166 template <size_t NumT>
0167 using make_index_sequence = impl::make_integer_sequence<size_t, NumT>;
0168
0169
0170 template <typename... Types>
0171 using index_sequence_for = impl::make_index_sequence<sizeof...(Types)>;
0172
0173 template <typename FnT, typename TupleT>
0174 static inline void
0175 apply(FnT&& _func, TupleT&& _args)
0176 {
0177 using tuple_type = typename std::decay<TupleT>::type;
0178 constexpr auto N = std::tuple_size<tuple_type>::value;
0179 impl::apply(std::forward<FnT>(_func), std::forward<TupleT>(_args),
0180 impl::make_index_sequence<N>{});
0181 }
0182
0183
0184
0185 }
0186
0187 }