File indexing completed on 2025-01-18 10:12:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_template_helpers_H
0018 #define __TBB_template_helpers_H
0019
0020 #include <utility>
0021 #include <cstddef>
0022 #include "../tbb_config.h"
0023 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
0024 #include <type_traits>
0025 #endif
0026 #if __TBB_CPP11_PRESENT
0027 #include <iterator>
0028 #include <memory> // allocator_traits
0029 #endif
0030
0031 namespace tbb { namespace internal {
0032
0033
0034 template<bool Condition, typename T = void> struct enable_if {};
0035 template<typename T> struct enable_if<true, T> { typedef T type; };
0036
0037
0038 template<typename T> struct strip { typedef T type; };
0039 template<typename T> struct strip<const T> { typedef T type; };
0040 template<typename T> struct strip<volatile T> { typedef T type; };
0041 template<typename T> struct strip<const volatile T> { typedef T type; };
0042 template<typename T> struct strip<T&> { typedef T type; };
0043 template<typename T> struct strip<const T&> { typedef T type; };
0044 template<typename T> struct strip<volatile T&> { typedef T type; };
0045 template<typename T> struct strip<const volatile T&> { typedef T type; };
0046
0047 template<typename T> struct strip<T(&)()> { typedef T(*type)(); };
0048 #if __TBB_CPP11_RVALUE_REF_PRESENT
0049 template<typename T> struct strip<T&&> { typedef T type; };
0050 template<typename T> struct strip<const T&&> { typedef T type; };
0051 template<typename T> struct strip<volatile T&&> { typedef T type; };
0052 template<typename T> struct strip<const volatile T&&> { typedef T type; };
0053 #endif
0054
0055 template<typename T, std::size_t N> struct strip<T(&)[N]> { typedef T* type; };
0056 template<typename T, std::size_t N> struct strip<const T(&)[N]> { typedef const T* type; };
0057 template<typename T, std::size_t N> struct strip<volatile T(&)[N]> { typedef volatile T* type; };
0058 template<typename T, std::size_t N> struct strip<const volatile T(&)[N]> { typedef const volatile T* type; };
0059
0060
0061 template<class U, class V> struct is_same_type { static const bool value = false; };
0062 template<class W> struct is_same_type<W,W> { static const bool value = true; };
0063
0064 template<typename T> struct is_ref { static const bool value = false; };
0065 template<typename U> struct is_ref<U&> { static const bool value = true; };
0066
0067
0068 template<typename T> struct is_integral_impl { static const bool value = false; };
0069 template<> struct is_integral_impl<bool> { static const bool value = true; };
0070 template<> struct is_integral_impl<char> { static const bool value = true; };
0071 #if __TBB_CPP11_PRESENT
0072 template<> struct is_integral_impl<char16_t> { static const bool value = true; };
0073 template<> struct is_integral_impl<char32_t> { static const bool value = true; };
0074 #endif
0075 template<> struct is_integral_impl<wchar_t> { static const bool value = true; };
0076 template<> struct is_integral_impl<short> { static const bool value = true; };
0077 template<> struct is_integral_impl<int> { static const bool value = true; };
0078 template<> struct is_integral_impl<long> { static const bool value = true; };
0079 template<> struct is_integral_impl<long long> { static const bool value = true; };
0080
0081 template<typename T>
0082 struct is_integral : is_integral_impl<typename strip<T>::type> {};
0083
0084 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
0085
0086 template<typename...> struct void_t { typedef void type; };
0087 #endif
0088
0089 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
0090
0091
0092 template<typename T, typename, template<typename> class... Checks>
0093 struct supports_impl { typedef std::false_type type; };
0094 template<typename T, template<typename> class... Checks>
0095 struct supports_impl<T, typename void_t<Checks<T>...>::type, Checks...> { typedef std::true_type type; };
0096
0097 template<typename T, template<typename> class... Checks>
0098 using supports = typename supports_impl<T, void, Checks...>::type;
0099
0100 #endif
0101
0102 #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
0103
0104
0105 template< typename... Types >
0106 struct stored_pack;
0107
0108 template<>
0109 struct stored_pack<>
0110 {
0111 typedef stored_pack<> pack_type;
0112 stored_pack() {}
0113
0114
0115 template< typename F, typename Pack > friend void call( F&& f, Pack&& p );
0116 template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p );
0117
0118 protected:
0119
0120
0121 template< typename Ret, typename F, typename... Preceding >
0122 static Ret call( F&& f, const pack_type& , Preceding&&... params ) {
0123 return std::forward<F>(f)( std::forward<Preceding>(params)... );
0124 }
0125 template< typename Ret, typename F, typename... Preceding >
0126 static Ret call( F&& f, pack_type&& , Preceding&&... params ) {
0127 return std::forward<F>(f)( std::forward<Preceding>(params)... );
0128 }
0129 };
0130
0131 template< typename T, typename... Types >
0132 struct stored_pack<T, Types...> : stored_pack<Types...>
0133 {
0134 typedef stored_pack<T, Types...> pack_type;
0135 typedef stored_pack<Types...> pack_remainder;
0136
0137
0138 typename strip<T>::type leftmost_value;
0139
0140
0141
0142 stored_pack( T&& t, Types&&... types )
0143 : pack_remainder(std::forward<Types>(types)...), leftmost_value(std::forward<T>(t)) {}
0144
0145
0146 template< typename F, typename Pack > friend void call( F&& f, Pack&& p );
0147 template< typename Ret, typename F, typename Pack > friend Ret call_and_return( F&& f, Pack&& p );
0148
0149 protected:
0150 template< typename Ret, typename F, typename... Preceding >
0151 static Ret call( F&& f, pack_type& pack, Preceding&&... params ) {
0152 return pack_remainder::template call<Ret>(
0153 std::forward<F>(f), static_cast<pack_remainder&>(pack),
0154 std::forward<Preceding>(params)... , pack.leftmost_value
0155 );
0156 }
0157 template< typename Ret, typename F, typename... Preceding >
0158 static Ret call( F&& f, const pack_type& pack, Preceding&&... params ) {
0159 return pack_remainder::template call<Ret>(
0160 std::forward<F>(f), static_cast<const pack_remainder&>(pack),
0161 std::forward<Preceding>(params)... , pack.leftmost_value
0162 );
0163 }
0164 template< typename Ret, typename F, typename... Preceding >
0165 static Ret call( F&& f, pack_type&& pack, Preceding&&... params ) {
0166 return pack_remainder::template call<Ret>(
0167 std::forward<F>(f), static_cast<pack_remainder&&>(pack),
0168 std::forward<Preceding>(params)... , std::move(pack.leftmost_value)
0169 );
0170 }
0171 };
0172
0173
0174 template< typename F, typename Pack >
0175 void call( F&& f, Pack&& p ) {
0176 strip<Pack>::type::template call<void>( std::forward<F>(f), std::forward<Pack>(p) );
0177 }
0178
0179 template< typename Ret, typename F, typename Pack >
0180 Ret call_and_return( F&& f, Pack&& p ) {
0181 return strip<Pack>::type::template call<Ret>( std::forward<F>(f), std::forward<Pack>(p) );
0182 }
0183
0184 template< typename... Types >
0185 stored_pack<Types...> save_pack( Types&&... types ) {
0186 return stored_pack<Types...>( std::forward<Types>(types)... );
0187 }
0188
0189 #endif
0190
0191 #if __TBB_CPP14_INTEGER_SEQUENCE_PRESENT
0192
0193 using std::index_sequence;
0194 using std::make_index_sequence;
0195
0196 #elif __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
0197
0198 template<std::size_t... S> class index_sequence {};
0199
0200 template<std::size_t N, std::size_t... S>
0201 struct make_index_sequence_impl : make_index_sequence_impl < N - 1, N - 1, S... > {};
0202
0203 template<std::size_t... S>
0204 struct make_index_sequence_impl <0, S...> {
0205 using type = index_sequence<S...>;
0206 };
0207
0208 template<std::size_t N>
0209 using make_index_sequence = typename tbb::internal::make_index_sequence_impl<N>::type;
0210
0211 #endif
0212
0213 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
0214 template<typename... Args>
0215 struct conjunction;
0216
0217 template<typename First, typename... Args>
0218 struct conjunction<First, Args...>
0219 : std::conditional<bool(First::value), conjunction<Args...>, First>::type {};
0220
0221 template<typename T>
0222 struct conjunction<T> : T {};
0223
0224 template<>
0225 struct conjunction<> : std::true_type {};
0226
0227 #endif
0228
0229 #if __TBB_CPP11_PRESENT
0230
0231 template< typename Iter >
0232 using iterator_value_t = typename std::iterator_traits<Iter>::value_type;
0233
0234 template< typename Iter >
0235 using iterator_key_t = typename std::remove_const<typename iterator_value_t<Iter>::first_type>::type;
0236
0237 template< typename Iter >
0238 using iterator_mapped_t = typename iterator_value_t<Iter>::second_type;
0239
0240 template< typename A > using value_type = typename A::value_type;
0241 template< typename A > using alloc_ptr_t = typename std::allocator_traits<A>::pointer;
0242 template< typename A > using has_allocate = decltype(std::declval<alloc_ptr_t<A>&>() = std::declval<A>().allocate(0));
0243 template< typename A > using has_deallocate = decltype(std::declval<A>().deallocate(std::declval<alloc_ptr_t<A>>(), 0));
0244
0245
0246 template< typename T >
0247 using is_allocator = supports<T, value_type, has_allocate, has_deallocate>;
0248
0249 #if __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT
0250
0251 template< typename T >
0252 static constexpr bool is_allocator_v = is_allocator<T>::value;
0253
0254 #endif
0255
0256 template< std::size_t N, typename... Args >
0257 struct pack_element {
0258 using type = void;
0259 };
0260
0261 template< std::size_t N, typename T, typename... Args >
0262 struct pack_element<N, T, Args...> {
0263 using type = typename pack_element<N - 1, Args...>::type;
0264 };
0265
0266 template< typename T, typename... Args >
0267 struct pack_element<0, T, Args...> {
0268 using type = T;
0269 };
0270
0271 template< std::size_t N, typename... Args >
0272 using pack_element_t = typename pack_element<N, Args...>::type;
0273
0274
0275
0276
0277 template <typename Comp, typename K>
0278 using is_transparent = typename std::conditional<true, Comp, K>::type::is_transparent;
0279
0280 #endif
0281
0282 template <typename F>
0283 struct body_arg_detector;
0284
0285 template <typename Callable, typename ReturnType, typename T>
0286 struct body_arg_detector<ReturnType(Callable::*)(T)> {
0287 typedef T arg_type;
0288 };
0289
0290 template <typename Callable, typename ReturnType, typename T>
0291 struct body_arg_detector<ReturnType(Callable::*)(T) const> {
0292 typedef T arg_type;
0293 };
0294
0295 #if __TBB_CPP11_PRESENT
0296 using std::conditional;
0297 #else
0298 template <bool C, typename T, typename U>
0299 struct conditional {
0300 typedef U type;
0301 };
0302
0303 template <typename T, typename U>
0304 struct conditional<true, T, U> {
0305 typedef T type;
0306 };
0307 #endif
0308
0309 } }
0310
0311 #endif