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_ALGORITHM_IMPL_H
11 #define _PSTL_GLUE_ALGORITHM_IMPL_H
12 
13 #include <functional>
14 
15 #include "pstl_config.h"
16 
17 #include "execution_defs.h"
18 #include "utils.h"
19 #include "algorithm_fwd.h"
20 #include "numeric_fwd.h" /* count and count_if use __pattern_transform_reduce */
21 
22 #include "execution_impl.h"
23 
24 _PSTL_HIDE_FROM_ABI_PUSH
25 
26 namespace std
27 {
28 
29 // [alg.any_of]
30 
31 template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
32 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
any_of(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred)33 any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
34 {
35     return __pstl::__internal::__pattern_any_of(
36         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
37         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
38         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
39 }
40 
41 // [alg.all_of]
42 
43 template <class _ExecutionPolicy, class _ForwardIterator, class _Pred>
44 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
all_of(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Pred __pred)45 all_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred)
46 {
47     return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::not_fn(__pred));
48 }
49 
50 // [alg.none_of]
51 
52 template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
53 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
none_of(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred)54 none_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
55 {
56     return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred);
57 }
58 
59 // [alg.foreach]
60 
61 template <class _ExecutionPolicy, class _ForwardIterator, class _Function>
62 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
for_each(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Function __f)63 for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f)
64 {
65     __pstl::__internal::__pattern_walk1(
66         std::forward<_ExecutionPolicy>(__exec), __first, __last, __f,
67         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
68         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
69 }
70 
71 template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
72 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
for_each_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_Size __n,_Function __f)73 for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f)
74 {
75     return __pstl::__internal::__pattern_walk1_n(
76         std::forward<_ExecutionPolicy>(__exec), __first, __n, __f,
77         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
78         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
79 }
80 
81 // [alg.find]
82 
83 template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
84 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
find_if(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred)85 find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
86 {
87     return __pstl::__internal::__pattern_find_if(
88         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
89         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
90         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
91 }
92 
93 template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
94 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
find_if_not(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred)95 find_if_not(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
96 {
97     return std::find_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::not_fn(__pred));
98 }
99 
100 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
101 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
find(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)102 find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
103 {
104     return std::find_if(std::forward<_ExecutionPolicy>(__exec), __first, __last,
105                         __pstl::__internal::__equal_value<_Tp>(__value));
106 }
107 
108 // [alg.find.end]
109 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
110 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
find_end(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __s_first,_ForwardIterator2 __s_last,_BinaryPredicate __pred)111 find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
112          _ForwardIterator2 __s_last, _BinaryPredicate __pred)
113 {
114     return __pstl::__internal::__pattern_find_end(
115         std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
116         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
117             __exec),
118         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
119             __exec));
120 }
121 
122 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
123 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
find_end(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __s_first,_ForwardIterator2 __s_last)124 find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
125          _ForwardIterator2 __s_last)
126 {
127     return std::find_end(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last,
128                          std::equal_to<>());
129 }
130 
131 // [alg.find_first_of]
132 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
133 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
find_first_of(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __s_first,_ForwardIterator2 __s_last,_BinaryPredicate __pred)134 find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
135               _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred)
136 {
137     return __pstl::__internal::__pattern_find_first_of(
138         std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
139         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
140             __exec),
141         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
142             __exec));
143 }
144 
145 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
146 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
find_first_of(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __s_first,_ForwardIterator2 __s_last)147 find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
148               _ForwardIterator2 __s_first, _ForwardIterator2 __s_last)
149 {
150     return std::find_first_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last,
151                               std::equal_to<>());
152 }
153 
154 // [alg.adjacent_find]
155 template <class _ExecutionPolicy, class _ForwardIterator>
156 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
adjacent_find(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)157 adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
158 {
159     typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
160     return __pstl::__internal::__pattern_adjacent_find(
161         std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<_ValueType>(),
162         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
163         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
164         /*first_semantic*/ false);
165 }
166 
167 template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
168 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
adjacent_find(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_BinaryPredicate __pred)169 adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
170 {
171     return __pstl::__internal::__pattern_adjacent_find(
172         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
173         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
174         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
175         /*first_semantic*/ false);
176 }
177 
178 // [alg.count]
179 
180 // Implementation note: count and count_if call the pattern directly instead of calling std::transform_reduce
181 // so that we do not have to include <numeric>.
182 
183 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
184 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
185                                                  typename iterator_traits<_ForwardIterator>::difference_type>
count(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)186 count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
187 {
188     typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
189     return __pstl::__internal::__pattern_count(
190         std::forward<_ExecutionPolicy>(__exec), __first, __last,
191         [&__value](const _ValueType& __x) { return __value == __x; },
192         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
193         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
194 }
195 
196 template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
197 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
198                                                  typename iterator_traits<_ForwardIterator>::difference_type>
count_if(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred)199 count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
200 {
201     return __pstl::__internal::__pattern_count(
202         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
203         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
204         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
205 }
206 
207 // [alg.search]
208 
209 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
210 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
search(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __s_first,_ForwardIterator2 __s_last,_BinaryPredicate __pred)211 search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
212        _ForwardIterator2 __s_last, _BinaryPredicate __pred)
213 {
214     return __pstl::__internal::__pattern_search(
215         std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred,
216         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
217             __exec),
218         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
219             __exec));
220 }
221 
222 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
223 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
search(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __s_first,_ForwardIterator2 __s_last)224 search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
225        _ForwardIterator2 __s_last)
226 {
227     return std::search(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>());
228 }
229 
230 template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
231 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
search_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Size __count,const _Tp & __value,_BinaryPredicate __pred)232 search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count,
233          const _Tp& __value, _BinaryPredicate __pred)
234 {
235     return __pstl::__internal::__pattern_search_n(
236         std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred,
237         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
238         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
239 }
240 
241 template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
242 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
search_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Size __count,const _Tp & __value)243 search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count,
244          const _Tp& __value)
245 {
246     return std::search_n(std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value,
247                          std::equal_to<typename iterator_traits<_ForwardIterator>::value_type>());
248 }
249 
250 // [alg.copy]
251 
252 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
253 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
copy(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result)254 copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result)
255 {
256     const auto __is_vector =
257         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
258             __exec);
259 
260     return __pstl::__internal::__pattern_walk2_brick(
261         std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
262         [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) {
263             return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector);
264         },
265         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
266             __exec));
267 }
268 
269 template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2>
270 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
copy_n(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_Size __n,_ForwardIterator2 __result)271 copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _ForwardIterator2 __result)
272 {
273     const auto __is_vector =
274         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
275             __exec);
276 
277     return __pstl::__internal::__pattern_walk2_brick_n(
278         std::forward<_ExecutionPolicy>(__exec), __first, __n, __result,
279         [__is_vector](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res) {
280             return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector);
281         },
282         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
283             __exec));
284 }
285 
286 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
287 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
copy_if(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result,_Predicate __pred)288 copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
289         _Predicate __pred)
290 {
291     return __pstl::__internal::__pattern_copy_if(
292         std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred,
293         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
294             __exec),
295         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
296             __exec));
297 }
298 
299 // [alg.swap]
300 
301 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
302 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
swap_ranges(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2)303 swap_ranges(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
304             _ForwardIterator2 __first2)
305 {
306     typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1;
307     typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2;
308     return __pstl::__internal::__pattern_walk2(
309         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2,
310         [](_ReferenceType1 __x, _ReferenceType2 __y) {
311             using std::swap;
312             swap(__x, __y);
313         },
314         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
315             __exec),
316         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
317             __exec));
318 }
319 
320 // [alg.transform]
321 
322 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation>
323 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
transform(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result,_UnaryOperation __op)324 transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
325           _UnaryOperation __op)
326 {
327     typedef typename iterator_traits<_ForwardIterator1>::reference _InputType;
328     typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType;
329     return __pstl::__internal::__pattern_walk2(
330         std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
331         [__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); },
332         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
333             __exec),
334         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
335             __exec));
336 }
337 
338 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
339           class _BinaryOperation>
340 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
transform(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator __result,_BinaryOperation __op)341 transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
342           _ForwardIterator __result, _BinaryOperation __op)
343 {
344     typedef typename iterator_traits<_ForwardIterator1>::reference _Input1Type;
345     typedef typename iterator_traits<_ForwardIterator2>::reference _Input2Type;
346     typedef typename iterator_traits<_ForwardIterator>::reference _OutputType;
347     return __pstl::__internal::__pattern_walk3(
348         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result,
349         [__op](_Input1Type x, _Input2Type y, _OutputType z) mutable { z = __op(x, y); },
350         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
351                                                          _ForwardIterator>(__exec),
352         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
353                                                            _ForwardIterator>(__exec));
354 }
355 
356 // [alg.replace]
357 
358 template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _Tp>
359 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
replace_if(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_UnaryPredicate __pred,const _Tp & __new_value)360 replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
361            const _Tp& __new_value)
362 {
363     typedef typename iterator_traits<_ForwardIterator>::reference _ElementType;
364     __pstl::__internal::__pattern_walk1(
365         std::forward<_ExecutionPolicy>(__exec), __first, __last,
366         [&__pred, &__new_value](_ElementType __elem) {
367             if (__pred(__elem))
368             {
369                 __elem = __new_value;
370             }
371         },
372         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
373         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
374 }
375 
376 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
377 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
replace(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,const _Tp & __old_value,const _Tp & __new_value)378 replace(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value,
379         const _Tp& __new_value)
380 {
381     std::replace_if(std::forward<_ExecutionPolicy>(__exec), __first, __last,
382                     __pstl::__internal::__equal_value<_Tp>(__old_value), __new_value);
383 }
384 
385 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryPredicate, class _Tp>
386 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
replace_copy_if(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result,_UnaryPredicate __pred,const _Tp & __new_value)387 replace_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
388                 _ForwardIterator2 __result, _UnaryPredicate __pred, const _Tp& __new_value)
389 {
390     typedef typename iterator_traits<_ForwardIterator1>::reference _InputType;
391     typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType;
392     return __pstl::__internal::__pattern_walk2(
393         std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
394         [__pred, &__new_value](_InputType __x, _OutputType __y) mutable { __y = __pred(__x) ? __new_value : __x; },
395         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
396             __exec),
397         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
398             __exec));
399 }
400 
401 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
402 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
replace_copy(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result,const _Tp & __old_value,const _Tp & __new_value)403 replace_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
404              const _Tp& __old_value, const _Tp& __new_value)
405 {
406     return std::replace_copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
407                                 __pstl::__internal::__equal_value<_Tp>(__old_value), __new_value);
408 }
409 
410 // [alg.fill]
411 
412 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
413 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
fill(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)414 fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
415 {
416     __pstl::__internal::__pattern_fill(
417         std::forward<_ExecutionPolicy>(__exec), __first, __last, __value,
418         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
419         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
420 }
421 
422 template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
423 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
fill_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_Size __count,const _Tp & __value)424 fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, const _Tp& __value)
425 {
426     if (__count <= 0)
427         return __first;
428 
429     return __pstl::__internal::__pattern_fill_n(
430         std::forward<_ExecutionPolicy>(__exec), __first, __count, __value,
431         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
432         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
433 }
434 
435 // [alg.generate]
436 template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
437 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
generate(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Generator __g)438 generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g)
439 {
440     __pstl::__internal::__pattern_generate(
441         std::forward<_ExecutionPolicy>(__exec), __first, __last, __g,
442         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
443         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
444 }
445 
446 template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
447 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
generate_n(_ExecutionPolicy && __exec,_ForwardIterator __first,_Size __count,_Generator __g)448 generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _Generator __g)
449 {
450     if (__count <= 0)
451         return __first;
452 
453     return __pstl::__internal::__pattern_generate_n(
454         std::forward<_ExecutionPolicy>(__exec), __first, __count, __g,
455         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
456         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
457 }
458 
459 // [alg.remove]
460 
461 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
462 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
remove_copy_if(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result,_Predicate __pred)463 remove_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
464                _ForwardIterator2 __result, _Predicate __pred)
465 {
466     return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, std::not_fn(__pred));
467 }
468 
469 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
470 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
remove_copy(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result,const _Tp & __value)471 remove_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
472             const _Tp& __value)
473 {
474     return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result,
475                         __pstl::__internal::__not_equal_value<_Tp>(__value));
476 }
477 
478 template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
479 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
remove_if(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_UnaryPredicate __pred)480 remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
481 {
482     return __pstl::__internal::__pattern_remove_if(
483         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
484         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
485         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
486 }
487 
488 template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
489 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
remove(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)490 remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
491 {
492     return std::remove_if(std::forward<_ExecutionPolicy>(__exec), __first, __last,
493                           __pstl::__internal::__equal_value<_Tp>(__value));
494 }
495 
496 // [alg.unique]
497 
498 template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
499 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
unique(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_BinaryPredicate __pred)500 unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred)
501 {
502     return __pstl::__internal::__pattern_unique(
503         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
504         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
505         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
506 }
507 
508 template <class _ExecutionPolicy, class _ForwardIterator>
509 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
unique(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)510 unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
511 {
512     return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<>());
513 }
514 
515 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
516 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
unique_copy(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result,_BinaryPredicate __pred)517 unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result,
518             _BinaryPredicate __pred)
519 {
520     return __pstl::__internal::__pattern_unique_copy(
521         std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred,
522         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
523             __exec),
524         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
525             __exec));
526 }
527 
528 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
529 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
unique_copy(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __result)530 unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result)
531 {
532     return std::unique_copy(__exec, __first, __last, __result, std::equal_to<>());
533 }
534 
535 // [alg.reverse]
536 
537 template <class _ExecutionPolicy, class _BidirectionalIterator>
538 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
reverse(_ExecutionPolicy && __exec,_BidirectionalIterator __first,_BidirectionalIterator __last)539 reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last)
540 {
541     __pstl::__internal::__pattern_reverse(
542         std::forward<_ExecutionPolicy>(__exec), __first, __last,
543         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec),
544         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
545 }
546 
547 template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator>
548 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
reverse_copy(_ExecutionPolicy && __exec,_BidirectionalIterator __first,_BidirectionalIterator __last,_ForwardIterator __d_first)549 reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last,
550              _ForwardIterator __d_first)
551 {
552     return __pstl::__internal::__pattern_reverse_copy(
553         std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first,
554         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>(
555             __exec),
556         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>(
557             __exec));
558 }
559 
560 // [alg.rotate]
561 
562 template <class _ExecutionPolicy, class _ForwardIterator>
563 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
rotate(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __middle,_ForwardIterator __last)564 rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
565 {
566     return __pstl::__internal::__pattern_rotate(
567         std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last,
568         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
569         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
570 }
571 
572 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
573 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
rotate_copy(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __middle,_ForwardIterator1 __last,_ForwardIterator2 __result)574 rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __middle, _ForwardIterator1 __last,
575             _ForwardIterator2 __result)
576 {
577     return __pstl::__internal::__pattern_rotate_copy(
578         std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result,
579         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
580             __exec),
581         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
582             __exec));
583 }
584 
585 // [alg.partitions]
586 
587 template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
588 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
is_partitioned(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_UnaryPredicate __pred)589 is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
590 {
591     return __pstl::__internal::__pattern_is_partitioned(
592         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
593         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
594         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
595 }
596 
597 template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
598 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
partition(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_UnaryPredicate __pred)599 partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred)
600 {
601     return __pstl::__internal::__pattern_partition(
602         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
603         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
604         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
605 }
606 
607 template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
608 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator>
stable_partition(_ExecutionPolicy && __exec,_BidirectionalIterator __first,_BidirectionalIterator __last,_UnaryPredicate __pred)609 stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last,
610                  _UnaryPredicate __pred)
611 {
612     return __pstl::__internal::__pattern_stable_partition(
613         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred,
614         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec),
615         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
616 }
617 
618 template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardIterator1, class _ForwardIterator2,
619           class _UnaryPredicate>
620 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
partition_copy(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_ForwardIterator1 __out_true,_ForwardIterator2 __out_false,_UnaryPredicate __pred)621 partition_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
622                _ForwardIterator1 __out_true, _ForwardIterator2 __out_false, _UnaryPredicate __pred)
623 {
624     return __pstl::__internal::__pattern_partition_copy(
625         std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred,
626         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1,
627                                                          _ForwardIterator2>(__exec),
628         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1,
629                                                            _ForwardIterator2>(__exec));
630 }
631 
632 // [alg.sort]
633 
634 template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
635 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
sort(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)636 sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
637 {
638     typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
639     return __pstl::__internal::__pattern_sort(
640         std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
641         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
642         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
643         typename std::is_move_constructible<_InputType>::type());
644 }
645 
646 template <class _ExecutionPolicy, class _RandomAccessIterator>
647 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
sort(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last)648 sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last)
649 {
650     typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
651     std::sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
652 }
653 
654 // [stable.sort]
655 
656 template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
657 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
stable_sort(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)658 stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
659 {
660     return __pstl::__internal::__pattern_stable_sort(
661         std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
662         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
663         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
664 }
665 
666 template <class _ExecutionPolicy, class _RandomAccessIterator>
667 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
stable_sort(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last)668 stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last)
669 {
670     typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
671     std::stable_sort(__exec, __first, __last, std::less<_InputType>());
672 }
673 
674 // [mismatch]
675 
676 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
677 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
mismatch(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_BinaryPredicate __pred)678 mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
679          _ForwardIterator2 __last2, _BinaryPredicate __pred)
680 {
681     return __pstl::__internal::__pattern_mismatch(
682         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred,
683         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
684             __exec),
685         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
686             __exec));
687 }
688 
689 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
690 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
mismatch(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_BinaryPredicate __pred)691 mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
692          _BinaryPredicate __pred)
693 {
694     return std::mismatch(__exec, __first1, __last1, __first2, std::next(__first2, std::distance(__first1, __last1)),
695                          __pred);
696 }
697 
698 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
699 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
mismatch(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2)700 mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
701          _ForwardIterator2 __last2)
702 {
703     return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2,
704                          std::equal_to<>());
705 }
706 
707 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
708 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
mismatch(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2)709 mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2)
710 {
711     //TODO: to get rid of "distance"
712     return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2,
713                          std::next(__first2, std::distance(__first1, __last1)));
714 }
715 
716 // [alg.equal]
717 
718 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
719 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
equal(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_BinaryPredicate __p)720 equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
721       _BinaryPredicate __p)
722 {
723     return __pstl::__internal::__pattern_equal(
724         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p,
725         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec),
726         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec));
727 }
728 
729 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
730 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
equal(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2)731 equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2)
732 {
733     return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, std::equal_to<>());
734 }
735 
736 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
737 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
equal(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_BinaryPredicate __p)738 equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
739       _ForwardIterator2 __last2, _BinaryPredicate __p)
740 {
741     return __pstl::__internal::__pattern_equal(
742         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p,
743         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec),
744         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec));
745 }
746 
747 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
748 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
equal(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2)749 equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
750       _ForwardIterator2 __last2)
751 {
752     return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>());
753 }
754 
755 // [alg.move]
756 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
757 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
move(_ExecutionPolicy && __exec,_ForwardIterator1 __first,_ForwardIterator1 __last,_ForwardIterator2 __d_first)758 move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first)
759 {
760     const auto __is_vector =
761         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
762             __exec);
763 
764     return __pstl::__internal::__pattern_walk2_brick(
765         std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first,
766         [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) {
767             return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector);
768         },
769         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
770             __exec));
771 }
772 
773 // [partial.sort]
774 
775 template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
776 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
partial_sort(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __middle,_RandomAccessIterator __last,_Compare __comp)777 partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle,
778              _RandomAccessIterator __last, _Compare __comp)
779 {
780     __pstl::__internal::__pattern_partial_sort(
781         std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp,
782         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
783         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
784 }
785 
786 template <class _ExecutionPolicy, class _RandomAccessIterator>
787 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
partial_sort(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __middle,_RandomAccessIterator __last)788 partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle,
789              _RandomAccessIterator __last)
790 {
791     typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
792     std::partial_sort(__exec, __first, __middle, __last, std::less<_InputType>());
793 }
794 
795 // [partial.sort.copy]
796 
797 template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
798 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
partial_sort_copy(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_RandomAccessIterator __d_first,_RandomAccessIterator __d_last,_Compare __comp)799 partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
800                   _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp)
801 {
802     return __pstl::__internal::__pattern_partial_sort_copy(
803         std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp,
804         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>(
805             __exec),
806         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>(
807             __exec));
808 }
809 
810 template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator>
811 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
partial_sort_copy(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_RandomAccessIterator __d_first,_RandomAccessIterator __d_last)812 partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
813                   _RandomAccessIterator __d_first, _RandomAccessIterator __d_last)
814 {
815     return std::partial_sort_copy(std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last,
816                                   std::less<>());
817 }
818 
819 // [is.sorted]
820 template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
821 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
is_sorted_until(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Compare __comp)822 is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
823 {
824     const _ForwardIterator __res = __pstl::__internal::__pattern_adjacent_find(
825         std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp),
826         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
827         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
828         /*first_semantic*/ false);
829     return __res == __last ? __last : std::next(__res);
830 }
831 
832 template <class _ExecutionPolicy, class _ForwardIterator>
833 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
is_sorted_until(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)834 is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
835 {
836     typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
837     return is_sorted_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
838 }
839 
840 template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
841 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
is_sorted(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Compare __comp)842 is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
843 {
844     return __pstl::__internal::__pattern_adjacent_find(
845                std::forward<_ExecutionPolicy>(__exec), __first, __last,
846                __pstl::__internal::__reorder_pred<_Compare>(__comp),
847                __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
848                __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
849                /*or_semantic*/ true) == __last;
850 }
851 
852 template <class _ExecutionPolicy, class _ForwardIterator>
853 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
is_sorted(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)854 is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
855 {
856     typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
857     return std::is_sorted(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
858 }
859 
860 // [alg.merge]
861 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
862           class _Compare>
863 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
merge(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __d_first,_Compare __comp)864 merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
865       _ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp)
866 {
867     return __pstl::__internal::__pattern_merge(
868         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp,
869         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
870                                                          _ForwardIterator>(__exec),
871         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
872                                                            _ForwardIterator>(__exec));
873 }
874 
875 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
876 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
merge(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __d_first)877 merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
878       _ForwardIterator2 __last2, _ForwardIterator __d_first)
879 {
880     return std::merge(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first,
881                       std::less<>());
882 }
883 
884 template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
885 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
inplace_merge(_ExecutionPolicy && __exec,_BidirectionalIterator __first,_BidirectionalIterator __middle,_BidirectionalIterator __last,_Compare __comp)886 inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle,
887               _BidirectionalIterator __last, _Compare __comp)
888 {
889     __pstl::__internal::__pattern_inplace_merge(
890         std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp,
891         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec),
892         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec));
893 }
894 
895 template <class _ExecutionPolicy, class _BidirectionalIterator>
896 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
inplace_merge(_ExecutionPolicy && __exec,_BidirectionalIterator __first,_BidirectionalIterator __middle,_BidirectionalIterator __last)897 inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle,
898               _BidirectionalIterator __last)
899 {
900     typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _InputType;
901     std::inplace_merge(__exec, __first, __middle, __last, std::less<_InputType>());
902 }
903 
904 // [includes]
905 
906 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
907 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
includes(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_Compare __comp)908 includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
909          _ForwardIterator2 __last2, _Compare __comp)
910 {
911     return __pstl::__internal::__pattern_includes(
912         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp,
913         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
914             __exec),
915         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
916             __exec));
917 }
918 
919 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
920 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
includes(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2)921 includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
922          _ForwardIterator2 __last2)
923 {
924     return std::includes(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>());
925 }
926 
927 // [set.union]
928 
929 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
930           class _Compare>
931 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_union(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result,_Compare __comp)932 set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
933           _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
934 {
935     return __pstl::__internal::__pattern_set_union(
936         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
937         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
938                                                          _ForwardIterator>(__exec),
939         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
940                                                            _ForwardIterator>(__exec));
941 }
942 
943 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
944 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_union(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result)945 set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
946           _ForwardIterator2 __last2, _ForwardIterator __result)
947 {
948     return std::set_union(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result,
949                           std::less<>());
950 }
951 
952 // [set.intersection]
953 
954 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
955           class _Compare>
956 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_intersection(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result,_Compare __comp)957 set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
958                  _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
959 {
960     return __pstl::__internal::__pattern_set_intersection(
961         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
962         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
963                                                          _ForwardIterator>(__exec),
964         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
965                                                            _ForwardIterator>(__exec));
966 }
967 
968 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
969 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_intersection(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result)970 set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
971                  _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result)
972 {
973     return std::set_intersection(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result,
974                                  std::less<>());
975 }
976 
977 // [set.difference]
978 
979 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
980           class _Compare>
981 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_difference(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result,_Compare __comp)982 set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
983                _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp)
984 {
985     return __pstl::__internal::__pattern_set_difference(
986         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
987         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
988                                                          _ForwardIterator>(__exec),
989         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
990                                                            _ForwardIterator>(__exec));
991 }
992 
993 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
994 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_difference(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result)995 set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
996                _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result)
997 {
998     return std::set_difference(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result,
999                                std::less<>());
1000 }
1001 
1002 // [set.symmetric.difference]
1003 
1004 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
1005           class _Compare>
1006 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_symmetric_difference(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result,_Compare __comp)1007 set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
1008                          _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result,
1009                          _Compare __comp)
1010 {
1011     return __pstl::__internal::__pattern_set_symmetric_difference(
1012         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
1013         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
1014                                                          _ForwardIterator>(__exec),
1015         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2,
1016                                                            _ForwardIterator>(__exec));
1017 }
1018 
1019 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
1020 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
set_symmetric_difference(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_ForwardIterator __result)1021 set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
1022                          _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result)
1023 {
1024     return std::set_symmetric_difference(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2,
1025                                          __result, std::less<>());
1026 }
1027 
1028 // [is.heap]
1029 template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1030 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
is_heap_until(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)1031 is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
1032 {
1033     return __pstl::__internal::__pattern_is_heap_until(
1034         std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
1035         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
1036         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
1037 }
1038 
1039 template <class _ExecutionPolicy, class _RandomAccessIterator>
1040 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
is_heap_until(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last)1041 is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last)
1042 {
1043     typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
1044     return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
1045 }
1046 
1047 template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1048 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
is_heap(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last,_Compare __comp)1049 is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
1050 {
1051     return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp) == __last;
1052 }
1053 
1054 template <class _ExecutionPolicy, class _RandomAccessIterator>
1055 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
is_heap(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __last)1056 is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last)
1057 {
1058     typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType;
1059     return std::is_heap(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
1060 }
1061 
1062 // [alg.min.max]
1063 
1064 template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
1065 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
min_element(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Compare __comp)1066 min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
1067 {
1068     return __pstl::__internal::__pattern_min_element(
1069         std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
1070         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
1071         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
1072 }
1073 
1074 template <class _ExecutionPolicy, class _ForwardIterator>
1075 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
min_element(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)1076 min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
1077 {
1078     typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
1079     return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>());
1080 }
1081 
1082 template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
1083 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
max_element(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Compare __comp)1084 max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
1085 {
1086     return min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last,
1087                        __pstl::__internal::__reorder_pred<_Compare>(__comp));
1088 }
1089 
1090 template <class _ExecutionPolicy, class _ForwardIterator>
1091 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
max_element(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)1092 max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
1093 {
1094     typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType;
1095     return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last,
1096                             __pstl::__internal::__reorder_pred<std::less<_InputType>>(std::less<_InputType>()));
1097 }
1098 
1099 template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
1100 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
minmax_element(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last,_Compare __comp)1101 minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp)
1102 {
1103     return __pstl::__internal::__pattern_minmax_element(
1104         std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
1105         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec),
1106         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec));
1107 }
1108 
1109 template <class _ExecutionPolicy, class _ForwardIterator>
1110 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
minmax_element(_ExecutionPolicy && __exec,_ForwardIterator __first,_ForwardIterator __last)1111 minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
1112 {
1113     typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType;
1114     return std::minmax_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_ValueType>());
1115 }
1116 
1117 // [alg.nth.element]
1118 
1119 template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1120 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
nth_element(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __nth,_RandomAccessIterator __last,_Compare __comp)1121 nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth,
1122             _RandomAccessIterator __last, _Compare __comp)
1123 {
1124     __pstl::__internal::__pattern_nth_element(
1125         std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp,
1126         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec),
1127         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec));
1128 }
1129 
1130 template <class _ExecutionPolicy, class _RandomAccessIterator>
1131 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
nth_element(_ExecutionPolicy && __exec,_RandomAccessIterator __first,_RandomAccessIterator __nth,_RandomAccessIterator __last)1132 nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth,
1133             _RandomAccessIterator __last)
1134 {
1135     typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType;
1136     std::nth_element(std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, std::less<_InputType>());
1137 }
1138 
1139 // [alg.lex.comparison]
1140 
1141 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
1142 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
lexicographical_compare(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2,_Compare __comp)1143 lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
1144                         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp)
1145 {
1146     return __pstl::__internal::__pattern_lexicographical_compare(
1147         std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp,
1148         __pstl::__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
1149             __exec),
1150         __pstl::__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(
1151             __exec));
1152 }
1153 
1154 template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
1155 __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
lexicographical_compare(_ExecutionPolicy && __exec,_ForwardIterator1 __first1,_ForwardIterator1 __last1,_ForwardIterator2 __first2,_ForwardIterator2 __last2)1156 lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
1157                         _ForwardIterator2 __first2, _ForwardIterator2 __last2)
1158 {
1159     return std::lexicographical_compare(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2,
1160                                         std::less<>());
1161 }
1162 
1163 } // namespace std
1164 
1165 _PSTL_HIDE_FROM_ABI_POP
1166 
1167 #endif /* _PSTL_GLUE_ALGORITHM_IMPL_H */
1168