1 | // -*- C++ -*- |
2 | //===-- glue_numeric_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_GLUE_NUMERIC_IMPL_H |
11 | #define _PSTL_GLUE_NUMERIC_IMPL_H |
12 | |
13 | #include <functional> |
14 | |
15 | #include "utils.h" |
16 | #include "numeric_fwd.h" |
17 | |
18 | namespace std |
19 | { |
20 | |
21 | // [reduce] |
22 | |
23 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation> |
24 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> |
25 | reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, |
26 | _BinaryOperation __binary_op) |
27 | { |
28 | return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, |
29 | __pstl::__internal::__no_op()); |
30 | } |
31 | |
32 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> |
33 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> |
34 | reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) |
35 | { |
36 | return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, std::plus<_Tp>(), |
37 | __pstl::__internal::__no_op()); |
38 | } |
39 | |
40 | template <class _ExecutionPolicy, class _ForwardIterator> |
41 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, |
42 | typename iterator_traits<_ForwardIterator>::value_type> |
43 | reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) |
44 | { |
45 | typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; |
46 | return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, _ValueType{}, |
47 | std::plus<_ValueType>(), __pstl::__internal::__no_op()); |
48 | } |
49 | |
50 | // [transform.reduce] |
51 | |
52 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> |
53 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> |
54 | transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, |
55 | _ForwardIterator2 __first2, _Tp __init) |
56 | { |
57 | typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; |
58 | return __pstl::__internal::__pattern_transform_reduce( |
59 | std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, std::plus<_InputType>(), |
60 | std::multiplies<_InputType>(), |
61 | __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
62 | __exec), |
63 | __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
64 | __exec)); |
65 | } |
66 | |
67 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation1, |
68 | class _BinaryOperation2> |
69 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> |
70 | transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, |
71 | _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) |
72 | { |
73 | return __pstl::__internal::__pattern_transform_reduce( |
74 | std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __init, __binary_op1, __binary_op2, |
75 | __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
76 | __exec), |
77 | __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
78 | __exec)); |
79 | } |
80 | |
81 | template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation, class _UnaryOperation> |
82 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> |
83 | transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, |
84 | _BinaryOperation __binary_op, _UnaryOperation __unary_op) |
85 | { |
86 | return __pstl::__internal::__pattern_transform_reduce( |
87 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op, |
88 | __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), |
89 | __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); |
90 | } |
91 | |
92 | // [exclusive.scan] |
93 | |
94 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> |
95 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
96 | exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
97 | _ForwardIterator2 __result, _Tp __init) |
98 | { |
99 | using namespace __pstl; |
100 | return __internal::__pattern_transform_scan( |
101 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init, |
102 | std::plus<_Tp>(), /*inclusive=*/std::false_type(), |
103 | __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), |
104 | __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); |
105 | } |
106 | |
107 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> |
108 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
109 | exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
110 | _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op) |
111 | { |
112 | using namespace __pstl; |
113 | return __internal::__pattern_transform_scan( |
114 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pstl::__internal::__no_op(), __init, |
115 | __binary_op, /*inclusive=*/std::false_type(), |
116 | __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), |
117 | __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); |
118 | } |
119 | |
120 | // [inclusive.scan] |
121 | |
122 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> |
123 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
124 | inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
125 | _ForwardIterator2 __result) |
126 | { |
127 | typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; |
128 | return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, |
129 | std::plus<_InputType>(), __pstl::__internal::__no_op()); |
130 | } |
131 | |
132 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> |
133 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
134 | inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
135 | _ForwardIterator2 __result, _BinaryOperation __binary_op) |
136 | { |
137 | return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, |
138 | __pstl::__internal::__no_op()); |
139 | } |
140 | |
141 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation> |
142 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
143 | inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
144 | _ForwardIterator2 __result, _BinaryOperation __binary_op, _Tp __init) |
145 | { |
146 | return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, |
147 | __pstl::__internal::__no_op(), __init); |
148 | } |
149 | |
150 | // [transform.exclusive.scan] |
151 | |
152 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp, class _BinaryOperation, |
153 | class _UnaryOperation> |
154 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
155 | transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
156 | _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op, |
157 | _UnaryOperation __unary_op) |
158 | { |
159 | return __pstl::__internal::__pattern_transform_scan( |
160 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op, |
161 | /*inclusive=*/std::false_type(), |
162 | __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
163 | __exec), |
164 | __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
165 | __exec)); |
166 | } |
167 | |
168 | // [transform.inclusive.scan] |
169 | |
170 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation, |
171 | class _UnaryOperation, class _Tp> |
172 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
173 | transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
174 | _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op, |
175 | _Tp __init) |
176 | { |
177 | return __pstl::__internal::__pattern_transform_scan( |
178 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __unary_op, __init, __binary_op, |
179 | /*inclusive=*/std::true_type(), |
180 | __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
181 | __exec), |
182 | __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
183 | __exec)); |
184 | } |
185 | |
186 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation, |
187 | class _BinaryOperation> |
188 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
189 | transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
190 | _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op) |
191 | { |
192 | if (__first != __last) |
193 | { |
194 | auto __tmp = __unary_op(*__first); |
195 | *__result = __tmp; |
196 | return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, |
197 | __binary_op, __unary_op, __tmp); |
198 | } |
199 | else |
200 | { |
201 | return __result; |
202 | } |
203 | } |
204 | |
205 | // [adjacent.difference] |
206 | |
207 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryOperation> |
208 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
209 | adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
210 | _ForwardIterator2 __d_first, _BinaryOperation __op) |
211 | { |
212 | |
213 | if (__first == __last) |
214 | return __d_first; |
215 | |
216 | return __pstl::__internal::__pattern_adjacent_difference( |
217 | std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op, |
218 | __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
219 | __exec), |
220 | __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>( |
221 | __exec)); |
222 | } |
223 | |
224 | template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> |
225 | __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> |
226 | adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, |
227 | _ForwardIterator2 __d_first) |
228 | { |
229 | typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType; |
230 | return adjacent_difference(std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, |
231 | std::minus<_ValueType>()); |
232 | } |
233 | |
234 | } // namespace std |
235 | |
236 | #endif /* _PSTL_GLUE_NUMERIC_IMPL_H_ */ |
237 | |