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