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