1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _PSTL_EXECUTION_IMPL_H
11 #define _PSTL_EXECUTION_IMPL_H
12
13 #include <iterator>
14 #include <type_traits>
15
16 #include "pstl_config.h"
17 #include "execution_defs.h"
18
19 _PSTL_HIDE_FROM_ABI_PUSH
20
21 namespace __pstl
22 {
23 namespace __internal
24 {
25
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>...>;
29
30 template <typename... _IteratorTypes>
31 using __are_random_access_iterators = __are_iterators_of<std::random_access_iterator_tag, _IteratorTypes...>;
32
33 struct __serial_backend_tag
34 {
35 };
36 struct __tbb_backend_tag
37 {
38 };
39 struct __openmp_backend_tag
40 {
41 };
42
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
55 {
56 using __is_vector = _IsVector;
57 };
58
59 template <class _IsVector>
60 struct __parallel_tag
61 {
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;
66 };
67
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;
71
72 template <class... _IteratorTypes>
73 __serial_tag</*_IsVector = */ std::false_type>
__select_backend(__pstl::execution::sequenced_policy,_IteratorTypes &&...)74 __select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...)
75 {
76 return {};
77 }
78
79 template <class... _IteratorTypes>
80 __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>>
__select_backend(__pstl::execution::unsequenced_policy,_IteratorTypes &&...)81 __select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...)
82 {
83 return {};
84 }
85
86 template <class... _IteratorTypes>
87 __tag_type</*_IsVector = */ std::false_type, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_policy,_IteratorTypes &&...)88 __select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...)
89 {
90 return {};
91 }
92
93 template <class... _IteratorTypes>
94 __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...>
__select_backend(__pstl::execution::parallel_unsequenced_policy,_IteratorTypes &&...)95 __select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...)
96 {
97 return {};
98 }
99
100 } // namespace __internal
101 } // namespace __pstl
102
103 _PSTL_HIDE_FROM_ABI_POP
104
105 #endif /* _PSTL_EXECUTION_IMPL_H */
106