1 | // -*- C++ -*- |
2 | //===-- execution_impl.h --------------------------------------------------===// |
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 "execution_defs.h" |
17 | |
18 | namespace __pstl |
19 | { |
20 | namespace __internal |
21 | { |
22 | |
23 | using namespace __pstl::execution; |
24 | |
25 | /* predicate */ |
26 | |
27 | template <typename _Tp> |
28 | std::false_type __lazy_and(_Tp, std::false_type) |
29 | { |
30 | return std::false_type{}; |
31 | } |
32 | |
33 | template <typename _Tp> |
34 | inline _Tp |
35 | __lazy_and(_Tp __a, std::true_type) |
36 | { |
37 | return __a; |
38 | } |
39 | |
40 | template <typename _Tp> |
41 | std::true_type __lazy_or(_Tp, std::true_type) |
42 | { |
43 | return std::true_type{}; |
44 | } |
45 | |
46 | template <typename _Tp> |
47 | inline _Tp |
48 | __lazy_or(_Tp __a, std::false_type) |
49 | { |
50 | return __a; |
51 | } |
52 | |
53 | /* iterator */ |
54 | template <typename _IteratorType, typename... _OtherIteratorTypes> |
55 | struct __is_random_access_iterator |
56 | { |
57 | static constexpr bool value = __internal::__is_random_access_iterator<_IteratorType>::value && |
58 | __internal::__is_random_access_iterator<_OtherIteratorTypes...>::value; |
59 | typedef std::integral_constant<bool, value> type; |
60 | }; |
61 | |
62 | template <typename _IteratorType> |
63 | struct __is_random_access_iterator<_IteratorType> |
64 | : std::is_same<typename std::iterator_traits<_IteratorType>::iterator_category, std::random_access_iterator_tag> |
65 | { |
66 | }; |
67 | |
68 | /* policy */ |
69 | template <typename _Policy> |
70 | struct __policy_traits |
71 | { |
72 | }; |
73 | |
74 | template <> |
75 | struct __policy_traits<sequenced_policy> |
76 | { |
77 | typedef std::false_type allow_parallel; |
78 | typedef std::false_type allow_unsequenced; |
79 | typedef std::false_type allow_vector; |
80 | }; |
81 | |
82 | template <> |
83 | struct __policy_traits<unsequenced_policy> |
84 | { |
85 | typedef std::false_type allow_parallel; |
86 | typedef std::true_type allow_unsequenced; |
87 | typedef std::true_type allow_vector; |
88 | }; |
89 | |
90 | template <> |
91 | struct __policy_traits<parallel_policy> |
92 | { |
93 | typedef std::true_type allow_parallel; |
94 | typedef std::false_type allow_unsequenced; |
95 | typedef std::false_type allow_vector; |
96 | }; |
97 | |
98 | template <> |
99 | struct __policy_traits<parallel_unsequenced_policy> |
100 | { |
101 | typedef std::true_type allow_parallel; |
102 | typedef std::true_type allow_unsequenced; |
103 | typedef std::true_type allow_vector; |
104 | }; |
105 | |
106 | template <typename _ExecutionPolicy> |
107 | using __collector_t = |
108 | typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__collector_type; |
109 | |
110 | template <typename _ExecutionPolicy> |
111 | using __allow_vector = |
112 | typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_vector; |
113 | |
114 | template <typename _ExecutionPolicy> |
115 | using __allow_unsequenced = |
116 | typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_unsequenced; |
117 | |
118 | template <typename _ExecutionPolicy> |
119 | using __allow_parallel = |
120 | typename __internal::__policy_traits<typename std::decay<_ExecutionPolicy>::type>::__allow_parallel; |
121 | |
122 | template <typename _ExecutionPolicy, typename... _IteratorTypes> |
123 | auto |
124 | __is_vectorization_preferred(_ExecutionPolicy&& __exec) |
125 | -> decltype(__internal::__lazy_and(__exec.__allow_vector(), |
126 | typename __internal::__is_random_access_iterator<_IteratorTypes...>::type())) |
127 | { |
128 | return __internal::__lazy_and(__exec.__allow_vector(), |
129 | typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()); |
130 | } |
131 | |
132 | template <typename _ExecutionPolicy, typename... _IteratorTypes> |
133 | auto |
134 | __is_parallelization_preferred(_ExecutionPolicy&& __exec) |
135 | -> decltype(__internal::__lazy_and(__exec.__allow_parallel(), |
136 | typename __internal::__is_random_access_iterator<_IteratorTypes...>::type())) |
137 | { |
138 | return __internal::__lazy_and(__exec.__allow_parallel(), |
139 | typename __internal::__is_random_access_iterator<_IteratorTypes...>::type()); |
140 | } |
141 | |
142 | template <typename policy, typename... _IteratorTypes> |
143 | struct __prefer_unsequenced_tag |
144 | { |
145 | static constexpr bool value = __internal::__allow_unsequenced<policy>::value && |
146 | __internal::__is_random_access_iterator<_IteratorTypes...>::value; |
147 | typedef std::integral_constant<bool, value> type; |
148 | }; |
149 | |
150 | template <typename policy, typename... _IteratorTypes> |
151 | struct __prefer_parallel_tag |
152 | { |
153 | static constexpr bool value = __internal::__allow_parallel<policy>::value && |
154 | __internal::__is_random_access_iterator<_IteratorTypes...>::value; |
155 | typedef std::integral_constant<bool, value> type; |
156 | }; |
157 | |
158 | } // namespace __internal |
159 | } // namespace __pstl |
160 | |
161 | #endif /* _PSTL_EXECUTION_IMPL_H */ |
162 | |