@@ -23,76 +23,76 @@ namespace __pstl
2323namespace __internal
2424{
2525
26- using namespace __pstl ::execution;
26+ template <typename _IteratorTag, typename ... _IteratorTypes>
27+ using __are_iterators_of = std::conjunction<
28+ std::is_base_of<_IteratorTag, typename std::iterator_traits<std::decay_t <_IteratorTypes>>::iterator_category>...>;
2729
28- template <typename _IteratorType>
29- struct __is_random_access_iterator
30- : std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category,
31- std::random_access_iterator_tag>
32- {
33- };
30+ template <typename ... _IteratorTypes>
31+ using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
3432
35- template <typename Policy>
36- struct __policy_traits
33+ struct __serial_backend_tag
3734{
3835};
39-
40- template <>
41- struct __policy_traits <sequenced_policy>
36+ struct __tbb_backend_tag
4237{
43- typedef std::false_type __allow_parallel;
44- typedef std::false_type __allow_unsequenced;
45- typedef std::false_type __allow_vector;
4638};
47-
48- template <>
49- struct __policy_traits <unsequenced_policy>
39+ struct __openmp_backend_tag
5040{
51- typedef std::false_type __allow_parallel;
52- typedef std::true_type __allow_unsequenced;
53- typedef std::true_type __allow_vector;
5441};
5542
56- template <>
57- struct __policy_traits <parallel_policy>
43+ #if defined(_PSTL_PAR_BACKEND_TBB)
44+ using __par_backend_tag = __tbb_backend_tag;
45+ #elif defined(_PSTL_PAR_BACKEND_OPENMP)
46+ using __par_backend_tag = __openmp_backend_tag;
47+ #elif defined(_PSTL_PAR_BACKEND_SERIAL)
48+ using __par_backend_tag = __serial_backend_tag;
49+ #else
50+ # error "A parallel backend must be specified";
51+ #endif
52+
53+ template <class _IsVector >
54+ struct __serial_tag
5855{
59- typedef std::true_type __allow_parallel;
60- typedef std::false_type __allow_unsequenced;
61- typedef std::false_type __allow_vector;
56+ using __is_vector = _IsVector;
6257};
6358
64- template <>
65- struct __policy_traits <parallel_unsequenced_policy>
59+ template <class _IsVector >
60+ struct __parallel_tag
6661{
67- typedef std::true_type __allow_parallel;
68- typedef std::true_type __allow_unsequenced;
69- typedef std::true_type __allow_vector;
62+ using __is_vector = _IsVector;
63+ // backend tag can be change depending on
64+ // TBB availability in the environment
65+ using __backend_tag = __par_backend_tag;
7066};
7167
72- template <typename _ExecutionPolicy >
73- using __allow_vector =
74- typename __internal::__policy_traits< typename std::decay<_ExecutionPolicy>::type >::__allow_vector ;
68+ template <class _IsVector , class ... _IteratorTypes >
69+ using __tag_type = typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value,
70+ __parallel_tag<_IsVector>, __serial_tag<_IsVector> >::type ;
7571
76- template <typename _ExecutionPolicy>
77- using __allow_unsequenced =
78- typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced;
72+ template <class ... _IteratorTypes>
73+ __serial_tag</* _IsVector = */ std::false_type>
74+ __select_backend (__pstl::execution::sequenced_policy, _IteratorTypes&&...)
75+ {
76+ return {};
77+ }
7978
80- template <typename _ExecutionPolicy>
81- using __allow_parallel =
82- typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel;
79+ template <class ... _IteratorTypes>
80+ __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
81+ __select_backend (__pstl::execution::unsequenced_policy, _IteratorTypes&&...)
82+ {
83+ return {};
84+ }
8385
84- template <typename _ExecutionPolicy, typename ... _IteratorTypes>
85- typename std::conjunction<__allow_vector<_ExecutionPolicy>,
86- __is_random_access_iterator<_IteratorTypes>...>::type
87- __is_vectorization_preferred (_ExecutionPolicy&&)
86+ template <class ... _IteratorTypes>
87+ __tag_type</* _IsVector = */ std::false_type, _IteratorTypes...>
88+ __select_backend (__pstl::execution::parallel_policy, _IteratorTypes&&...)
8889{
8990 return {};
9091}
9192
92- template <typename _ExecutionPolicy, typename ... _IteratorTypes>
93- typename std::conjunction<__allow_parallel<_ExecutionPolicy>,
94- __is_random_access_iterator<_IteratorTypes>...>::type
95- __is_parallelization_preferred (_ExecutionPolicy&&)
93+ template <class ... _IteratorTypes>
94+ __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
95+ __select_backend (__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...)
9696{
9797 return {};
9898}
0 commit comments