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
20namespace std
21{
22
23// [alg.any_of]
24
25template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
26__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
27any_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
38template <class _ExecutionPolicy, class _ForwardIterator, class _Pred>
39__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
40all_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
48template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
49__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
50none_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
57template <class _ExecutionPolicy, class _ForwardIterator, class _Function>
58__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
59for_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
67template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function>
68__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
69for_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
80template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
81__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
82find_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
91template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
92__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
93find_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
99template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
100__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
101find(_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]
108template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
109__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
110find_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
120template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
121__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
122find_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]
130template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
131__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
132find_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
142template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
143__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
144find_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]
152template <class _ExecutionPolicy, class _ForwardIterator>
153__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
154adjacent_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
164template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
165__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
166adjacent_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
180template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
181__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
182                                                 typename iterator_traits<_ForwardIterator>::difference_type>
183count(_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
194template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate>
195__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy,
196                                                 typename iterator_traits<_ForwardIterator>::difference_type>
197count_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
208template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
209__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
210search(_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
220template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
221__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1>
222search(_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
229template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
230__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
231search_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
241template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
242__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
243search_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
252template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
253__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
254copy(_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
268template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2>
269__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
270copy_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
284template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
285__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
286copy_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
298template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
299__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
300swap_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
318template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation>
319__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
320transform(_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
333template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
334          class _BinaryOperation>
335__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
336transform(_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
354template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _Tp>
355__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
356replace_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
372template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
373__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
374replace(_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
381template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryPredicate, class _Tp>
382__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
383replace_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
396template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
397__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
398replace_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
407template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
408__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
409fill(_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
417template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
418__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
419fill_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]
432template <class _ExecutionPolicy, class _ForwardIterator, class _Generator>
433__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
434generate(_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
443template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator>
444__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
445generate_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
459template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
460__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
461remove_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
468template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
469__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
470remove_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
477template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
478__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
479remove_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
488template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
489__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
490remove(_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
498template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate>
499__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
500unique(_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
509template <class _ExecutionPolicy, class _ForwardIterator>
510__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
511unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last)
512{
513    return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__pstl_equal());
514}
515
516template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
517__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
518unique_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
528template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
529__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
530unique_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
537template <class _ExecutionPolicy, class _BidirectionalIterator>
538__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
539reverse(_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
548template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator>
549__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
550reverse_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
562template <class _ExecutionPolicy, class _ForwardIterator>
563__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
564rotate(_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
573template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
574__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
575rotate_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
587template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
588__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
589is_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
598template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate>
599__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
600partition(_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
609template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate>
610__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator>
611stable_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
621template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardIterator1, class _ForwardIterator2,
622          class _UnaryPredicate>
623__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
624partition_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
638template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
639__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
640sort(_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
651template <class _ExecutionPolicy, class _RandomAccessIterator>
652__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
653sort(_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
661template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
662__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
663stable_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
672template <class _ExecutionPolicy, class _RandomAccessIterator>
673__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
674stable_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
682template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
683__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
684mismatch(_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
694template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
695__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
696mismatch(_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
703template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
704__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
705mismatch(_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
712template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
713__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>>
714mismatch(_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
723template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
724__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
725equal(_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
735template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
736__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
737equal(_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
743template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
744__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
745equal(_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
755template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
756__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
757equal(_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]
765template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
766__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2>
767move(_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
783template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
784__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
785partial_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
795template <class _ExecutionPolicy, class _RandomAccessIterator>
796__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
797partial_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
806template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare>
807__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
808partial_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
818template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator>
819__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
820partial_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]
828template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
829__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
830is_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
840template <class _ExecutionPolicy, class _ForwardIterator>
841__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
842is_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
848template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
849__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
850is_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
860template <class _ExecutionPolicy, class _ForwardIterator>
861__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
862is_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]
869template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
870          class _Compare>
871__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
872merge(_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
884template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
885__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
886merge(_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
893template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare>
894__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
895inplace_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
905template <class _ExecutionPolicy, class _BidirectionalIterator>
906__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
907inplace_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
916template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
917__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
918includes(_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
928template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
929__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
930includes(_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
939template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
940          class _Compare>
941__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
942set_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
954template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
955__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
956set_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
965template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
966          class _Compare>
967__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
968set_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
980template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
981__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
982set_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
991template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
992          class _Compare>
993__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
994set_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
1006template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
1007__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
1008set_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
1017template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator,
1018          class _Compare>
1019__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
1020set_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
1033template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator>
1034__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
1035set_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]
1043template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1044__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
1045is_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
1054template <class _ExecutionPolicy, class _RandomAccessIterator>
1055__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator>
1056is_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
1062template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1063__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
1064is_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
1069template <class _ExecutionPolicy, class _RandomAccessIterator>
1070__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
1071is_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
1079template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
1080__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
1081min_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
1090template <class _ExecutionPolicy, class _ForwardIterator>
1091__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
1092min_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
1098template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
1099__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
1100max_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
1106template <class _ExecutionPolicy, class _ForwardIterator>
1107__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
1108max_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
1115template <class _ExecutionPolicy, class _ForwardIterator, class _Compare>
1116__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
1117minmax_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
1126template <class _ExecutionPolicy, class _ForwardIterator>
1127__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>>
1128minmax_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
1136template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare>
1137__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
1138nth_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
1148template <class _ExecutionPolicy, class _RandomAccessIterator>
1149__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void>
1150nth_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
1159template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare>
1160__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
1161lexicographical_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
1171template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
1172__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
1173lexicographical_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