17 #ifndef __TBB_template_helpers_H
18 #define __TBB_template_helpers_H
22 #include "../tbb_config.h"
23 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
24 #include <type_traits>
26 #if __TBB_CPP11_PRESENT
34 template<
bool Condition,
typename T =
void>
struct enable_if {};
38 template<
typename T>
struct strip {
typedef T
type; };
39 template<
typename T>
struct strip<const T> {
typedef T
type; };
40 template<
typename T>
struct strip<volatile T> {
typedef T
type; };
41 template<
typename T>
struct strip<const volatile T> {
typedef T
type; };
42 template<
typename T>
struct strip<T&> {
typedef T
type; };
43 template<
typename T>
struct strip<const T&> {
typedef T
type; };
44 template<
typename T>
struct strip<volatile T&> {
typedef T
type; };
45 template<
typename T>
struct strip<const volatile T&> {
typedef T
type; };
47 template<
typename T>
struct strip<T(&)()> {
typedef T(*
type)(); };
48 #if __TBB_CPP11_RVALUE_REF_PRESENT
49 template<
typename T>
struct strip<T&&> {
typedef T
type; };
50 template<
typename T>
struct strip<const T&&> {
typedef T
type; };
51 template<
typename T>
struct strip<volatile T&&> {
typedef T
type; };
52 template<
typename T>
struct strip<const volatile T&&> {
typedef T
type; };
54 template<
typename T, std::
size_t N>
struct strip<T(&)[N]> {
typedef T*
type; };
56 template<
typename T, std::
size_t N>
struct strip<const T(&)[N]> {
typedef const T*
type; };
57 template<
typename T, std::
size_t N>
struct strip<volatile T(&)[N]> {
typedef volatile T*
type; };
58 template<
typename T, std::
size_t N>
struct strip<const volatile T(&)[N]> {
typedef const volatile T*
type; };
64 template<
typename T>
struct is_ref {
static const bool value =
false; };
65 template<
typename U>
struct is_ref<U&> {
static const bool value =
true; };
71 #if __TBB_CPP11_PRESENT
84 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
85 template<
typename...>
struct void_t {
typedef void type; };
89 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
92 template<
typename T,
typename,
template<
typename>
class... Checks>
94 template<
typename T,
template<
typename>
class... Checks>
97 template<
typename T,
template<
typename>
class... Checks>
98 using supports =
typename supports_impl<T,
void, Checks...>
::type;
102 #if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
105 template<
typename... Types >
111 typedef stored_pack<> pack_type;
115 template<
typename F,
typename Pack >
friend void call( F&& f, Pack&&
p );
116 template<
typename Ret,
typename F,
typename Pack >
friend Ret call_and_return( F&& f, Pack&&
p );
121 template<
typename Ret,
typename F,
typename... Preceding >
122 static Ret call( F&& f,
const pack_type& , Preceding&&... params ) {
123 return std::forward<F>(f)( std::forward<Preceding>(params)... );
125 template<
typename Ret,
typename F,
typename... Preceding >
126 static Ret call( F&& f, pack_type&& , Preceding&&... params ) {
127 return std::forward<F>(f)( std::forward<Preceding>(params)... );
131 template<
typename T,
typename... Types >
132 struct stored_pack<T, Types...> : stored_pack<Types...>
134 typedef stored_pack<T, Types...> pack_type;
135 typedef stored_pack<Types...> pack_remainder;
142 stored_pack( T&& t, Types&&... types )
143 : pack_remainder(std::forward<Types>(types)...), leftmost_value(std::forward<T>(t)) {}
146 template<
typename F,
typename Pack >
friend void call( F&& f, Pack&&
p );
147 template<
typename Ret,
typename F,
typename Pack >
friend Ret call_and_return( F&& f, Pack&&
p );
150 template<
typename Ret,
typename F,
typename... Preceding >
151 static Ret call( F&& f, pack_type& pack, Preceding&&... params ) {
152 return pack_remainder::template call<Ret>(
153 std::forward<F>(f),
static_cast<pack_remainder&
>(pack),
154 std::forward<Preceding>(params)... , pack.leftmost_value
157 template<
typename Ret,
typename F,
typename... Preceding >
158 static Ret call( F&& f,
const pack_type& pack, Preceding&&... params ) {
159 return pack_remainder::template call<Ret>(
160 std::forward<F>(f),
static_cast<const pack_remainder&
>(pack),
161 std::forward<Preceding>(params)... , pack.leftmost_value
164 template<
typename Ret,
typename F,
typename... Preceding >
165 static Ret call( F&& f, pack_type&& pack, Preceding&&... params ) {
166 return pack_remainder::template call<Ret>(
167 std::forward<F>(f),
static_cast<pack_remainder&&
>(pack),
168 std::forward<Preceding>(params)... ,
std::move(pack.leftmost_value)
174 template<
typename F,
typename Pack >
175 void call( F&& f, Pack&&
p ) {
176 strip<Pack>::type::template call<void>( std::forward<F>(f), std::forward<Pack>(
p) );
179 template<
typename Ret,
typename F,
typename Pack >
180 Ret call_and_return( F&& f, Pack&&
p ) {
181 return strip<Pack>::type::template call<Ret>( std::forward<F>(f), std::forward<Pack>(
p) );
184 template<
typename... Types >
185 stored_pack<Types...> save_pack( Types&&... types ) {
186 return stored_pack<Types...>( std::forward<Types>(types)... );
191 #if __TBB_CPP14_INTEGER_SEQUENCE_PRESENT
193 using std::index_sequence;
194 using std::make_index_sequence;
196 #elif __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_TEMPLATE_ALIASES_PRESENT
198 template<std::size_t...
S>
class index_sequence {};
200 template<std::size_t N, std::size_t...
S>
201 struct make_index_sequence_impl : make_index_sequence_impl < N - 1, N - 1, S... > {};
203 template<std::size_t...
S>
204 struct make_index_sequence_impl <0,
S...> {
205 using type = index_sequence<
S...>;
208 template<std::
size_t N>
213 #if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
214 template<
typename... Args>
217 template<
typename First,
typename... Args>
219 : std::conditional<bool(First::value), conjunction<Args...>, First>
::type {};
229 #if __TBB_CPP11_PRESENT
231 template<
typename Iter >
232 using iterator_value_t =
typename std::iterator_traits<Iter>::value_type;
234 template<
typename Iter >
235 using iterator_key_t =
typename std::remove_const<typename iterator_value_t<Iter>::first_type>
::type;
237 template<
typename Iter >
238 using iterator_mapped_t =
typename iterator_value_t<Iter>::second_type;
240 template<
typename A >
using value_type =
typename A::value_type;
241 template<
typename A >
using alloc_ptr_t =
typename std::allocator_traits<A>::pointer;
242 template<
typename A >
using has_allocate = decltype(std::declval<alloc_ptr_t<A>&>() = std::declval<A>().allocate(0));
243 template<
typename A >
using has_deallocate = decltype(std::declval<A>().deallocate(std::declval<alloc_ptr_t<A>>(), 0));
246 template<
typename T >
247 using is_allocator = supports<T, value_type, has_allocate, has_deallocate>;
249 #if __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT
251 template<
typename T >
256 template< std::size_t N,
typename... Args >
257 struct pack_element {
261 template< std::size_t N,
typename T,
typename... Args >
262 struct pack_element<N, T, Args...> {
263 using type =
typename pack_element<N - 1, Args...>
::type;
266 template<
typename T,
typename... Args >
267 struct pack_element<0, T, Args...> {
271 template< std::size_t N,
typename... Args >
272 using pack_element_t =
typename pack_element<N, Args...>
::type;
277 template <
typename Comp,
typename K>
278 using is_transparent =
typename std::conditional<true, Comp, K>::type::is_transparent;