1*e4b17023SJohn Marino // -*- C++ -*-
2*e4b17023SJohn Marino 
3*e4b17023SJohn Marino // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4*e4b17023SJohn Marino //
5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library.  This library is free
6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the terms
7*e4b17023SJohn Marino // of the GNU General Public License as published by the Free Software
8*e4b17023SJohn Marino // Foundation; either version 3, or (at your option) any later
9*e4b17023SJohn Marino // version.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, but
12*e4b17023SJohn Marino // WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*e4b17023SJohn Marino // General Public License for more details.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino /** @file parallel/algo.h
26*e4b17023SJohn Marino  *  @brief Parallel STL function calls corresponding to the stl_algo.h header.
27*e4b17023SJohn Marino  *
28*e4b17023SJohn Marino  *  The functions defined here mainly do case switches and
29*e4b17023SJohn Marino  *  call the actual parallelized versions in other files.
30*e4b17023SJohn Marino  *  Inlining policy: Functions that basically only contain one function call,
31*e4b17023SJohn Marino  *  are declared inline.
32*e4b17023SJohn Marino  *  This file is a GNU parallel extension to the Standard C++ Library.
33*e4b17023SJohn Marino  */
34*e4b17023SJohn Marino 
35*e4b17023SJohn Marino // Written by Johannes Singler and Felix Putze.
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino #ifndef _GLIBCXX_PARALLEL_ALGO_H
38*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_ALGO_H 1
39*e4b17023SJohn Marino 
40*e4b17023SJohn Marino #include <parallel/algorithmfwd.h>
41*e4b17023SJohn Marino #include <bits/stl_algobase.h>
42*e4b17023SJohn Marino #include <bits/stl_algo.h>
43*e4b17023SJohn Marino #include <parallel/iterator.h>
44*e4b17023SJohn Marino #include <parallel/base.h>
45*e4b17023SJohn Marino #include <parallel/sort.h>
46*e4b17023SJohn Marino #include <parallel/workstealing.h>
47*e4b17023SJohn Marino #include <parallel/par_loop.h>
48*e4b17023SJohn Marino #include <parallel/omp_loop.h>
49*e4b17023SJohn Marino #include <parallel/omp_loop_static.h>
50*e4b17023SJohn Marino #include <parallel/for_each_selectors.h>
51*e4b17023SJohn Marino #include <parallel/for_each.h>
52*e4b17023SJohn Marino #include <parallel/find.h>
53*e4b17023SJohn Marino #include <parallel/find_selectors.h>
54*e4b17023SJohn Marino #include <parallel/search.h>
55*e4b17023SJohn Marino #include <parallel/random_shuffle.h>
56*e4b17023SJohn Marino #include <parallel/partition.h>
57*e4b17023SJohn Marino #include <parallel/merge.h>
58*e4b17023SJohn Marino #include <parallel/unique_copy.h>
59*e4b17023SJohn Marino #include <parallel/set_operations.h>
60*e4b17023SJohn Marino 
_GLIBCXX_VISIBILITY(default)61*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
62*e4b17023SJohn Marino {
63*e4b17023SJohn Marino namespace __parallel
64*e4b17023SJohn Marino {
65*e4b17023SJohn Marino   // Sequential fallback
66*e4b17023SJohn Marino   template<typename _IIter, typename _Function>
67*e4b17023SJohn Marino     inline _Function
68*e4b17023SJohn Marino     for_each(_IIter __begin, _IIter __end, _Function __f,
69*e4b17023SJohn Marino              __gnu_parallel::sequential_tag)
70*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::for_each(__begin, __end, __f); }
71*e4b17023SJohn Marino 
72*e4b17023SJohn Marino 
73*e4b17023SJohn Marino   // Sequential fallback for input iterator case
74*e4b17023SJohn Marino   template<typename _IIter, typename _Function, typename _IteratorTag>
75*e4b17023SJohn Marino     inline _Function
76*e4b17023SJohn Marino     __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
77*e4b17023SJohn Marino                     _IteratorTag)
78*e4b17023SJohn Marino     { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }
79*e4b17023SJohn Marino 
80*e4b17023SJohn Marino   // Parallel algorithm for random access iterators
81*e4b17023SJohn Marino   template<typename _RAIter, typename _Function>
82*e4b17023SJohn Marino     _Function
83*e4b17023SJohn Marino     __for_each_switch(_RAIter __begin, _RAIter __end,
84*e4b17023SJohn Marino                     _Function __f, random_access_iterator_tag,
85*e4b17023SJohn Marino                     __gnu_parallel::_Parallelism __parallelism_tag
86*e4b17023SJohn Marino                     = __gnu_parallel::parallel_balanced)
87*e4b17023SJohn Marino     {
88*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
89*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
90*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().for_each_minimal_n
91*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
92*e4b17023SJohn Marino         {
93*e4b17023SJohn Marino           bool __dummy;
94*e4b17023SJohn Marino     __gnu_parallel::__for_each_selector<_RAIter> __functionality;
95*e4b17023SJohn Marino 
96*e4b17023SJohn Marino           return __gnu_parallel::
97*e4b17023SJohn Marino             __for_each_template_random_access(
98*e4b17023SJohn Marino               __begin, __end, __f, __functionality,
99*e4b17023SJohn Marino               __gnu_parallel::_DummyReduct(), true, __dummy, -1,
100*e4b17023SJohn Marino               __parallelism_tag);
101*e4b17023SJohn Marino         }
102*e4b17023SJohn Marino       else
103*e4b17023SJohn Marino         return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
104*e4b17023SJohn Marino     }
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino   // Public interface
107*e4b17023SJohn Marino   template<typename _Iterator, typename _Function>
108*e4b17023SJohn Marino     inline _Function
109*e4b17023SJohn Marino     for_each(_Iterator __begin, _Iterator __end, _Function __f,
110*e4b17023SJohn Marino              __gnu_parallel::_Parallelism __parallelism_tag)
111*e4b17023SJohn Marino     {
112*e4b17023SJohn Marino       typedef std::iterator_traits<_Iterator> _IteratorTraits;
113*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
114*e4b17023SJohn Marino       return __for_each_switch(__begin, __end, __f, _IteratorCategory(),
115*e4b17023SJohn Marino                              __parallelism_tag);
116*e4b17023SJohn Marino     }
117*e4b17023SJohn Marino 
118*e4b17023SJohn Marino   template<typename _Iterator, typename _Function>
119*e4b17023SJohn Marino     inline _Function
120*e4b17023SJohn Marino     for_each(_Iterator __begin, _Iterator __end, _Function __f)
121*e4b17023SJohn Marino     {
122*e4b17023SJohn Marino       typedef std::iterator_traits<_Iterator> _IteratorTraits;
123*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
124*e4b17023SJohn Marino       return __for_each_switch(__begin, __end, __f, _IteratorCategory());
125*e4b17023SJohn Marino     }
126*e4b17023SJohn Marino 
127*e4b17023SJohn Marino 
128*e4b17023SJohn Marino   // Sequential fallback
129*e4b17023SJohn Marino   template<typename _IIter, typename _Tp>
130*e4b17023SJohn Marino     inline _IIter
131*e4b17023SJohn Marino     find(_IIter __begin, _IIter __end, const _Tp& __val,
132*e4b17023SJohn Marino          __gnu_parallel::sequential_tag)
133*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::find(__begin, __end, __val); }
134*e4b17023SJohn Marino 
135*e4b17023SJohn Marino   // Sequential fallback for input iterator case
136*e4b17023SJohn Marino   template<typename _IIter, typename _Tp, typename _IteratorTag>
137*e4b17023SJohn Marino     inline _IIter
138*e4b17023SJohn Marino     __find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
139*e4b17023SJohn Marino                 _IteratorTag)
140*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::find(__begin, __end, __val); }
141*e4b17023SJohn Marino 
142*e4b17023SJohn Marino   // Parallel find for random access iterators
143*e4b17023SJohn Marino   template<typename _RAIter, typename _Tp>
144*e4b17023SJohn Marino     _RAIter
145*e4b17023SJohn Marino     __find_switch(_RAIter __begin, _RAIter __end,
146*e4b17023SJohn Marino                 const _Tp& __val, random_access_iterator_tag)
147*e4b17023SJohn Marino     {
148*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
149*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
150*e4b17023SJohn Marino 
151*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(true))
152*e4b17023SJohn Marino         {
153*e4b17023SJohn Marino 	  std::binder2nd<__gnu_parallel::_EqualTo<_ValueType, const _Tp&> >
154*e4b17023SJohn Marino             __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val);
155*e4b17023SJohn Marino           return __gnu_parallel::__find_template(
156*e4b17023SJohn Marino                    __begin, __end, __begin, __comp,
157*e4b17023SJohn Marino                    __gnu_parallel::__find_if_selector()).first;
158*e4b17023SJohn Marino         }
159*e4b17023SJohn Marino       else
160*e4b17023SJohn Marino         return _GLIBCXX_STD_A::find(__begin, __end, __val);
161*e4b17023SJohn Marino     }
162*e4b17023SJohn Marino 
163*e4b17023SJohn Marino   // Public interface
164*e4b17023SJohn Marino   template<typename _IIter, typename _Tp>
165*e4b17023SJohn Marino     inline _IIter
166*e4b17023SJohn Marino     find(_IIter __begin, _IIter __end, const _Tp& __val)
167*e4b17023SJohn Marino     {
168*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IteratorTraits;
169*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
170*e4b17023SJohn Marino       return __find_switch(__begin, __end, __val, _IteratorCategory());
171*e4b17023SJohn Marino     }
172*e4b17023SJohn Marino 
173*e4b17023SJohn Marino   // Sequential fallback
174*e4b17023SJohn Marino   template<typename _IIter, typename _Predicate>
175*e4b17023SJohn Marino     inline _IIter
176*e4b17023SJohn Marino     find_if(_IIter __begin, _IIter __end, _Predicate __pred,
177*e4b17023SJohn Marino             __gnu_parallel::sequential_tag)
178*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
179*e4b17023SJohn Marino 
180*e4b17023SJohn Marino   // Sequential fallback for input iterator case
181*e4b17023SJohn Marino   template<typename _IIter, typename _Predicate, typename _IteratorTag>
182*e4b17023SJohn Marino     inline _IIter
183*e4b17023SJohn Marino     __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
184*e4b17023SJohn Marino                    _IteratorTag)
185*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
186*e4b17023SJohn Marino 
187*e4b17023SJohn Marino   // Parallel find_if for random access iterators
188*e4b17023SJohn Marino   template<typename _RAIter, typename _Predicate>
189*e4b17023SJohn Marino     _RAIter
190*e4b17023SJohn Marino     __find_if_switch(_RAIter __begin, _RAIter __end,
191*e4b17023SJohn Marino                    _Predicate __pred, random_access_iterator_tag)
192*e4b17023SJohn Marino     {
193*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(true))
194*e4b17023SJohn Marino         return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
195*e4b17023SJohn Marino                                              __gnu_parallel::
196*e4b17023SJohn Marino                                              __find_if_selector()).first;
197*e4b17023SJohn Marino       else
198*e4b17023SJohn Marino         return _GLIBCXX_STD_A::find_if(__begin, __end, __pred);
199*e4b17023SJohn Marino     }
200*e4b17023SJohn Marino 
201*e4b17023SJohn Marino   // Public interface
202*e4b17023SJohn Marino   template<typename _IIter, typename _Predicate>
203*e4b17023SJohn Marino     inline _IIter
204*e4b17023SJohn Marino     find_if(_IIter __begin, _IIter __end, _Predicate __pred)
205*e4b17023SJohn Marino     {
206*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IteratorTraits;
207*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
208*e4b17023SJohn Marino       return __find_if_switch(__begin, __end, __pred, _IteratorCategory());
209*e4b17023SJohn Marino     }
210*e4b17023SJohn Marino 
211*e4b17023SJohn Marino   // Sequential fallback
212*e4b17023SJohn Marino   template<typename _IIter, typename _FIterator>
213*e4b17023SJohn Marino     inline _IIter
214*e4b17023SJohn Marino     find_first_of(_IIter __begin1, _IIter __end1,
215*e4b17023SJohn Marino                   _FIterator __begin2, _FIterator __end2,
216*e4b17023SJohn Marino                   __gnu_parallel::sequential_tag)
217*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2);
218*e4b17023SJohn Marino       }
219*e4b17023SJohn Marino 
220*e4b17023SJohn Marino   // Sequential fallback
221*e4b17023SJohn Marino   template<typename _IIter, typename _FIterator,
222*e4b17023SJohn Marino            typename _BinaryPredicate>
223*e4b17023SJohn Marino     inline _IIter
224*e4b17023SJohn Marino     find_first_of(_IIter __begin1, _IIter __end1,
225*e4b17023SJohn Marino                   _FIterator __begin2, _FIterator __end2,
226*e4b17023SJohn Marino                   _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
227*e4b17023SJohn Marino   { return _GLIBCXX_STD_A::find_first_of(
228*e4b17023SJohn Marino              __begin1, __end1, __begin2, __end2, __comp); }
229*e4b17023SJohn Marino 
230*e4b17023SJohn Marino   // Sequential fallback for input iterator type
231*e4b17023SJohn Marino   template<typename _IIter, typename _FIterator,
232*e4b17023SJohn Marino            typename _IteratorTag1, typename _IteratorTag2>
233*e4b17023SJohn Marino     inline _IIter
234*e4b17023SJohn Marino     __find_first_of_switch(_IIter __begin1, _IIter __end1,
235*e4b17023SJohn Marino                          _FIterator __begin2, _FIterator __end2,
236*e4b17023SJohn Marino                          _IteratorTag1, _IteratorTag2)
237*e4b17023SJohn Marino     { return find_first_of(__begin1, __end1, __begin2, __end2,
238*e4b17023SJohn Marino                            __gnu_parallel::sequential_tag()); }
239*e4b17023SJohn Marino 
240*e4b17023SJohn Marino   // Parallel algorithm for random access iterators
241*e4b17023SJohn Marino   template<typename _RAIter, typename _FIterator,
242*e4b17023SJohn Marino            typename _BinaryPredicate, typename _IteratorTag>
243*e4b17023SJohn Marino     inline _RAIter
244*e4b17023SJohn Marino     __find_first_of_switch(_RAIter __begin1,
245*e4b17023SJohn Marino                          _RAIter __end1,
246*e4b17023SJohn Marino                          _FIterator __begin2, _FIterator __end2,
247*e4b17023SJohn Marino                          _BinaryPredicate __comp, random_access_iterator_tag,
248*e4b17023SJohn Marino                          _IteratorTag)
249*e4b17023SJohn Marino     {
250*e4b17023SJohn Marino       return __gnu_parallel::
251*e4b17023SJohn Marino         __find_template(__begin1, __end1, __begin1, __comp,
252*e4b17023SJohn Marino                       __gnu_parallel::__find_first_of_selector
253*e4b17023SJohn Marino                       <_FIterator>(__begin2, __end2)).first;
254*e4b17023SJohn Marino     }
255*e4b17023SJohn Marino 
256*e4b17023SJohn Marino   // Sequential fallback for input iterator type
257*e4b17023SJohn Marino   template<typename _IIter, typename _FIterator,
258*e4b17023SJohn Marino            typename _BinaryPredicate, typename _IteratorTag1,
259*e4b17023SJohn Marino            typename _IteratorTag2>
260*e4b17023SJohn Marino     inline _IIter
261*e4b17023SJohn Marino     __find_first_of_switch(_IIter __begin1, _IIter __end1,
262*e4b17023SJohn Marino                          _FIterator __begin2, _FIterator __end2,
263*e4b17023SJohn Marino                          _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
264*e4b17023SJohn Marino     { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
265*e4b17023SJohn Marino                            __gnu_parallel::sequential_tag()); }
266*e4b17023SJohn Marino 
267*e4b17023SJohn Marino   // Public interface
268*e4b17023SJohn Marino   template<typename _IIter, typename _FIterator,
269*e4b17023SJohn Marino            typename _BinaryPredicate>
270*e4b17023SJohn Marino     inline _IIter
271*e4b17023SJohn Marino     find_first_of(_IIter __begin1, _IIter __end1,
272*e4b17023SJohn Marino                   _FIterator __begin2, _FIterator __end2,
273*e4b17023SJohn Marino                   _BinaryPredicate __comp)
274*e4b17023SJohn Marino     {
275*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IIterTraits;
276*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator> _FIterTraits;
277*e4b17023SJohn Marino       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
278*e4b17023SJohn Marino       typedef typename _FIterTraits::iterator_category _FIteratorCategory;
279*e4b17023SJohn Marino 
280*e4b17023SJohn Marino       return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
281*e4b17023SJohn Marino                                   _IIteratorCategory(), _FIteratorCategory());
282*e4b17023SJohn Marino     }
283*e4b17023SJohn Marino 
284*e4b17023SJohn Marino   // Public interface, insert default comparator
285*e4b17023SJohn Marino   template<typename _IIter, typename _FIterator>
286*e4b17023SJohn Marino     inline _IIter
287*e4b17023SJohn Marino     find_first_of(_IIter __begin1, _IIter __end1,
288*e4b17023SJohn Marino                   _FIterator __begin2, _FIterator __end2)
289*e4b17023SJohn Marino     {
290*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IIterTraits;
291*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator> _FIterTraits;
292*e4b17023SJohn Marino       typedef typename _IIterTraits::value_type _IValueType;
293*e4b17023SJohn Marino       typedef typename _FIterTraits::value_type _FValueType;
294*e4b17023SJohn Marino 
295*e4b17023SJohn Marino       return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2,
296*e4b17023SJohn Marino                          __gnu_parallel::_EqualTo<_IValueType, _FValueType>());
297*e4b17023SJohn Marino     }
298*e4b17023SJohn Marino 
299*e4b17023SJohn Marino   // Sequential fallback
300*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator>
301*e4b17023SJohn Marino     inline _OutputIterator
302*e4b17023SJohn Marino     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
303*e4b17023SJohn Marino                 __gnu_parallel::sequential_tag)
304*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); }
305*e4b17023SJohn Marino 
306*e4b17023SJohn Marino   // Sequential fallback
307*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator,
308*e4b17023SJohn Marino            typename _Predicate>
309*e4b17023SJohn Marino     inline _OutputIterator
310*e4b17023SJohn Marino     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
311*e4b17023SJohn Marino                 _Predicate __pred, __gnu_parallel::sequential_tag)
312*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); }
313*e4b17023SJohn Marino 
314*e4b17023SJohn Marino   // Sequential fallback for input iterator case
315*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator,
316*e4b17023SJohn Marino            typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
317*e4b17023SJohn Marino     inline _OutputIterator
318*e4b17023SJohn Marino     __unique_copy_switch(_IIter __begin, _IIter __last,
319*e4b17023SJohn Marino                        _OutputIterator __out, _Predicate __pred,
320*e4b17023SJohn Marino                        _IteratorTag1, _IteratorTag2)
321*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); }
322*e4b17023SJohn Marino 
323*e4b17023SJohn Marino   // Parallel unique_copy for random access iterators
324*e4b17023SJohn Marino   template<typename _RAIter, typename RandomAccessOutputIterator,
325*e4b17023SJohn Marino            typename _Predicate>
326*e4b17023SJohn Marino     RandomAccessOutputIterator
327*e4b17023SJohn Marino     __unique_copy_switch(_RAIter __begin, _RAIter __last,
328*e4b17023SJohn Marino                        RandomAccessOutputIterator __out, _Predicate __pred,
329*e4b17023SJohn Marino                        random_access_iterator_tag, random_access_iterator_tag)
330*e4b17023SJohn Marino     {
331*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
332*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
333*e4b17023SJohn Marino             > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
334*e4b17023SJohn Marino         return __gnu_parallel::__parallel_unique_copy(
335*e4b17023SJohn Marino                  __begin, __last, __out, __pred);
336*e4b17023SJohn Marino       else
337*e4b17023SJohn Marino         return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred);
338*e4b17023SJohn Marino     }
339*e4b17023SJohn Marino 
340*e4b17023SJohn Marino   // Public interface
341*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator>
342*e4b17023SJohn Marino     inline _OutputIterator
343*e4b17023SJohn Marino     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
344*e4b17023SJohn Marino     {
345*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IIterTraits;
346*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
347*e4b17023SJohn Marino       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
348*e4b17023SJohn Marino       typedef typename _IIterTraits::value_type _ValueType;
349*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
350*e4b17023SJohn Marino 
351*e4b17023SJohn Marino       return __unique_copy_switch(
352*e4b17023SJohn Marino                __begin1, __end1, __out, equal_to<_ValueType>(),
353*e4b17023SJohn Marino                _IIteratorCategory(), _OIterCategory());
354*e4b17023SJohn Marino     }
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino   // Public interface
357*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator, typename _Predicate>
358*e4b17023SJohn Marino     inline _OutputIterator
359*e4b17023SJohn Marino     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
360*e4b17023SJohn Marino                 _Predicate __pred)
361*e4b17023SJohn Marino     {
362*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IIterTraits;
363*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
364*e4b17023SJohn Marino       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
365*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino       return __unique_copy_switch(
368*e4b17023SJohn Marino                __begin1, __end1, __out, __pred,
369*e4b17023SJohn Marino                _IIteratorCategory(), _OIterCategory());
370*e4b17023SJohn Marino     }
371*e4b17023SJohn Marino 
372*e4b17023SJohn Marino   // Sequential fallback
373*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
374*e4b17023SJohn Marino            typename _OutputIterator>
375*e4b17023SJohn Marino     inline _OutputIterator
376*e4b17023SJohn Marino     set_union(_IIter1 __begin1, _IIter1 __end1,
377*e4b17023SJohn Marino               _IIter2 __begin2, _IIter2 __end2,
378*e4b17023SJohn Marino               _OutputIterator __out, __gnu_parallel::sequential_tag)
379*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_union(
380*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out); }
381*e4b17023SJohn Marino 
382*e4b17023SJohn Marino   // Sequential fallback
383*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
384*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
385*e4b17023SJohn Marino     inline _OutputIterator
386*e4b17023SJohn Marino     set_union(_IIter1 __begin1, _IIter1 __end1,
387*e4b17023SJohn Marino               _IIter2 __begin2, _IIter2 __end2,
388*e4b17023SJohn Marino               _OutputIterator __out, _Predicate __pred,
389*e4b17023SJohn Marino               __gnu_parallel::sequential_tag)
390*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
391*e4b17023SJohn Marino                                        __begin2, __end2, __out, __pred); }
392*e4b17023SJohn Marino 
393*e4b17023SJohn Marino   // Sequential fallback for input iterator case
394*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2, typename _Predicate,
395*e4b17023SJohn Marino            typename _OutputIterator, typename _IteratorTag1,
396*e4b17023SJohn Marino            typename _IteratorTag2, typename _IteratorTag3>
397*e4b17023SJohn Marino     inline _OutputIterator
398*e4b17023SJohn Marino     __set_union_switch(
399*e4b17023SJohn Marino       _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
400*e4b17023SJohn Marino       _OutputIterator __result, _Predicate __pred,
401*e4b17023SJohn Marino       _IteratorTag1, _IteratorTag2, _IteratorTag3)
402*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
403*e4b17023SJohn Marino                                        __begin2, __end2, __result, __pred); }
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino   // Parallel set_union for random access iterators
406*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
407*e4b17023SJohn Marino            typename _Output_RAIter, typename _Predicate>
408*e4b17023SJohn Marino     _Output_RAIter
409*e4b17023SJohn Marino     __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
410*e4b17023SJohn Marino                      _RAIter2 __begin2, _RAIter2 __end2,
411*e4b17023SJohn Marino                      _Output_RAIter __result, _Predicate __pred,
412*e4b17023SJohn Marino                      random_access_iterator_tag, random_access_iterator_tag,
413*e4b17023SJohn Marino                      random_access_iterator_tag)
414*e4b17023SJohn Marino     {
415*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
416*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
417*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().set_union_minimal_n
418*e4b17023SJohn Marino             || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
419*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().set_union_minimal_n))
420*e4b17023SJohn Marino         return __gnu_parallel::__parallel_set_union(
421*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result, __pred);
422*e4b17023SJohn Marino       else
423*e4b17023SJohn Marino         return _GLIBCXX_STD_A::set_union(__begin1, __end1,
424*e4b17023SJohn Marino                                          __begin2, __end2, __result, __pred);
425*e4b17023SJohn Marino     }
426*e4b17023SJohn Marino 
427*e4b17023SJohn Marino   // Public interface
428*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
429*e4b17023SJohn Marino            typename _OutputIterator>
430*e4b17023SJohn Marino     inline _OutputIterator
431*e4b17023SJohn Marino     set_union(_IIter1 __begin1, _IIter1 __end1,
432*e4b17023SJohn Marino               _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
433*e4b17023SJohn Marino     {
434*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
435*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
436*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
437*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
438*e4b17023SJohn Marino         _IIterCategory1;
439*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
440*e4b17023SJohn Marino         _IIterCategory2;
441*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
442*e4b17023SJohn Marino       typedef typename _IIterTraits1::value_type _ValueType1;
443*e4b17023SJohn Marino       typedef typename _IIterTraits2::value_type _ValueType2;
444*e4b17023SJohn Marino 
445*e4b17023SJohn Marino       return __set_union_switch(
446*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out,
447*e4b17023SJohn Marino                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
448*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
449*e4b17023SJohn Marino     }
450*e4b17023SJohn Marino 
451*e4b17023SJohn Marino   // Public interface
452*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
453*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
454*e4b17023SJohn Marino     inline _OutputIterator
455*e4b17023SJohn Marino     set_union(_IIter1 __begin1, _IIter1 __end1,
456*e4b17023SJohn Marino               _IIter2 __begin2, _IIter2 __end2,
457*e4b17023SJohn Marino               _OutputIterator __out, _Predicate __pred)
458*e4b17023SJohn Marino     {
459*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
460*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
461*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
462*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
463*e4b17023SJohn Marino         _IIterCategory1;
464*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
465*e4b17023SJohn Marino         _IIterCategory2;
466*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
467*e4b17023SJohn Marino 
468*e4b17023SJohn Marino       return __set_union_switch(
469*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out, __pred,
470*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
471*e4b17023SJohn Marino     }
472*e4b17023SJohn Marino 
473*e4b17023SJohn Marino   // Sequential fallback.
474*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
475*e4b17023SJohn Marino            typename _OutputIterator>
476*e4b17023SJohn Marino     inline _OutputIterator
477*e4b17023SJohn Marino     set_intersection(_IIter1 __begin1, _IIter1 __end1,
478*e4b17023SJohn Marino                      _IIter2 __begin2, _IIter2 __end2,
479*e4b17023SJohn Marino                      _OutputIterator __out, __gnu_parallel::sequential_tag)
480*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1,
481*e4b17023SJohn Marino                                               __begin2, __end2, __out); }
482*e4b17023SJohn Marino 
483*e4b17023SJohn Marino   // Sequential fallback.
484*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
485*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
486*e4b17023SJohn Marino     inline _OutputIterator
487*e4b17023SJohn Marino     set_intersection(_IIter1 __begin1, _IIter1 __end1,
488*e4b17023SJohn Marino                      _IIter2 __begin2, _IIter2 __end2,
489*e4b17023SJohn Marino                      _OutputIterator __out, _Predicate __pred,
490*e4b17023SJohn Marino                      __gnu_parallel::sequential_tag)
491*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_intersection(
492*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out, __pred); }
493*e4b17023SJohn Marino 
494*e4b17023SJohn Marino   // Sequential fallback for input iterator case
495*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
496*e4b17023SJohn Marino            typename _Predicate, typename _OutputIterator,
497*e4b17023SJohn Marino            typename _IteratorTag1, typename _IteratorTag2,
498*e4b17023SJohn Marino            typename _IteratorTag3>
499*e4b17023SJohn Marino     inline _OutputIterator
500*e4b17023SJohn Marino     __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
501*e4b17023SJohn Marino                               _IIter2 __begin2, _IIter2 __end2,
502*e4b17023SJohn Marino                               _OutputIterator __result, _Predicate __pred,
503*e4b17023SJohn Marino                               _IteratorTag1, _IteratorTag2, _IteratorTag3)
504*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2,
505*e4b17023SJohn Marino                                               __end2, __result, __pred); }
506*e4b17023SJohn Marino 
507*e4b17023SJohn Marino   // Parallel set_intersection for random access iterators
508*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
509*e4b17023SJohn Marino            typename _Output_RAIter, typename _Predicate>
510*e4b17023SJohn Marino     _Output_RAIter
511*e4b17023SJohn Marino     __set_intersection_switch(_RAIter1 __begin1,
512*e4b17023SJohn Marino                             _RAIter1 __end1,
513*e4b17023SJohn Marino                             _RAIter2 __begin2,
514*e4b17023SJohn Marino                             _RAIter2 __end2,
515*e4b17023SJohn Marino                             _Output_RAIter __result,
516*e4b17023SJohn Marino                             _Predicate __pred,
517*e4b17023SJohn Marino                             random_access_iterator_tag,
518*e4b17023SJohn Marino                             random_access_iterator_tag,
519*e4b17023SJohn Marino                             random_access_iterator_tag)
520*e4b17023SJohn Marino     {
521*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
522*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
523*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().set_union_minimal_n
524*e4b17023SJohn Marino             || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
525*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().set_union_minimal_n))
526*e4b17023SJohn Marino         return __gnu_parallel::__parallel_set_intersection(
527*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result, __pred);
528*e4b17023SJohn Marino       else
529*e4b17023SJohn Marino         return _GLIBCXX_STD_A::set_intersection(
530*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result, __pred);
531*e4b17023SJohn Marino     }
532*e4b17023SJohn Marino 
533*e4b17023SJohn Marino   // Public interface
534*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
535*e4b17023SJohn Marino            typename _OutputIterator>
536*e4b17023SJohn Marino     inline _OutputIterator
537*e4b17023SJohn Marino     set_intersection(_IIter1 __begin1, _IIter1 __end1,
538*e4b17023SJohn Marino                      _IIter2 __begin2, _IIter2 __end2,
539*e4b17023SJohn Marino                      _OutputIterator __out)
540*e4b17023SJohn Marino     {
541*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
542*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
543*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
544*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
545*e4b17023SJohn Marino         _IIterCategory1;
546*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
547*e4b17023SJohn Marino         _IIterCategory2;
548*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
549*e4b17023SJohn Marino       typedef typename _IIterTraits1::value_type _ValueType1;
550*e4b17023SJohn Marino       typedef typename _IIterTraits2::value_type _ValueType2;
551*e4b17023SJohn Marino 
552*e4b17023SJohn Marino       return __set_intersection_switch(
553*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out,
554*e4b17023SJohn Marino                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
555*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
556*e4b17023SJohn Marino     }
557*e4b17023SJohn Marino 
558*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
559*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
560*e4b17023SJohn Marino     inline _OutputIterator
561*e4b17023SJohn Marino     set_intersection(_IIter1 __begin1, _IIter1 __end1,
562*e4b17023SJohn Marino                      _IIter2 __begin2, _IIter2 __end2,
563*e4b17023SJohn Marino                      _OutputIterator __out, _Predicate __pred)
564*e4b17023SJohn Marino     {
565*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
566*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
567*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
568*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
569*e4b17023SJohn Marino         _IIterCategory1;
570*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
571*e4b17023SJohn Marino         _IIterCategory2;
572*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
573*e4b17023SJohn Marino 
574*e4b17023SJohn Marino       return __set_intersection_switch(
575*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out, __pred,
576*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
577*e4b17023SJohn Marino     }
578*e4b17023SJohn Marino 
579*e4b17023SJohn Marino   // Sequential fallback
580*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
581*e4b17023SJohn Marino            typename _OutputIterator>
582*e4b17023SJohn Marino     inline _OutputIterator
583*e4b17023SJohn Marino     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
584*e4b17023SJohn Marino                              _IIter2 __begin2, _IIter2 __end2,
585*e4b17023SJohn Marino                              _OutputIterator __out,
586*e4b17023SJohn Marino                              __gnu_parallel::sequential_tag)
587*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_symmetric_difference(
588*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out); }
589*e4b17023SJohn Marino 
590*e4b17023SJohn Marino   // Sequential fallback
591*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
592*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
593*e4b17023SJohn Marino     inline _OutputIterator
594*e4b17023SJohn Marino     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
595*e4b17023SJohn Marino                              _IIter2 __begin2, _IIter2 __end2,
596*e4b17023SJohn Marino                              _OutputIterator __out, _Predicate __pred,
597*e4b17023SJohn Marino                              __gnu_parallel::sequential_tag)
598*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_symmetric_difference(
599*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out, __pred); }
600*e4b17023SJohn Marino 
601*e4b17023SJohn Marino   // Sequential fallback for input iterator case
602*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
603*e4b17023SJohn Marino            typename _Predicate, typename _OutputIterator,
604*e4b17023SJohn Marino            typename _IteratorTag1, typename _IteratorTag2,
605*e4b17023SJohn Marino            typename _IteratorTag3>
606*e4b17023SJohn Marino     inline _OutputIterator
607*e4b17023SJohn Marino     __set_symmetric_difference_switch(
608*e4b17023SJohn Marino       _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
609*e4b17023SJohn Marino       _OutputIterator __result, _Predicate __pred,
610*e4b17023SJohn Marino       _IteratorTag1, _IteratorTag2, _IteratorTag3)
611*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_symmetric_difference(
612*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __result, __pred); }
613*e4b17023SJohn Marino 
614*e4b17023SJohn Marino   // Parallel set_symmetric_difference for random access iterators
615*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
616*e4b17023SJohn Marino            typename _Output_RAIter, typename _Predicate>
617*e4b17023SJohn Marino     _Output_RAIter
618*e4b17023SJohn Marino     __set_symmetric_difference_switch(_RAIter1 __begin1,
619*e4b17023SJohn Marino                                     _RAIter1 __end1,
620*e4b17023SJohn Marino                                     _RAIter2 __begin2,
621*e4b17023SJohn Marino                                     _RAIter2 __end2,
622*e4b17023SJohn Marino                                     _Output_RAIter __result,
623*e4b17023SJohn Marino                                     _Predicate __pred,
624*e4b17023SJohn Marino                                     random_access_iterator_tag,
625*e4b17023SJohn Marino                                     random_access_iterator_tag,
626*e4b17023SJohn Marino                                     random_access_iterator_tag)
627*e4b17023SJohn Marino     {
628*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
629*e4b17023SJohn Marino       static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
630*e4b17023SJohn Marino       >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
631*e4b17023SJohn Marino       || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
632*e4b17023SJohn Marino       >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
633*e4b17023SJohn Marino   return __gnu_parallel::__parallel_set_symmetric_difference(
634*e4b17023SJohn Marino            __begin1, __end1, __begin2, __end2, __result, __pred);
635*e4b17023SJohn Marino       else
636*e4b17023SJohn Marino         return _GLIBCXX_STD_A::set_symmetric_difference(
637*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result, __pred);
638*e4b17023SJohn Marino     }
639*e4b17023SJohn Marino 
640*e4b17023SJohn Marino   // Public interface.
641*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
642*e4b17023SJohn Marino            typename _OutputIterator>
643*e4b17023SJohn Marino     inline _OutputIterator
644*e4b17023SJohn Marino     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
645*e4b17023SJohn Marino                              _IIter2 __begin2, _IIter2 __end2,
646*e4b17023SJohn Marino                              _OutputIterator __out)
647*e4b17023SJohn Marino     {
648*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
649*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
650*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
651*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
652*e4b17023SJohn Marino         _IIterCategory1;
653*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
654*e4b17023SJohn Marino         _IIterCategory2;
655*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
656*e4b17023SJohn Marino       typedef typename _IIterTraits1::value_type _ValueType1;
657*e4b17023SJohn Marino       typedef typename _IIterTraits2::value_type _ValueType2;
658*e4b17023SJohn Marino 
659*e4b17023SJohn Marino       return __set_symmetric_difference_switch(
660*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out,
661*e4b17023SJohn Marino                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
662*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
663*e4b17023SJohn Marino     }
664*e4b17023SJohn Marino 
665*e4b17023SJohn Marino   // Public interface.
666*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
667*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
668*e4b17023SJohn Marino     inline _OutputIterator
669*e4b17023SJohn Marino     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
670*e4b17023SJohn Marino                              _IIter2 __begin2, _IIter2 __end2,
671*e4b17023SJohn Marino                              _OutputIterator __out, _Predicate __pred)
672*e4b17023SJohn Marino     {
673*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
674*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
675*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
676*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
677*e4b17023SJohn Marino         _IIterCategory1;
678*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
679*e4b17023SJohn Marino         _IIterCategory2;
680*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
681*e4b17023SJohn Marino 
682*e4b17023SJohn Marino       return __set_symmetric_difference_switch(
683*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out, __pred,
684*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
685*e4b17023SJohn Marino     }
686*e4b17023SJohn Marino 
687*e4b17023SJohn Marino   // Sequential fallback.
688*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
689*e4b17023SJohn Marino            typename _OutputIterator>
690*e4b17023SJohn Marino     inline _OutputIterator
691*e4b17023SJohn Marino     set_difference(_IIter1 __begin1, _IIter1 __end1,
692*e4b17023SJohn Marino                    _IIter2 __begin2, _IIter2 __end2,
693*e4b17023SJohn Marino                    _OutputIterator __out, __gnu_parallel::sequential_tag)
694*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_difference(
695*e4b17023SJohn Marino                __begin1,__end1, __begin2, __end2, __out); }
696*e4b17023SJohn Marino 
697*e4b17023SJohn Marino   // Sequential fallback.
698*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
699*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
700*e4b17023SJohn Marino     inline _OutputIterator
701*e4b17023SJohn Marino     set_difference(_IIter1 __begin1, _IIter1 __end1,
702*e4b17023SJohn Marino                    _IIter2 __begin2, _IIter2 __end2,
703*e4b17023SJohn Marino                    _OutputIterator __out, _Predicate __pred,
704*e4b17023SJohn Marino                    __gnu_parallel::sequential_tag)
705*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_difference(__begin1, __end1,
706*e4b17023SJohn Marino                                             __begin2, __end2, __out, __pred); }
707*e4b17023SJohn Marino 
708*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
709*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2, typename _Predicate,
710*e4b17023SJohn Marino            typename _OutputIterator, typename _IteratorTag1,
711*e4b17023SJohn Marino            typename _IteratorTag2, typename _IteratorTag3>
712*e4b17023SJohn Marino     inline _OutputIterator
713*e4b17023SJohn Marino     __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
714*e4b17023SJohn Marino                           _IIter2 __begin2, _IIter2 __end2,
715*e4b17023SJohn Marino                           _OutputIterator __result, _Predicate __pred,
716*e4b17023SJohn Marino                           _IteratorTag1, _IteratorTag2, _IteratorTag3)
717*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::set_difference(
718*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __result, __pred); }
719*e4b17023SJohn Marino 
720*e4b17023SJohn Marino   // Parallel set_difference for random access iterators
721*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
722*e4b17023SJohn Marino            typename _Output_RAIter, typename _Predicate>
723*e4b17023SJohn Marino     _Output_RAIter
724*e4b17023SJohn Marino     __set_difference_switch(_RAIter1 __begin1,
725*e4b17023SJohn Marino                           _RAIter1 __end1,
726*e4b17023SJohn Marino                           _RAIter2 __begin2,
727*e4b17023SJohn Marino                           _RAIter2 __end2,
728*e4b17023SJohn Marino                           _Output_RAIter __result, _Predicate __pred,
729*e4b17023SJohn Marino                           random_access_iterator_tag,
730*e4b17023SJohn Marino                           random_access_iterator_tag,
731*e4b17023SJohn Marino                           random_access_iterator_tag)
732*e4b17023SJohn Marino     {
733*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
734*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
735*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().set_difference_minimal_n
736*e4b17023SJohn Marino             || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
737*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
738*e4b17023SJohn Marino         return __gnu_parallel::__parallel_set_difference(
739*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result, __pred);
740*e4b17023SJohn Marino       else
741*e4b17023SJohn Marino         return _GLIBCXX_STD_A::set_difference(
742*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result, __pred);
743*e4b17023SJohn Marino     }
744*e4b17023SJohn Marino 
745*e4b17023SJohn Marino   // Public interface
746*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
747*e4b17023SJohn Marino            typename _OutputIterator>
748*e4b17023SJohn Marino     inline _OutputIterator
749*e4b17023SJohn Marino     set_difference(_IIter1 __begin1, _IIter1 __end1,
750*e4b17023SJohn Marino                    _IIter2 __begin2, _IIter2 __end2,
751*e4b17023SJohn Marino                    _OutputIterator __out)
752*e4b17023SJohn Marino     {
753*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
754*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
755*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
756*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
757*e4b17023SJohn Marino         _IIterCategory1;
758*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
759*e4b17023SJohn Marino         _IIterCategory2;
760*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
761*e4b17023SJohn Marino       typedef typename _IIterTraits1::value_type _ValueType1;
762*e4b17023SJohn Marino       typedef typename _IIterTraits2::value_type _ValueType2;
763*e4b17023SJohn Marino 
764*e4b17023SJohn Marino       return __set_difference_switch(
765*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out,
766*e4b17023SJohn Marino                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
767*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
768*e4b17023SJohn Marino     }
769*e4b17023SJohn Marino 
770*e4b17023SJohn Marino   // Public interface
771*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
772*e4b17023SJohn Marino            typename _OutputIterator, typename _Predicate>
773*e4b17023SJohn Marino     inline _OutputIterator
774*e4b17023SJohn Marino     set_difference(_IIter1 __begin1, _IIter1 __end1,
775*e4b17023SJohn Marino                    _IIter2 __begin2, _IIter2 __end2,
776*e4b17023SJohn Marino                    _OutputIterator __out, _Predicate __pred)
777*e4b17023SJohn Marino     {
778*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
779*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
780*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
781*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
782*e4b17023SJohn Marino         _IIterCategory1;
783*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
784*e4b17023SJohn Marino         _IIterCategory2;
785*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
786*e4b17023SJohn Marino 
787*e4b17023SJohn Marino       return __set_difference_switch(
788*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __out, __pred,
789*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
790*e4b17023SJohn Marino     }
791*e4b17023SJohn Marino 
792*e4b17023SJohn Marino   // Sequential fallback
793*e4b17023SJohn Marino   template<typename _FIterator>
794*e4b17023SJohn Marino     inline _FIterator
795*e4b17023SJohn Marino     adjacent_find(_FIterator __begin, _FIterator __end,
796*e4b17023SJohn Marino                   __gnu_parallel::sequential_tag)
797*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::adjacent_find(__begin, __end); }
798*e4b17023SJohn Marino 
799*e4b17023SJohn Marino   // Sequential fallback
800*e4b17023SJohn Marino   template<typename _FIterator, typename _BinaryPredicate>
801*e4b17023SJohn Marino     inline _FIterator
802*e4b17023SJohn Marino     adjacent_find(_FIterator __begin, _FIterator __end,
803*e4b17023SJohn Marino                   _BinaryPredicate __binary_pred,
804*e4b17023SJohn Marino                   __gnu_parallel::sequential_tag)
805*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); }
806*e4b17023SJohn Marino 
807*e4b17023SJohn Marino   // Parallel algorithm for random access iterators
808*e4b17023SJohn Marino   template<typename _RAIter>
809*e4b17023SJohn Marino     _RAIter
810*e4b17023SJohn Marino     __adjacent_find_switch(_RAIter __begin, _RAIter __end,
811*e4b17023SJohn Marino                          random_access_iterator_tag)
812*e4b17023SJohn Marino     {
813*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
814*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
815*e4b17023SJohn Marino 
816*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(true))
817*e4b17023SJohn Marino         {
818*e4b17023SJohn Marino           _RAIter __spot = __gnu_parallel::
819*e4b17023SJohn Marino               __find_template(
820*e4b17023SJohn Marino                 __begin, __end - 1, __begin, equal_to<_ValueType>(),
821*e4b17023SJohn Marino                 __gnu_parallel::__adjacent_find_selector())
822*e4b17023SJohn Marino             .first;
823*e4b17023SJohn Marino           if (__spot == (__end - 1))
824*e4b17023SJohn Marino             return __end;
825*e4b17023SJohn Marino           else
826*e4b17023SJohn Marino             return __spot;
827*e4b17023SJohn Marino         }
828*e4b17023SJohn Marino       else
829*e4b17023SJohn Marino         return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
830*e4b17023SJohn Marino     }
831*e4b17023SJohn Marino 
832*e4b17023SJohn Marino   // Sequential fallback for input iterator case
833*e4b17023SJohn Marino   template<typename _FIterator, typename _IteratorTag>
834*e4b17023SJohn Marino     inline _FIterator
835*e4b17023SJohn Marino     __adjacent_find_switch(_FIterator __begin, _FIterator __end,
836*e4b17023SJohn Marino                          _IteratorTag)
837*e4b17023SJohn Marino     { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }
838*e4b17023SJohn Marino 
839*e4b17023SJohn Marino   // Public interface
840*e4b17023SJohn Marino   template<typename _FIterator>
841*e4b17023SJohn Marino     inline _FIterator
842*e4b17023SJohn Marino     adjacent_find(_FIterator __begin, _FIterator __end)
843*e4b17023SJohn Marino     {
844*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
845*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
846*e4b17023SJohn Marino       return __adjacent_find_switch(__begin, __end, _IteratorCategory());
847*e4b17023SJohn Marino     }
848*e4b17023SJohn Marino 
849*e4b17023SJohn Marino   // Sequential fallback for input iterator case
850*e4b17023SJohn Marino   template<typename _FIterator, typename _BinaryPredicate,
851*e4b17023SJohn Marino            typename _IteratorTag>
852*e4b17023SJohn Marino     inline _FIterator
853*e4b17023SJohn Marino     __adjacent_find_switch(_FIterator __begin, _FIterator __end,
854*e4b17023SJohn Marino                          _BinaryPredicate __pred, _IteratorTag)
855*e4b17023SJohn Marino     { return adjacent_find(__begin, __end, __pred,
856*e4b17023SJohn Marino                            __gnu_parallel::sequential_tag()); }
857*e4b17023SJohn Marino 
858*e4b17023SJohn Marino   // Parallel algorithm for random access iterators
859*e4b17023SJohn Marino   template<typename _RAIter, typename _BinaryPredicate>
860*e4b17023SJohn Marino     _RAIter
861*e4b17023SJohn Marino     __adjacent_find_switch(_RAIter __begin, _RAIter __end,
862*e4b17023SJohn Marino                          _BinaryPredicate __pred, random_access_iterator_tag)
863*e4b17023SJohn Marino     {
864*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(true))
865*e4b17023SJohn Marino         return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
866*e4b17023SJohn Marino                                              __gnu_parallel::
867*e4b17023SJohn Marino                                              __adjacent_find_selector()).first;
868*e4b17023SJohn Marino       else
869*e4b17023SJohn Marino         return adjacent_find(__begin, __end, __pred,
870*e4b17023SJohn Marino                              __gnu_parallel::sequential_tag());
871*e4b17023SJohn Marino     }
872*e4b17023SJohn Marino 
873*e4b17023SJohn Marino   // Public interface
874*e4b17023SJohn Marino   template<typename _FIterator, typename _BinaryPredicate>
875*e4b17023SJohn Marino     inline _FIterator
876*e4b17023SJohn Marino     adjacent_find(_FIterator __begin, _FIterator __end,
877*e4b17023SJohn Marino                   _BinaryPredicate __pred)
878*e4b17023SJohn Marino     {
879*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
880*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
881*e4b17023SJohn Marino       return __adjacent_find_switch(__begin, __end, __pred,
882*e4b17023SJohn Marino                                     _IteratorCategory());
883*e4b17023SJohn Marino     }
884*e4b17023SJohn Marino 
885*e4b17023SJohn Marino   // Sequential fallback
886*e4b17023SJohn Marino   template<typename _IIter, typename _Tp>
887*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
888*e4b17023SJohn Marino     count(_IIter __begin, _IIter __end, const _Tp& __value,
889*e4b17023SJohn Marino           __gnu_parallel::sequential_tag)
890*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::count(__begin, __end, __value); }
891*e4b17023SJohn Marino 
892*e4b17023SJohn Marino   // Parallel code for random access iterators
893*e4b17023SJohn Marino   template<typename _RAIter, typename _Tp>
894*e4b17023SJohn Marino     typename iterator_traits<_RAIter>::difference_type
895*e4b17023SJohn Marino     __count_switch(_RAIter __begin, _RAIter __end,
896*e4b17023SJohn Marino                  const _Tp& __value, random_access_iterator_tag,
897*e4b17023SJohn Marino                  __gnu_parallel::_Parallelism __parallelism_tag
898*e4b17023SJohn Marino                  = __gnu_parallel::parallel_unbalanced)
899*e4b17023SJohn Marino     {
900*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
901*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
902*e4b17023SJohn Marino       typedef typename _TraitsType::difference_type _DifferenceType;
903*e4b17023SJohn Marino       typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
904*e4b17023SJohn Marino 
905*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
906*e4b17023SJohn Marino             static_cast<_SequenceIndex>(__end - __begin)
907*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().count_minimal_n
908*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
909*e4b17023SJohn Marino         {
910*e4b17023SJohn Marino           __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
911*e4b17023SJohn Marino             __functionality;
912*e4b17023SJohn Marino           _DifferenceType __res = 0;
913*e4b17023SJohn Marino           __gnu_parallel::
914*e4b17023SJohn Marino             __for_each_template_random_access(
915*e4b17023SJohn Marino               __begin, __end, __value, __functionality,
916*e4b17023SJohn Marino               std::plus<_SequenceIndex>(), __res, __res, -1,
917*e4b17023SJohn Marino               __parallelism_tag);
918*e4b17023SJohn Marino           return __res;
919*e4b17023SJohn Marino         }
920*e4b17023SJohn Marino       else
921*e4b17023SJohn Marino         return count(__begin, __end, __value,
922*e4b17023SJohn Marino                      __gnu_parallel::sequential_tag());
923*e4b17023SJohn Marino     }
924*e4b17023SJohn Marino 
925*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
926*e4b17023SJohn Marino   template<typename _IIter, typename _Tp, typename _IteratorTag>
927*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
928*e4b17023SJohn Marino     __count_switch(_IIter __begin, _IIter __end, const _Tp& __value,
929*e4b17023SJohn Marino                  _IteratorTag)
930*e4b17023SJohn Marino     { return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
931*e4b17023SJohn Marino       }
932*e4b17023SJohn Marino 
933*e4b17023SJohn Marino   // Public interface.
934*e4b17023SJohn Marino   template<typename _IIter, typename _Tp>
935*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
936*e4b17023SJohn Marino     count(_IIter __begin, _IIter __end, const _Tp& __value,
937*e4b17023SJohn Marino           __gnu_parallel::_Parallelism __parallelism_tag)
938*e4b17023SJohn Marino     {
939*e4b17023SJohn Marino       typedef iterator_traits<_IIter> _TraitsType;
940*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
941*e4b17023SJohn Marino       return __count_switch(__begin, __end, __value, _IteratorCategory(),
942*e4b17023SJohn Marino                             __parallelism_tag);
943*e4b17023SJohn Marino     }
944*e4b17023SJohn Marino 
945*e4b17023SJohn Marino   template<typename _IIter, typename _Tp>
946*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
947*e4b17023SJohn Marino     count(_IIter __begin, _IIter __end, const _Tp& __value)
948*e4b17023SJohn Marino     {
949*e4b17023SJohn Marino       typedef iterator_traits<_IIter> _TraitsType;
950*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
951*e4b17023SJohn Marino       return __count_switch(__begin, __end, __value, _IteratorCategory());
952*e4b17023SJohn Marino     }
953*e4b17023SJohn Marino 
954*e4b17023SJohn Marino 
955*e4b17023SJohn Marino   // Sequential fallback.
956*e4b17023SJohn Marino   template<typename _IIter, typename _Predicate>
957*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
958*e4b17023SJohn Marino     count_if(_IIter __begin, _IIter __end, _Predicate __pred,
959*e4b17023SJohn Marino              __gnu_parallel::sequential_tag)
960*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); }
961*e4b17023SJohn Marino 
962*e4b17023SJohn Marino   // Parallel count_if for random access iterators
963*e4b17023SJohn Marino   template<typename _RAIter, typename _Predicate>
964*e4b17023SJohn Marino     typename iterator_traits<_RAIter>::difference_type
965*e4b17023SJohn Marino     __count_if_switch(_RAIter __begin, _RAIter __end,
966*e4b17023SJohn Marino                     _Predicate __pred, random_access_iterator_tag,
967*e4b17023SJohn Marino                     __gnu_parallel::_Parallelism __parallelism_tag
968*e4b17023SJohn Marino                     = __gnu_parallel::parallel_unbalanced)
969*e4b17023SJohn Marino     {
970*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
971*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
972*e4b17023SJohn Marino       typedef typename _TraitsType::difference_type _DifferenceType;
973*e4b17023SJohn Marino       typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
974*e4b17023SJohn Marino 
975*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
976*e4b17023SJohn Marino             static_cast<_SequenceIndex>(__end - __begin)
977*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().count_minimal_n
978*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
979*e4b17023SJohn Marino         {
980*e4b17023SJohn Marino           _DifferenceType __res = 0;
981*e4b17023SJohn Marino           __gnu_parallel::
982*e4b17023SJohn Marino             __count_if_selector<_RAIter, _DifferenceType>
983*e4b17023SJohn Marino             __functionality;
984*e4b17023SJohn Marino           __gnu_parallel::
985*e4b17023SJohn Marino             __for_each_template_random_access(
986*e4b17023SJohn Marino               __begin, __end, __pred, __functionality,
987*e4b17023SJohn Marino               std::plus<_SequenceIndex>(), __res, __res, -1,
988*e4b17023SJohn Marino               __parallelism_tag);
989*e4b17023SJohn Marino           return __res;
990*e4b17023SJohn Marino         }
991*e4b17023SJohn Marino       else
992*e4b17023SJohn Marino         return count_if(__begin, __end, __pred,
993*e4b17023SJohn Marino                         __gnu_parallel::sequential_tag());
994*e4b17023SJohn Marino     }
995*e4b17023SJohn Marino 
996*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
997*e4b17023SJohn Marino   template<typename _IIter, typename _Predicate, typename _IteratorTag>
998*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
999*e4b17023SJohn Marino     __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
1000*e4b17023SJohn Marino                     _IteratorTag)
1001*e4b17023SJohn Marino     { return count_if(__begin, __end, __pred,
1002*e4b17023SJohn Marino                       __gnu_parallel::sequential_tag()); }
1003*e4b17023SJohn Marino 
1004*e4b17023SJohn Marino   // Public interface.
1005*e4b17023SJohn Marino   template<typename _IIter, typename _Predicate>
1006*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
1007*e4b17023SJohn Marino     count_if(_IIter __begin, _IIter __end, _Predicate __pred,
1008*e4b17023SJohn Marino              __gnu_parallel::_Parallelism __parallelism_tag)
1009*e4b17023SJohn Marino     {
1010*e4b17023SJohn Marino       typedef iterator_traits<_IIter> _TraitsType;
1011*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
1012*e4b17023SJohn Marino       return __count_if_switch(__begin, __end, __pred, _IteratorCategory(),
1013*e4b17023SJohn Marino                              __parallelism_tag);
1014*e4b17023SJohn Marino     }
1015*e4b17023SJohn Marino 
1016*e4b17023SJohn Marino   template<typename _IIter, typename _Predicate>
1017*e4b17023SJohn Marino     inline typename iterator_traits<_IIter>::difference_type
1018*e4b17023SJohn Marino     count_if(_IIter __begin, _IIter __end, _Predicate __pred)
1019*e4b17023SJohn Marino     {
1020*e4b17023SJohn Marino       typedef iterator_traits<_IIter> _TraitsType;
1021*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
1022*e4b17023SJohn Marino       return __count_if_switch(__begin, __end, __pred, _IteratorCategory());
1023*e4b17023SJohn Marino     }
1024*e4b17023SJohn Marino 
1025*e4b17023SJohn Marino 
1026*e4b17023SJohn Marino   // Sequential fallback.
1027*e4b17023SJohn Marino   template<typename _FIterator1, typename _FIterator2>
1028*e4b17023SJohn Marino     inline _FIterator1
1029*e4b17023SJohn Marino     search(_FIterator1 __begin1, _FIterator1 __end1,
1030*e4b17023SJohn Marino            _FIterator2 __begin2, _FIterator2 __end2,
1031*e4b17023SJohn Marino            __gnu_parallel::sequential_tag)
1032*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); }
1033*e4b17023SJohn Marino 
1034*e4b17023SJohn Marino   // Parallel algorithm for random access iterator
1035*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2>
1036*e4b17023SJohn Marino     _RAIter1
1037*e4b17023SJohn Marino     __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
1038*e4b17023SJohn Marino                   _RAIter2 __begin2, _RAIter2 __end2,
1039*e4b17023SJohn Marino                   random_access_iterator_tag, random_access_iterator_tag)
1040*e4b17023SJohn Marino     {
1041*e4b17023SJohn Marino       typedef std::iterator_traits<_RAIter1> _Iterator1Traits;
1042*e4b17023SJohn Marino       typedef typename _Iterator1Traits::value_type _ValueType1;
1043*e4b17023SJohn Marino       typedef std::iterator_traits<_RAIter2> _Iterator2Traits;
1044*e4b17023SJohn Marino       typedef typename _Iterator2Traits::value_type _ValueType2;
1045*e4b17023SJohn Marino 
1046*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1047*e4b17023SJohn Marino                 static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
1048*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().search_minimal_n))
1049*e4b17023SJohn Marino         return __gnu_parallel::
1050*e4b17023SJohn Marino           __search_template(
1051*e4b17023SJohn Marino             __begin1, __end1, __begin2, __end2,
1052*e4b17023SJohn Marino             __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>());
1053*e4b17023SJohn Marino       else
1054*e4b17023SJohn Marino         return search(__begin1, __end1, __begin2, __end2,
1055*e4b17023SJohn Marino                       __gnu_parallel::sequential_tag());
1056*e4b17023SJohn Marino     }
1057*e4b17023SJohn Marino 
1058*e4b17023SJohn Marino   // Sequential fallback for input iterator case
1059*e4b17023SJohn Marino   template<typename _FIterator1, typename _FIterator2,
1060*e4b17023SJohn Marino            typename _IteratorTag1, typename _IteratorTag2>
1061*e4b17023SJohn Marino     inline _FIterator1
1062*e4b17023SJohn Marino     __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
1063*e4b17023SJohn Marino                   _FIterator2 __begin2, _FIterator2 __end2,
1064*e4b17023SJohn Marino                   _IteratorTag1, _IteratorTag2)
1065*e4b17023SJohn Marino     { return search(__begin1, __end1, __begin2, __end2,
1066*e4b17023SJohn Marino                     __gnu_parallel::sequential_tag()); }
1067*e4b17023SJohn Marino 
1068*e4b17023SJohn Marino   // Public interface.
1069*e4b17023SJohn Marino   template<typename _FIterator1, typename _FIterator2>
1070*e4b17023SJohn Marino     inline _FIterator1
1071*e4b17023SJohn Marino     search(_FIterator1 __begin1, _FIterator1 __end1,
1072*e4b17023SJohn Marino            _FIterator2 __begin2, _FIterator2 __end2)
1073*e4b17023SJohn Marino     {
1074*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
1075*e4b17023SJohn Marino       typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
1076*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
1077*e4b17023SJohn Marino       typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
1078*e4b17023SJohn Marino 
1079*e4b17023SJohn Marino       return __search_switch(__begin1, __end1, __begin2, __end2,
1080*e4b17023SJohn Marino                            _IteratorCategory1(), _IteratorCategory2());
1081*e4b17023SJohn Marino     }
1082*e4b17023SJohn Marino 
1083*e4b17023SJohn Marino   // Public interface.
1084*e4b17023SJohn Marino   template<typename _FIterator1, typename _FIterator2,
1085*e4b17023SJohn Marino            typename _BinaryPredicate>
1086*e4b17023SJohn Marino     inline _FIterator1
1087*e4b17023SJohn Marino     search(_FIterator1 __begin1, _FIterator1 __end1,
1088*e4b17023SJohn Marino            _FIterator2 __begin2, _FIterator2 __end2,
1089*e4b17023SJohn Marino            _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
1090*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::search(
1091*e4b17023SJohn Marino                                __begin1, __end1, __begin2, __end2, __pred); }
1092*e4b17023SJohn Marino 
1093*e4b17023SJohn Marino   // Parallel algorithm for random access iterator.
1094*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
1095*e4b17023SJohn Marino            typename _BinaryPredicate>
1096*e4b17023SJohn Marino     _RAIter1
1097*e4b17023SJohn Marino     __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
1098*e4b17023SJohn Marino                   _RAIter2 __begin2, _RAIter2 __end2,
1099*e4b17023SJohn Marino                   _BinaryPredicate __pred,
1100*e4b17023SJohn Marino                   random_access_iterator_tag, random_access_iterator_tag)
1101*e4b17023SJohn Marino     {
1102*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1103*e4b17023SJohn Marino                 static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
1104*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().search_minimal_n))
1105*e4b17023SJohn Marino         return __gnu_parallel::__search_template(__begin1, __end1,
1106*e4b17023SJohn Marino                                                __begin2, __end2, __pred);
1107*e4b17023SJohn Marino       else
1108*e4b17023SJohn Marino         return search(__begin1, __end1, __begin2, __end2, __pred,
1109*e4b17023SJohn Marino                       __gnu_parallel::sequential_tag());
1110*e4b17023SJohn Marino     }
1111*e4b17023SJohn Marino 
1112*e4b17023SJohn Marino   // Sequential fallback for input iterator case
1113*e4b17023SJohn Marino   template<typename _FIterator1, typename _FIterator2,
1114*e4b17023SJohn Marino            typename _BinaryPredicate, typename _IteratorTag1,
1115*e4b17023SJohn Marino            typename _IteratorTag2>
1116*e4b17023SJohn Marino     inline _FIterator1
1117*e4b17023SJohn Marino     __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
1118*e4b17023SJohn Marino                   _FIterator2 __begin2, _FIterator2 __end2,
1119*e4b17023SJohn Marino                   _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
1120*e4b17023SJohn Marino     { return search(__begin1, __end1, __begin2, __end2, __pred,
1121*e4b17023SJohn Marino                     __gnu_parallel::sequential_tag()); }
1122*e4b17023SJohn Marino 
1123*e4b17023SJohn Marino   // Public interface
1124*e4b17023SJohn Marino   template<typename _FIterator1, typename _FIterator2,
1125*e4b17023SJohn Marino            typename _BinaryPredicate>
1126*e4b17023SJohn Marino     inline _FIterator1
1127*e4b17023SJohn Marino     search(_FIterator1 __begin1, _FIterator1 __end1,
1128*e4b17023SJohn Marino            _FIterator2 __begin2, _FIterator2 __end2,
1129*e4b17023SJohn Marino            _BinaryPredicate  __pred)
1130*e4b17023SJohn Marino     {
1131*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
1132*e4b17023SJohn Marino       typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
1133*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
1134*e4b17023SJohn Marino       typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
1135*e4b17023SJohn Marino       return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
1136*e4b17023SJohn Marino                            _IteratorCategory1(), _IteratorCategory2());
1137*e4b17023SJohn Marino     }
1138*e4b17023SJohn Marino 
1139*e4b17023SJohn Marino   // Sequential fallback
1140*e4b17023SJohn Marino   template<typename _FIterator, typename _Integer, typename _Tp>
1141*e4b17023SJohn Marino     inline _FIterator
1142*e4b17023SJohn Marino     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1143*e4b17023SJohn Marino              const _Tp& __val, __gnu_parallel::sequential_tag)
1144*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); }
1145*e4b17023SJohn Marino 
1146*e4b17023SJohn Marino   // Sequential fallback
1147*e4b17023SJohn Marino   template<typename _FIterator, typename _Integer, typename _Tp,
1148*e4b17023SJohn Marino            typename _BinaryPredicate>
1149*e4b17023SJohn Marino     inline _FIterator
1150*e4b17023SJohn Marino     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1151*e4b17023SJohn Marino              const _Tp& __val, _BinaryPredicate __binary_pred,
1152*e4b17023SJohn Marino              __gnu_parallel::sequential_tag)
1153*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::search_n(
1154*e4b17023SJohn Marino                __begin, __end, __count, __val, __binary_pred); }
1155*e4b17023SJohn Marino 
1156*e4b17023SJohn Marino   // Public interface.
1157*e4b17023SJohn Marino   template<typename _FIterator, typename _Integer, typename _Tp>
1158*e4b17023SJohn Marino     inline _FIterator
1159*e4b17023SJohn Marino     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1160*e4b17023SJohn Marino              const _Tp& __val)
1161*e4b17023SJohn Marino     {
1162*e4b17023SJohn Marino       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
1163*e4b17023SJohn Marino       return __gnu_parallel::search_n(__begin, __end, __count, __val,
1164*e4b17023SJohn Marino                       __gnu_parallel::_EqualTo<_ValueType, _Tp>());
1165*e4b17023SJohn Marino     }
1166*e4b17023SJohn Marino 
1167*e4b17023SJohn Marino   // Parallel algorithm for random access iterators.
1168*e4b17023SJohn Marino   template<typename _RAIter, typename _Integer,
1169*e4b17023SJohn Marino            typename _Tp, typename _BinaryPredicate>
1170*e4b17023SJohn Marino     _RAIter
1171*e4b17023SJohn Marino     __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count,
1172*e4b17023SJohn Marino                       const _Tp& __val, _BinaryPredicate __binary_pred,
1173*e4b17023SJohn Marino                       random_access_iterator_tag)
1174*e4b17023SJohn Marino     {
1175*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1176*e4b17023SJohn Marino                 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1177*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().search_minimal_n))
1178*e4b17023SJohn Marino         {
1179*e4b17023SJohn Marino           __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count);
1180*e4b17023SJohn Marino           return __gnu_parallel::__search_template(
1181*e4b17023SJohn Marino                    __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
1182*e4b17023SJohn Marino         }
1183*e4b17023SJohn Marino       else
1184*e4b17023SJohn Marino         return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
1185*e4b17023SJohn Marino                                         __binary_pred);
1186*e4b17023SJohn Marino     }
1187*e4b17023SJohn Marino 
1188*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
1189*e4b17023SJohn Marino   template<typename _FIterator, typename _Integer, typename _Tp,
1190*e4b17023SJohn Marino            typename _BinaryPredicate, typename _IteratorTag>
1191*e4b17023SJohn Marino     inline _FIterator
1192*e4b17023SJohn Marino     __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count,
1193*e4b17023SJohn Marino                       const _Tp& __val, _BinaryPredicate __binary_pred,
1194*e4b17023SJohn Marino                       _IteratorTag)
1195*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
1196*e4b17023SJohn Marino                                       __binary_pred); }
1197*e4b17023SJohn Marino 
1198*e4b17023SJohn Marino   // Public interface.
1199*e4b17023SJohn Marino   template<typename _FIterator, typename _Integer, typename _Tp,
1200*e4b17023SJohn Marino            typename _BinaryPredicate>
1201*e4b17023SJohn Marino     inline _FIterator
1202*e4b17023SJohn Marino     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1203*e4b17023SJohn Marino              const _Tp& __val, _BinaryPredicate __binary_pred)
1204*e4b17023SJohn Marino     {
1205*e4b17023SJohn Marino       return __search_n_switch(__begin, __end, __count, __val, __binary_pred,
1206*e4b17023SJohn Marino                              typename std::iterator_traits<_FIterator>::
1207*e4b17023SJohn Marino                              iterator_category());
1208*e4b17023SJohn Marino     }
1209*e4b17023SJohn Marino 
1210*e4b17023SJohn Marino 
1211*e4b17023SJohn Marino   // Sequential fallback.
1212*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator,
1213*e4b17023SJohn Marino            typename _UnaryOperation>
1214*e4b17023SJohn Marino     inline _OutputIterator
1215*e4b17023SJohn Marino     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1216*e4b17023SJohn Marino               _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
1217*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); }
1218*e4b17023SJohn Marino 
1219*e4b17023SJohn Marino   // Parallel unary transform for random access iterators.
1220*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
1221*e4b17023SJohn Marino            typename _UnaryOperation>
1222*e4b17023SJohn Marino     _RAIter2
1223*e4b17023SJohn Marino     __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
1224*e4b17023SJohn Marino                       _RAIter2 __result, _UnaryOperation __unary_op,
1225*e4b17023SJohn Marino                       random_access_iterator_tag, random_access_iterator_tag,
1226*e4b17023SJohn Marino                       __gnu_parallel::_Parallelism __parallelism_tag
1227*e4b17023SJohn Marino                       = __gnu_parallel::parallel_balanced)
1228*e4b17023SJohn Marino     {
1229*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1230*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1231*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().transform_minimal_n
1232*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
1233*e4b17023SJohn Marino         {
1234*e4b17023SJohn Marino           bool __dummy = true;
1235*e4b17023SJohn Marino           typedef __gnu_parallel::_IteratorPair<_RAIter1,
1236*e4b17023SJohn Marino             _RAIter2, random_access_iterator_tag> _ItTrip;
1237*e4b17023SJohn Marino           _ItTrip __begin_pair(__begin, __result),
1238*e4b17023SJohn Marino                   __end_pair(__end, __result + (__end - __begin));
1239*e4b17023SJohn Marino           __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
1240*e4b17023SJohn Marino           __gnu_parallel::
1241*e4b17023SJohn Marino             __for_each_template_random_access(
1242*e4b17023SJohn Marino               __begin_pair, __end_pair, __unary_op, __functionality,
1243*e4b17023SJohn Marino               __gnu_parallel::_DummyReduct(),
1244*e4b17023SJohn Marino               __dummy, __dummy, -1, __parallelism_tag);
1245*e4b17023SJohn Marino           return __functionality._M_finish_iterator;
1246*e4b17023SJohn Marino         }
1247*e4b17023SJohn Marino       else
1248*e4b17023SJohn Marino         return transform(__begin, __end, __result, __unary_op,
1249*e4b17023SJohn Marino                          __gnu_parallel::sequential_tag());
1250*e4b17023SJohn Marino     }
1251*e4b17023SJohn Marino 
1252*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
1253*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
1254*e4b17023SJohn Marino            typename _UnaryOperation, typename _IteratorTag1,
1255*e4b17023SJohn Marino            typename _IteratorTag2>
1256*e4b17023SJohn Marino     inline _RAIter2
1257*e4b17023SJohn Marino     __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
1258*e4b17023SJohn Marino                       _RAIter2 __result, _UnaryOperation __unary_op,
1259*e4b17023SJohn Marino                       _IteratorTag1, _IteratorTag2)
1260*e4b17023SJohn Marino     { return transform(__begin, __end, __result, __unary_op,
1261*e4b17023SJohn Marino                        __gnu_parallel::sequential_tag()); }
1262*e4b17023SJohn Marino 
1263*e4b17023SJohn Marino   // Public interface.
1264*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator,
1265*e4b17023SJohn Marino            typename _UnaryOperation>
1266*e4b17023SJohn Marino     inline _OutputIterator
1267*e4b17023SJohn Marino     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1268*e4b17023SJohn Marino               _UnaryOperation __unary_op,
1269*e4b17023SJohn Marino               __gnu_parallel::_Parallelism __parallelism_tag)
1270*e4b17023SJohn Marino     {
1271*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IIterTraits;
1272*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1273*e4b17023SJohn Marino       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
1274*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
1275*e4b17023SJohn Marino 
1276*e4b17023SJohn Marino       return __transform1_switch(__begin, __end, __result, __unary_op,
1277*e4b17023SJohn Marino                                _IIteratorCategory(), _OIterCategory(),
1278*e4b17023SJohn Marino                                __parallelism_tag);
1279*e4b17023SJohn Marino     }
1280*e4b17023SJohn Marino 
1281*e4b17023SJohn Marino   template<typename _IIter, typename _OutputIterator,
1282*e4b17023SJohn Marino            typename _UnaryOperation>
1283*e4b17023SJohn Marino     inline _OutputIterator
1284*e4b17023SJohn Marino     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1285*e4b17023SJohn Marino               _UnaryOperation __unary_op)
1286*e4b17023SJohn Marino     {
1287*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter> _IIterTraits;
1288*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1289*e4b17023SJohn Marino       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
1290*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
1291*e4b17023SJohn Marino 
1292*e4b17023SJohn Marino       return __transform1_switch(__begin, __end, __result, __unary_op,
1293*e4b17023SJohn Marino                                _IIteratorCategory(), _OIterCategory());
1294*e4b17023SJohn Marino     }
1295*e4b17023SJohn Marino 
1296*e4b17023SJohn Marino 
1297*e4b17023SJohn Marino   // Sequential fallback
1298*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
1299*e4b17023SJohn Marino            typename _OutputIterator, typename _BinaryOperation>
1300*e4b17023SJohn Marino     inline _OutputIterator
1301*e4b17023SJohn Marino     transform(_IIter1 __begin1, _IIter1 __end1,
1302*e4b17023SJohn Marino               _IIter2 __begin2, _OutputIterator __result,
1303*e4b17023SJohn Marino               _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
1304*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::transform(__begin1, __end1,
1305*e4b17023SJohn Marino                                        __begin2, __result, __binary_op); }
1306*e4b17023SJohn Marino 
1307*e4b17023SJohn Marino   // Parallel binary transform for random access iterators.
1308*e4b17023SJohn Marino   template<typename _RAIter1, typename _RAIter2,
1309*e4b17023SJohn Marino            typename _RAIter3, typename _BinaryOperation>
1310*e4b17023SJohn Marino     _RAIter3
1311*e4b17023SJohn Marino     __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
1312*e4b17023SJohn Marino                       _RAIter2 __begin2,
1313*e4b17023SJohn Marino                       _RAIter3 __result, _BinaryOperation __binary_op,
1314*e4b17023SJohn Marino                       random_access_iterator_tag, random_access_iterator_tag,
1315*e4b17023SJohn Marino                       random_access_iterator_tag,
1316*e4b17023SJohn Marino                       __gnu_parallel::_Parallelism __parallelism_tag
1317*e4b17023SJohn Marino                       = __gnu_parallel::parallel_balanced)
1318*e4b17023SJohn Marino     {
1319*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1320*e4b17023SJohn Marino             (__end1 - __begin1) >=
1321*e4b17023SJohn Marino                 __gnu_parallel::_Settings::get().transform_minimal_n
1322*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
1323*e4b17023SJohn Marino         {
1324*e4b17023SJohn Marino           bool __dummy = true;
1325*e4b17023SJohn Marino           typedef __gnu_parallel::_IteratorTriple<_RAIter1,
1326*e4b17023SJohn Marino             _RAIter2, _RAIter3,
1327*e4b17023SJohn Marino             random_access_iterator_tag> _ItTrip;
1328*e4b17023SJohn Marino           _ItTrip __begin_triple(__begin1, __begin2, __result),
1329*e4b17023SJohn Marino             __end_triple(__end1, __begin2 + (__end1 - __begin1),
1330*e4b17023SJohn Marino                        __result + (__end1 - __begin1));
1331*e4b17023SJohn Marino           __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
1332*e4b17023SJohn Marino           __gnu_parallel::
1333*e4b17023SJohn Marino             __for_each_template_random_access(__begin_triple, __end_triple,
1334*e4b17023SJohn Marino                                             __binary_op, __functionality,
1335*e4b17023SJohn Marino                                             __gnu_parallel::_DummyReduct(),
1336*e4b17023SJohn Marino                                             __dummy, __dummy, -1,
1337*e4b17023SJohn Marino                                             __parallelism_tag);
1338*e4b17023SJohn Marino           return __functionality._M_finish_iterator;
1339*e4b17023SJohn Marino         }
1340*e4b17023SJohn Marino       else
1341*e4b17023SJohn Marino         return transform(__begin1, __end1, __begin2, __result, __binary_op,
1342*e4b17023SJohn Marino                          __gnu_parallel::sequential_tag());
1343*e4b17023SJohn Marino     }
1344*e4b17023SJohn Marino 
1345*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
1346*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
1347*e4b17023SJohn Marino            typename _OutputIterator, typename _BinaryOperation,
1348*e4b17023SJohn Marino            typename _Tag1, typename _Tag2, typename _Tag3>
1349*e4b17023SJohn Marino     inline _OutputIterator
1350*e4b17023SJohn Marino     __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
1351*e4b17023SJohn Marino                       _IIter2 __begin2, _OutputIterator __result,
1352*e4b17023SJohn Marino                       _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
1353*e4b17023SJohn Marino     { return transform(__begin1, __end1, __begin2, __result, __binary_op,
1354*e4b17023SJohn Marino                        __gnu_parallel::sequential_tag()); }
1355*e4b17023SJohn Marino 
1356*e4b17023SJohn Marino   // Public interface.
1357*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
1358*e4b17023SJohn Marino            typename _OutputIterator, typename _BinaryOperation>
1359*e4b17023SJohn Marino     inline _OutputIterator
1360*e4b17023SJohn Marino     transform(_IIter1 __begin1, _IIter1 __end1,
1361*e4b17023SJohn Marino               _IIter2 __begin2, _OutputIterator __result,
1362*e4b17023SJohn Marino               _BinaryOperation __binary_op,
1363*e4b17023SJohn Marino               __gnu_parallel::_Parallelism __parallelism_tag)
1364*e4b17023SJohn Marino     {
1365*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
1366*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
1367*e4b17023SJohn Marino         _IIterCategory1;
1368*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
1369*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
1370*e4b17023SJohn Marino         _IIterCategory2;
1371*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1372*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
1373*e4b17023SJohn Marino 
1374*e4b17023SJohn Marino       return __transform2_switch(
1375*e4b17023SJohn Marino                __begin1, __end1, __begin2, __result, __binary_op,
1376*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory(),
1377*e4b17023SJohn Marino                __parallelism_tag);
1378*e4b17023SJohn Marino     }
1379*e4b17023SJohn Marino 
1380*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
1381*e4b17023SJohn Marino            typename _OutputIterator, typename _BinaryOperation>
1382*e4b17023SJohn Marino     inline _OutputIterator
1383*e4b17023SJohn Marino     transform(_IIter1 __begin1, _IIter1 __end1,
1384*e4b17023SJohn Marino               _IIter2 __begin2, _OutputIterator __result,
1385*e4b17023SJohn Marino               _BinaryOperation __binary_op)
1386*e4b17023SJohn Marino     {
1387*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
1388*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
1389*e4b17023SJohn Marino         _IIterCategory1;
1390*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
1391*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
1392*e4b17023SJohn Marino         _IIterCategory2;
1393*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1394*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
1395*e4b17023SJohn Marino 
1396*e4b17023SJohn Marino       return __transform2_switch(
1397*e4b17023SJohn Marino                __begin1, __end1, __begin2, __result, __binary_op,
1398*e4b17023SJohn Marino                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
1399*e4b17023SJohn Marino     }
1400*e4b17023SJohn Marino 
1401*e4b17023SJohn Marino   // Sequential fallback
1402*e4b17023SJohn Marino   template<typename _FIterator, typename _Tp>
1403*e4b17023SJohn Marino     inline void
1404*e4b17023SJohn Marino     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1405*e4b17023SJohn Marino             const _Tp& __new_value, __gnu_parallel::sequential_tag)
1406*e4b17023SJohn Marino     { _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); }
1407*e4b17023SJohn Marino 
1408*e4b17023SJohn Marino   // Sequential fallback for input iterator case
1409*e4b17023SJohn Marino   template<typename _FIterator, typename _Tp, typename _IteratorTag>
1410*e4b17023SJohn Marino     inline void
1411*e4b17023SJohn Marino     __replace_switch(_FIterator __begin, _FIterator __end,
1412*e4b17023SJohn Marino                      const _Tp& __old_value, const _Tp& __new_value,
1413*e4b17023SJohn Marino                      _IteratorTag)
1414*e4b17023SJohn Marino     { replace(__begin, __end, __old_value, __new_value,
1415*e4b17023SJohn Marino               __gnu_parallel::sequential_tag()); }
1416*e4b17023SJohn Marino 
1417*e4b17023SJohn Marino   // Parallel replace for random access iterators
1418*e4b17023SJohn Marino   template<typename _RAIter, typename _Tp>
1419*e4b17023SJohn Marino     inline void
1420*e4b17023SJohn Marino     __replace_switch(_RAIter __begin, _RAIter __end,
1421*e4b17023SJohn Marino                    const _Tp& __old_value, const _Tp& __new_value,
1422*e4b17023SJohn Marino                    random_access_iterator_tag,
1423*e4b17023SJohn Marino                    __gnu_parallel::_Parallelism __parallelism_tag
1424*e4b17023SJohn Marino                    = __gnu_parallel::parallel_balanced)
1425*e4b17023SJohn Marino     {
1426*e4b17023SJohn Marino       // XXX parallel version is where?
1427*e4b17023SJohn Marino       replace(__begin, __end, __old_value, __new_value,
1428*e4b17023SJohn Marino               __gnu_parallel::sequential_tag());
1429*e4b17023SJohn Marino     }
1430*e4b17023SJohn Marino 
1431*e4b17023SJohn Marino   // Public interface
1432*e4b17023SJohn Marino   template<typename _FIterator, typename _Tp>
1433*e4b17023SJohn Marino     inline void
1434*e4b17023SJohn Marino     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1435*e4b17023SJohn Marino             const _Tp& __new_value,
1436*e4b17023SJohn Marino             __gnu_parallel::_Parallelism __parallelism_tag)
1437*e4b17023SJohn Marino     {
1438*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
1439*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
1440*e4b17023SJohn Marino       __replace_switch(__begin, __end, __old_value, __new_value,
1441*e4b17023SJohn Marino                        _IteratorCategory(),
1442*e4b17023SJohn Marino                      __parallelism_tag);
1443*e4b17023SJohn Marino     }
1444*e4b17023SJohn Marino 
1445*e4b17023SJohn Marino   template<typename _FIterator, typename _Tp>
1446*e4b17023SJohn Marino     inline void
1447*e4b17023SJohn Marino     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1448*e4b17023SJohn Marino             const _Tp& __new_value)
1449*e4b17023SJohn Marino     {
1450*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
1451*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
1452*e4b17023SJohn Marino       __replace_switch(__begin, __end, __old_value, __new_value,
1453*e4b17023SJohn Marino                        _IteratorCategory());
1454*e4b17023SJohn Marino     }
1455*e4b17023SJohn Marino 
1456*e4b17023SJohn Marino 
1457*e4b17023SJohn Marino   // Sequential fallback
1458*e4b17023SJohn Marino   template<typename _FIterator, typename _Predicate, typename _Tp>
1459*e4b17023SJohn Marino     inline void
1460*e4b17023SJohn Marino     replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
1461*e4b17023SJohn Marino                const _Tp& __new_value, __gnu_parallel::sequential_tag)
1462*e4b17023SJohn Marino     { _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); }
1463*e4b17023SJohn Marino 
1464*e4b17023SJohn Marino   // Sequential fallback for input iterator case
1465*e4b17023SJohn Marino   template<typename _FIterator, typename _Predicate, typename _Tp,
1466*e4b17023SJohn Marino            typename _IteratorTag>
1467*e4b17023SJohn Marino     inline void
1468*e4b17023SJohn Marino     __replace_if_switch(_FIterator __begin, _FIterator __end,
1469*e4b17023SJohn Marino                       _Predicate __pred, const _Tp& __new_value, _IteratorTag)
1470*e4b17023SJohn Marino     { replace_if(__begin, __end, __pred, __new_value,
1471*e4b17023SJohn Marino                  __gnu_parallel::sequential_tag()); }
1472*e4b17023SJohn Marino 
1473*e4b17023SJohn Marino   // Parallel algorithm for random access iterators.
1474*e4b17023SJohn Marino   template<typename _RAIter, typename _Predicate, typename _Tp>
1475*e4b17023SJohn Marino     void
1476*e4b17023SJohn Marino     __replace_if_switch(_RAIter __begin, _RAIter __end,
1477*e4b17023SJohn Marino                       _Predicate __pred, const _Tp& __new_value,
1478*e4b17023SJohn Marino                       random_access_iterator_tag,
1479*e4b17023SJohn Marino                       __gnu_parallel::_Parallelism __parallelism_tag
1480*e4b17023SJohn Marino                       = __gnu_parallel::parallel_balanced)
1481*e4b17023SJohn Marino     {
1482*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1483*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1484*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().replace_minimal_n
1485*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
1486*e4b17023SJohn Marino         {
1487*e4b17023SJohn Marino           bool __dummy;
1488*e4b17023SJohn Marino           __gnu_parallel::
1489*e4b17023SJohn Marino             __replace_if_selector<_RAIter, _Predicate, _Tp>
1490*e4b17023SJohn Marino             __functionality(__new_value);
1491*e4b17023SJohn Marino           __gnu_parallel::
1492*e4b17023SJohn Marino             __for_each_template_random_access(
1493*e4b17023SJohn Marino               __begin, __end, __pred, __functionality,
1494*e4b17023SJohn Marino               __gnu_parallel::_DummyReduct(),
1495*e4b17023SJohn Marino               true, __dummy, -1, __parallelism_tag);
1496*e4b17023SJohn Marino         }
1497*e4b17023SJohn Marino       else
1498*e4b17023SJohn Marino         replace_if(__begin, __end, __pred, __new_value,
1499*e4b17023SJohn Marino                    __gnu_parallel::sequential_tag());
1500*e4b17023SJohn Marino     }
1501*e4b17023SJohn Marino 
1502*e4b17023SJohn Marino   // Public interface.
1503*e4b17023SJohn Marino   template<typename _FIterator, typename _Predicate, typename _Tp>
1504*e4b17023SJohn Marino     inline void
1505*e4b17023SJohn Marino     replace_if(_FIterator __begin, _FIterator __end,
1506*e4b17023SJohn Marino                _Predicate __pred, const _Tp& __new_value,
1507*e4b17023SJohn Marino                __gnu_parallel::_Parallelism __parallelism_tag)
1508*e4b17023SJohn Marino     {
1509*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator> _IteratorTraits;
1510*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1511*e4b17023SJohn Marino       __replace_if_switch(__begin, __end, __pred, __new_value,
1512*e4b17023SJohn Marino                           _IteratorCategory(), __parallelism_tag);
1513*e4b17023SJohn Marino     }
1514*e4b17023SJohn Marino 
1515*e4b17023SJohn Marino   template<typename _FIterator, typename _Predicate, typename _Tp>
1516*e4b17023SJohn Marino     inline void
1517*e4b17023SJohn Marino     replace_if(_FIterator __begin, _FIterator __end,
1518*e4b17023SJohn Marino                _Predicate __pred, const _Tp& __new_value)
1519*e4b17023SJohn Marino     {
1520*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator> _IteratorTraits;
1521*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1522*e4b17023SJohn Marino       __replace_if_switch(__begin, __end, __pred, __new_value,
1523*e4b17023SJohn Marino                           _IteratorCategory());
1524*e4b17023SJohn Marino     }
1525*e4b17023SJohn Marino 
1526*e4b17023SJohn Marino   // Sequential fallback
1527*e4b17023SJohn Marino   template<typename _FIterator, typename _Generator>
1528*e4b17023SJohn Marino     inline void
1529*e4b17023SJohn Marino     generate(_FIterator __begin, _FIterator __end, _Generator __gen,
1530*e4b17023SJohn Marino              __gnu_parallel::sequential_tag)
1531*e4b17023SJohn Marino     { _GLIBCXX_STD_A::generate(__begin, __end, __gen); }
1532*e4b17023SJohn Marino 
1533*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
1534*e4b17023SJohn Marino   template<typename _FIterator, typename _Generator, typename _IteratorTag>
1535*e4b17023SJohn Marino     inline void
1536*e4b17023SJohn Marino     __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen,
1537*e4b17023SJohn Marino                     _IteratorTag)
1538*e4b17023SJohn Marino     { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }
1539*e4b17023SJohn Marino 
1540*e4b17023SJohn Marino   // Parallel algorithm for random access iterators.
1541*e4b17023SJohn Marino   template<typename _RAIter, typename _Generator>
1542*e4b17023SJohn Marino     void
1543*e4b17023SJohn Marino     __generate_switch(_RAIter __begin, _RAIter __end,
1544*e4b17023SJohn Marino                     _Generator __gen, random_access_iterator_tag,
1545*e4b17023SJohn Marino                     __gnu_parallel::_Parallelism __parallelism_tag
1546*e4b17023SJohn Marino                     = __gnu_parallel::parallel_balanced)
1547*e4b17023SJohn Marino     {
1548*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1549*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1550*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().generate_minimal_n
1551*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
1552*e4b17023SJohn Marino         {
1553*e4b17023SJohn Marino           bool __dummy;
1554*e4b17023SJohn Marino           __gnu_parallel::__generate_selector<_RAIter>
1555*e4b17023SJohn Marino             __functionality;
1556*e4b17023SJohn Marino           __gnu_parallel::
1557*e4b17023SJohn Marino             __for_each_template_random_access(
1558*e4b17023SJohn Marino               __begin, __end, __gen, __functionality,
1559*e4b17023SJohn Marino               __gnu_parallel::_DummyReduct(),
1560*e4b17023SJohn Marino               true, __dummy, -1, __parallelism_tag);
1561*e4b17023SJohn Marino         }
1562*e4b17023SJohn Marino       else
1563*e4b17023SJohn Marino         generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
1564*e4b17023SJohn Marino     }
1565*e4b17023SJohn Marino 
1566*e4b17023SJohn Marino   // Public interface.
1567*e4b17023SJohn Marino   template<typename _FIterator, typename _Generator>
1568*e4b17023SJohn Marino     inline void
1569*e4b17023SJohn Marino     generate(_FIterator __begin, _FIterator __end,
1570*e4b17023SJohn Marino              _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
1571*e4b17023SJohn Marino     {
1572*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator> _IteratorTraits;
1573*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1574*e4b17023SJohn Marino       __generate_switch(__begin, __end, __gen, _IteratorCategory(),
1575*e4b17023SJohn Marino                         __parallelism_tag);
1576*e4b17023SJohn Marino     }
1577*e4b17023SJohn Marino 
1578*e4b17023SJohn Marino   template<typename _FIterator, typename _Generator>
1579*e4b17023SJohn Marino     inline void
1580*e4b17023SJohn Marino     generate(_FIterator __begin, _FIterator __end, _Generator __gen)
1581*e4b17023SJohn Marino     {
1582*e4b17023SJohn Marino       typedef std::iterator_traits<_FIterator> _IteratorTraits;
1583*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1584*e4b17023SJohn Marino       __generate_switch(__begin, __end, __gen, _IteratorCategory());
1585*e4b17023SJohn Marino     }
1586*e4b17023SJohn Marino 
1587*e4b17023SJohn Marino 
1588*e4b17023SJohn Marino   // Sequential fallback.
1589*e4b17023SJohn Marino   template<typename _OutputIterator, typename _Size, typename _Generator>
1590*e4b17023SJohn Marino     inline _OutputIterator
1591*e4b17023SJohn Marino     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
1592*e4b17023SJohn Marino                __gnu_parallel::sequential_tag)
1593*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); }
1594*e4b17023SJohn Marino 
1595*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
1596*e4b17023SJohn Marino   template<typename _OutputIterator, typename _Size, typename _Generator,
1597*e4b17023SJohn Marino            typename _IteratorTag>
1598*e4b17023SJohn Marino     inline _OutputIterator
1599*e4b17023SJohn Marino     __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen,
1600*e4b17023SJohn Marino                         _IteratorTag)
1601*e4b17023SJohn Marino     { return generate_n(__begin, __n, __gen,
1602*e4b17023SJohn Marino                         __gnu_parallel::sequential_tag()); }
1603*e4b17023SJohn Marino 
1604*e4b17023SJohn Marino   // Parallel algorithm for random access iterators.
1605*e4b17023SJohn Marino   template<typename _RAIter, typename _Size, typename _Generator>
1606*e4b17023SJohn Marino     inline _RAIter
1607*e4b17023SJohn Marino     __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen,
1608*e4b17023SJohn Marino                       random_access_iterator_tag,
1609*e4b17023SJohn Marino                       __gnu_parallel::_Parallelism __parallelism_tag
1610*e4b17023SJohn Marino                       = __gnu_parallel::parallel_balanced)
1611*e4b17023SJohn Marino     {
1612*e4b17023SJohn Marino       // XXX parallel version is where?
1613*e4b17023SJohn Marino       return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
1614*e4b17023SJohn Marino     }
1615*e4b17023SJohn Marino 
1616*e4b17023SJohn Marino   // Public interface.
1617*e4b17023SJohn Marino   template<typename _OutputIterator, typename _Size, typename _Generator>
1618*e4b17023SJohn Marino     inline _OutputIterator
1619*e4b17023SJohn Marino     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
1620*e4b17023SJohn Marino                __gnu_parallel::_Parallelism __parallelism_tag)
1621*e4b17023SJohn Marino     {
1622*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
1623*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1624*e4b17023SJohn Marino       return __generate_n_switch(__begin, __n, __gen, _IteratorCategory(),
1625*e4b17023SJohn Marino                                __parallelism_tag);
1626*e4b17023SJohn Marino     }
1627*e4b17023SJohn Marino 
1628*e4b17023SJohn Marino   template<typename _OutputIterator, typename _Size, typename _Generator>
1629*e4b17023SJohn Marino     inline _OutputIterator
1630*e4b17023SJohn Marino     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen)
1631*e4b17023SJohn Marino     {
1632*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
1633*e4b17023SJohn Marino       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1634*e4b17023SJohn Marino       return __generate_n_switch(__begin, __n, __gen, _IteratorCategory());
1635*e4b17023SJohn Marino     }
1636*e4b17023SJohn Marino 
1637*e4b17023SJohn Marino 
1638*e4b17023SJohn Marino   // Sequential fallback.
1639*e4b17023SJohn Marino   template<typename _RAIter>
1640*e4b17023SJohn Marino     inline void
1641*e4b17023SJohn Marino     random_shuffle(_RAIter __begin, _RAIter __end,
1642*e4b17023SJohn Marino                    __gnu_parallel::sequential_tag)
1643*e4b17023SJohn Marino     { _GLIBCXX_STD_A::random_shuffle(__begin, __end); }
1644*e4b17023SJohn Marino 
1645*e4b17023SJohn Marino   // Sequential fallback.
1646*e4b17023SJohn Marino   template<typename _RAIter, typename _RandomNumberGenerator>
1647*e4b17023SJohn Marino     inline void
1648*e4b17023SJohn Marino     random_shuffle(_RAIter __begin, _RAIter __end,
1649*e4b17023SJohn Marino                    _RandomNumberGenerator& __rand,
1650*e4b17023SJohn Marino                    __gnu_parallel::sequential_tag)
1651*e4b17023SJohn Marino     { _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); }
1652*e4b17023SJohn Marino 
1653*e4b17023SJohn Marino 
1654*e4b17023SJohn Marino   /** @brief Functor wrapper for std::rand(). */
1655*e4b17023SJohn Marino   template<typename _MustBeInt = int>
1656*e4b17023SJohn Marino     struct _CRandNumber
1657*e4b17023SJohn Marino     {
1658*e4b17023SJohn Marino       int
1659*e4b17023SJohn Marino       operator()(int __limit)
1660*e4b17023SJohn Marino       { return rand() % __limit; }
1661*e4b17023SJohn Marino     };
1662*e4b17023SJohn Marino 
1663*e4b17023SJohn Marino   // Fill in random number generator.
1664*e4b17023SJohn Marino   template<typename _RAIter>
1665*e4b17023SJohn Marino     inline void
1666*e4b17023SJohn Marino     random_shuffle(_RAIter __begin, _RAIter __end)
1667*e4b17023SJohn Marino     {
1668*e4b17023SJohn Marino       _CRandNumber<> __r;
1669*e4b17023SJohn Marino       // Parallelization still possible.
1670*e4b17023SJohn Marino       __gnu_parallel::random_shuffle(__begin, __end, __r);
1671*e4b17023SJohn Marino     }
1672*e4b17023SJohn Marino 
1673*e4b17023SJohn Marino   // Parallel algorithm for random access iterators.
1674*e4b17023SJohn Marino   template<typename _RAIter, typename _RandomNumberGenerator>
1675*e4b17023SJohn Marino     void
1676*e4b17023SJohn Marino     random_shuffle(_RAIter __begin, _RAIter __end,
1677*e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__
1678*e4b17023SJohn Marino                    _RandomNumberGenerator&& __rand)
1679*e4b17023SJohn Marino #else
1680*e4b17023SJohn Marino                    _RandomNumberGenerator& __rand)
1681*e4b17023SJohn Marino #endif
1682*e4b17023SJohn Marino     {
1683*e4b17023SJohn Marino       if (__begin == __end)
1684*e4b17023SJohn Marino         return;
1685*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1686*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1687*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
1688*e4b17023SJohn Marino         __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
1689*e4b17023SJohn Marino       else
1690*e4b17023SJohn Marino         __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
1691*e4b17023SJohn Marino     }
1692*e4b17023SJohn Marino 
1693*e4b17023SJohn Marino   // Sequential fallback.
1694*e4b17023SJohn Marino   template<typename _FIterator, typename _Predicate>
1695*e4b17023SJohn Marino     inline _FIterator
1696*e4b17023SJohn Marino     partition(_FIterator __begin, _FIterator __end,
1697*e4b17023SJohn Marino               _Predicate __pred, __gnu_parallel::sequential_tag)
1698*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::partition(__begin, __end, __pred); }
1699*e4b17023SJohn Marino 
1700*e4b17023SJohn Marino   // Sequential fallback for input iterator case.
1701*e4b17023SJohn Marino   template<typename _FIterator, typename _Predicate, typename _IteratorTag>
1702*e4b17023SJohn Marino     inline _FIterator
1703*e4b17023SJohn Marino     __partition_switch(_FIterator __begin, _FIterator __end,
1704*e4b17023SJohn Marino                      _Predicate __pred, _IteratorTag)
1705*e4b17023SJohn Marino     { return partition(__begin, __end, __pred,
1706*e4b17023SJohn Marino                        __gnu_parallel::sequential_tag()); }
1707*e4b17023SJohn Marino 
1708*e4b17023SJohn Marino   // Parallel algorithm for random access iterators.
1709*e4b17023SJohn Marino   template<typename _RAIter, typename _Predicate>
1710*e4b17023SJohn Marino     _RAIter
1711*e4b17023SJohn Marino     __partition_switch(_RAIter __begin, _RAIter __end,
1712*e4b17023SJohn Marino                      _Predicate __pred, random_access_iterator_tag)
1713*e4b17023SJohn Marino     {
1714*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
1715*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1716*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().partition_minimal_n))
1717*e4b17023SJohn Marino         {
1718*e4b17023SJohn Marino           typedef typename std::iterator_traits<_RAIter>::
1719*e4b17023SJohn Marino             difference_type _DifferenceType;
1720*e4b17023SJohn Marino           _DifferenceType __middle = __gnu_parallel::
1721*e4b17023SJohn Marino             __parallel_partition(__begin, __end, __pred,
1722*e4b17023SJohn Marino                                __gnu_parallel::__get_max_threads());
1723*e4b17023SJohn Marino           return __begin + __middle;
1724*e4b17023SJohn Marino         }
1725*e4b17023SJohn Marino       else
1726*e4b17023SJohn Marino         return partition(__begin, __end, __pred,
1727*e4b17023SJohn Marino                          __gnu_parallel::sequential_tag());
1728*e4b17023SJohn Marino     }
1729*e4b17023SJohn Marino 
1730*e4b17023SJohn Marino   // Public interface.
1731*e4b17023SJohn Marino   template<typename _FIterator, typename _Predicate>
1732*e4b17023SJohn Marino     inline _FIterator
1733*e4b17023SJohn Marino     partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
1734*e4b17023SJohn Marino     {
1735*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
1736*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
1737*e4b17023SJohn Marino       return __partition_switch(__begin, __end, __pred, _IteratorCategory());
1738*e4b17023SJohn Marino     }
1739*e4b17023SJohn Marino 
1740*e4b17023SJohn Marino   // sort interface
1741*e4b17023SJohn Marino 
1742*e4b17023SJohn Marino   // Sequential fallback
1743*e4b17023SJohn Marino   template<typename _RAIter>
1744*e4b17023SJohn Marino     inline void
1745*e4b17023SJohn Marino     sort(_RAIter __begin, _RAIter __end,
1746*e4b17023SJohn Marino          __gnu_parallel::sequential_tag)
1747*e4b17023SJohn Marino     { _GLIBCXX_STD_A::sort(__begin, __end); }
1748*e4b17023SJohn Marino 
1749*e4b17023SJohn Marino   // Sequential fallback
1750*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
1751*e4b17023SJohn Marino     inline void
1752*e4b17023SJohn Marino     sort(_RAIter __begin, _RAIter __end, _Compare __comp,
1753*e4b17023SJohn Marino          __gnu_parallel::sequential_tag)
1754*e4b17023SJohn Marino     { _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end,
1755*e4b17023SJohn Marino                                                              __comp); }
1756*e4b17023SJohn Marino 
1757*e4b17023SJohn Marino   // Public interface
1758*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare,
1759*e4b17023SJohn Marino            typename _Parallelism>
1760*e4b17023SJohn Marino   void
1761*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end, _Compare __comp,
1762*e4b17023SJohn Marino        _Parallelism __parallelism)
1763*e4b17023SJohn Marino   {
1764*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1765*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1766*e4b17023SJohn Marino 
1767*e4b17023SJohn Marino     if (__begin != __end)
1768*e4b17023SJohn Marino       {
1769*e4b17023SJohn Marino         if (_GLIBCXX_PARALLEL_CONDITION(
1770*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
1771*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().sort_minimal_n))
1772*e4b17023SJohn Marino           __gnu_parallel::__parallel_sort<false>(
1773*e4b17023SJohn Marino                             __begin, __end, __comp, __parallelism);
1774*e4b17023SJohn Marino         else
1775*e4b17023SJohn Marino           sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
1776*e4b17023SJohn Marino       }
1777*e4b17023SJohn Marino   }
1778*e4b17023SJohn Marino 
1779*e4b17023SJohn Marino   // Public interface, insert default comparator
1780*e4b17023SJohn Marino   template<typename _RAIter>
1781*e4b17023SJohn Marino     inline void
1782*e4b17023SJohn Marino     sort(_RAIter __begin, _RAIter __end)
1783*e4b17023SJohn Marino     {
1784*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
1785*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
1786*e4b17023SJohn Marino       sort(__begin, __end, std::less<_ValueType>(),
1787*e4b17023SJohn Marino            __gnu_parallel::default_parallel_tag());
1788*e4b17023SJohn Marino     }
1789*e4b17023SJohn Marino 
1790*e4b17023SJohn Marino   // Public interface, insert default comparator
1791*e4b17023SJohn Marino   template<typename _RAIter>
1792*e4b17023SJohn Marino   inline void
1793*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end,
1794*e4b17023SJohn Marino        __gnu_parallel::default_parallel_tag __parallelism)
1795*e4b17023SJohn Marino   {
1796*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1797*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1798*e4b17023SJohn Marino     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1799*e4b17023SJohn Marino   }
1800*e4b17023SJohn Marino 
1801*e4b17023SJohn Marino   // Public interface, insert default comparator
1802*e4b17023SJohn Marino   template<typename _RAIter>
1803*e4b17023SJohn Marino   inline void
1804*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end,
1805*e4b17023SJohn Marino        __gnu_parallel::parallel_tag __parallelism)
1806*e4b17023SJohn Marino   {
1807*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1808*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1809*e4b17023SJohn Marino     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1810*e4b17023SJohn Marino   }
1811*e4b17023SJohn Marino 
1812*e4b17023SJohn Marino   // Public interface, insert default comparator
1813*e4b17023SJohn Marino   template<typename _RAIter>
1814*e4b17023SJohn Marino   inline void
1815*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end,
1816*e4b17023SJohn Marino        __gnu_parallel::multiway_mergesort_tag __parallelism)
1817*e4b17023SJohn Marino   {
1818*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1819*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1820*e4b17023SJohn Marino     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1821*e4b17023SJohn Marino   }
1822*e4b17023SJohn Marino 
1823*e4b17023SJohn Marino   // Public interface, insert default comparator
1824*e4b17023SJohn Marino   template<typename _RAIter>
1825*e4b17023SJohn Marino   inline void
1826*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end,
1827*e4b17023SJohn Marino        __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
1828*e4b17023SJohn Marino   {
1829*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1830*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1831*e4b17023SJohn Marino     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1832*e4b17023SJohn Marino   }
1833*e4b17023SJohn Marino 
1834*e4b17023SJohn Marino   // Public interface, insert default comparator
1835*e4b17023SJohn Marino   template<typename _RAIter>
1836*e4b17023SJohn Marino   inline void
1837*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end,
1838*e4b17023SJohn Marino        __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
1839*e4b17023SJohn Marino   {
1840*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1841*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1842*e4b17023SJohn Marino     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1843*e4b17023SJohn Marino   }
1844*e4b17023SJohn Marino 
1845*e4b17023SJohn Marino   // Public interface, insert default comparator
1846*e4b17023SJohn Marino   template<typename _RAIter>
1847*e4b17023SJohn Marino   inline void
1848*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end,
1849*e4b17023SJohn Marino        __gnu_parallel::quicksort_tag __parallelism)
1850*e4b17023SJohn Marino   {
1851*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1852*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1853*e4b17023SJohn Marino     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1854*e4b17023SJohn Marino   }
1855*e4b17023SJohn Marino 
1856*e4b17023SJohn Marino   // Public interface, insert default comparator
1857*e4b17023SJohn Marino   template<typename _RAIter>
1858*e4b17023SJohn Marino   inline void
1859*e4b17023SJohn Marino   sort(_RAIter __begin, _RAIter __end,
1860*e4b17023SJohn Marino        __gnu_parallel::balanced_quicksort_tag __parallelism)
1861*e4b17023SJohn Marino   {
1862*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1863*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1864*e4b17023SJohn Marino     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1865*e4b17023SJohn Marino   }
1866*e4b17023SJohn Marino 
1867*e4b17023SJohn Marino   // Public interface
1868*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
1869*e4b17023SJohn Marino     void
1870*e4b17023SJohn Marino     sort(_RAIter __begin, _RAIter __end, _Compare __comp)
1871*e4b17023SJohn Marino     {
1872*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
1873*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
1874*e4b17023SJohn Marino     sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
1875*e4b17023SJohn Marino   }
1876*e4b17023SJohn Marino 
1877*e4b17023SJohn Marino 
1878*e4b17023SJohn Marino   // stable_sort interface
1879*e4b17023SJohn Marino 
1880*e4b17023SJohn Marino 
1881*e4b17023SJohn Marino   // Sequential fallback
1882*e4b17023SJohn Marino   template<typename _RAIter>
1883*e4b17023SJohn Marino   inline void
1884*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1885*e4b17023SJohn Marino        __gnu_parallel::sequential_tag)
1886*e4b17023SJohn Marino   { _GLIBCXX_STD_A::stable_sort(__begin, __end); }
1887*e4b17023SJohn Marino 
1888*e4b17023SJohn Marino   // Sequential fallback
1889*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
1890*e4b17023SJohn Marino   inline void
1891*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1892*e4b17023SJohn Marino               _Compare __comp, __gnu_parallel::sequential_tag)
1893*e4b17023SJohn Marino   { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(
1894*e4b17023SJohn Marino       __begin, __end, __comp); }
1895*e4b17023SJohn Marino 
1896*e4b17023SJohn Marino   // Public interface
1897*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare,
1898*e4b17023SJohn Marino            typename _Parallelism>
1899*e4b17023SJohn Marino   void
1900*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1901*e4b17023SJohn Marino               _Compare __comp, _Parallelism __parallelism)
1902*e4b17023SJohn Marino   {
1903*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1904*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1905*e4b17023SJohn Marino 
1906*e4b17023SJohn Marino     if (__begin != __end)
1907*e4b17023SJohn Marino       {
1908*e4b17023SJohn Marino         if (_GLIBCXX_PARALLEL_CONDITION(
1909*e4b17023SJohn Marino               static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
1910*e4b17023SJohn Marino               __gnu_parallel::_Settings::get().sort_minimal_n))
1911*e4b17023SJohn Marino           __gnu_parallel::__parallel_sort<true>(
1912*e4b17023SJohn Marino                             __begin, __end, __comp, __parallelism);
1913*e4b17023SJohn Marino         else
1914*e4b17023SJohn Marino           stable_sort(__begin, __end, __comp,
1915*e4b17023SJohn Marino                       __gnu_parallel::sequential_tag());
1916*e4b17023SJohn Marino       }
1917*e4b17023SJohn Marino   }
1918*e4b17023SJohn Marino 
1919*e4b17023SJohn Marino   // Public interface, insert default comparator
1920*e4b17023SJohn Marino   template<typename _RAIter>
1921*e4b17023SJohn Marino   inline void
1922*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end)
1923*e4b17023SJohn Marino   {
1924*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1925*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1926*e4b17023SJohn Marino     stable_sort(__begin, __end, std::less<_ValueType>(),
1927*e4b17023SJohn Marino                 __gnu_parallel::default_parallel_tag());
1928*e4b17023SJohn Marino   }
1929*e4b17023SJohn Marino 
1930*e4b17023SJohn Marino   // Public interface, insert default comparator
1931*e4b17023SJohn Marino   template<typename _RAIter>
1932*e4b17023SJohn Marino   inline void
1933*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1934*e4b17023SJohn Marino               __gnu_parallel::default_parallel_tag __parallelism)
1935*e4b17023SJohn Marino   {
1936*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1937*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1938*e4b17023SJohn Marino     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1939*e4b17023SJohn Marino   }
1940*e4b17023SJohn Marino 
1941*e4b17023SJohn Marino   // Public interface, insert default comparator
1942*e4b17023SJohn Marino   template<typename _RAIter>
1943*e4b17023SJohn Marino   inline void
1944*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1945*e4b17023SJohn Marino               __gnu_parallel::parallel_tag __parallelism)
1946*e4b17023SJohn Marino   {
1947*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1948*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1949*e4b17023SJohn Marino     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1950*e4b17023SJohn Marino   }
1951*e4b17023SJohn Marino 
1952*e4b17023SJohn Marino   // Public interface, insert default comparator
1953*e4b17023SJohn Marino   template<typename _RAIter>
1954*e4b17023SJohn Marino   inline void
1955*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1956*e4b17023SJohn Marino               __gnu_parallel::multiway_mergesort_tag __parallelism)
1957*e4b17023SJohn Marino   {
1958*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1959*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1960*e4b17023SJohn Marino     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1961*e4b17023SJohn Marino   }
1962*e4b17023SJohn Marino 
1963*e4b17023SJohn Marino   // Public interface, insert default comparator
1964*e4b17023SJohn Marino   template<typename _RAIter>
1965*e4b17023SJohn Marino   inline void
1966*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1967*e4b17023SJohn Marino               __gnu_parallel::quicksort_tag __parallelism)
1968*e4b17023SJohn Marino   {
1969*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1970*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1971*e4b17023SJohn Marino     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1972*e4b17023SJohn Marino   }
1973*e4b17023SJohn Marino 
1974*e4b17023SJohn Marino   // Public interface, insert default comparator
1975*e4b17023SJohn Marino   template<typename _RAIter>
1976*e4b17023SJohn Marino   inline void
1977*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1978*e4b17023SJohn Marino               __gnu_parallel::balanced_quicksort_tag __parallelism)
1979*e4b17023SJohn Marino   {
1980*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1981*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1982*e4b17023SJohn Marino     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1983*e4b17023SJohn Marino   }
1984*e4b17023SJohn Marino 
1985*e4b17023SJohn Marino   // Public interface
1986*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
1987*e4b17023SJohn Marino   void
1988*e4b17023SJohn Marino   stable_sort(_RAIter __begin, _RAIter __end,
1989*e4b17023SJohn Marino               _Compare __comp)
1990*e4b17023SJohn Marino   {
1991*e4b17023SJohn Marino     typedef iterator_traits<_RAIter> _TraitsType;
1992*e4b17023SJohn Marino     typedef typename _TraitsType::value_type _ValueType;
1993*e4b17023SJohn Marino     stable_sort(
1994*e4b17023SJohn Marino       __begin, __end, __comp, __gnu_parallel::default_parallel_tag());
1995*e4b17023SJohn Marino   }
1996*e4b17023SJohn Marino 
1997*e4b17023SJohn Marino   // Sequential fallback
1998*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
1999*e4b17023SJohn Marino            typename _OutputIterator>
2000*e4b17023SJohn Marino     inline _OutputIterator
2001*e4b17023SJohn Marino     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
2002*e4b17023SJohn Marino           _IIter2 __end2, _OutputIterator __result,
2003*e4b17023SJohn Marino           __gnu_parallel::sequential_tag)
2004*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::merge(
2005*e4b17023SJohn Marino                __begin1, __end1, __begin2, __end2, __result); }
2006*e4b17023SJohn Marino 
2007*e4b17023SJohn Marino   // Sequential fallback
2008*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
2009*e4b17023SJohn Marino            typename _OutputIterator, typename _Compare>
2010*e4b17023SJohn Marino     inline _OutputIterator
2011*e4b17023SJohn Marino     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
2012*e4b17023SJohn Marino           _IIter2 __end2, _OutputIterator __result, _Compare __comp,
2013*e4b17023SJohn Marino           __gnu_parallel::sequential_tag)
2014*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::merge(
2015*e4b17023SJohn Marino                 __begin1, __end1, __begin2, __end2, __result, __comp); }
2016*e4b17023SJohn Marino 
2017*e4b17023SJohn Marino   // Sequential fallback for input iterator case
2018*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2, typename _OutputIterator,
2019*e4b17023SJohn Marino            typename _Compare, typename _IteratorTag1,
2020*e4b17023SJohn Marino            typename _IteratorTag2, typename _IteratorTag3>
2021*e4b17023SJohn Marino     inline _OutputIterator
2022*e4b17023SJohn Marino     __merge_switch(_IIter1 __begin1, _IIter1 __end1,
2023*e4b17023SJohn Marino                  _IIter2 __begin2, _IIter2 __end2,
2024*e4b17023SJohn Marino                  _OutputIterator __result, _Compare __comp,
2025*e4b17023SJohn Marino                  _IteratorTag1, _IteratorTag2, _IteratorTag3)
2026*e4b17023SJohn Marino      { return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2,
2027*e4b17023SJohn Marino                                     __result, __comp); }
2028*e4b17023SJohn Marino 
2029*e4b17023SJohn Marino   // Parallel algorithm for random access iterators
2030*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
2031*e4b17023SJohn Marino            typename _OutputIterator, typename _Compare>
2032*e4b17023SJohn Marino     _OutputIterator
2033*e4b17023SJohn Marino     __merge_switch(_IIter1 __begin1, _IIter1 __end1,
2034*e4b17023SJohn Marino                  _IIter2 __begin2, _IIter2 __end2,
2035*e4b17023SJohn Marino                  _OutputIterator __result, _Compare __comp,
2036*e4b17023SJohn Marino                  random_access_iterator_tag, random_access_iterator_tag,
2037*e4b17023SJohn Marino                  random_access_iterator_tag)
2038*e4b17023SJohn Marino     {
2039*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
2040*e4b17023SJohn Marino             (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
2041*e4b17023SJohn Marino              >= __gnu_parallel::_Settings::get().merge_minimal_n
2042*e4b17023SJohn Marino              || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
2043*e4b17023SJohn Marino              >= __gnu_parallel::_Settings::get().merge_minimal_n)))
2044*e4b17023SJohn Marino         return __gnu_parallel::__parallel_merge_advance(
2045*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result,
2046*e4b17023SJohn Marino                  (__end1 - __begin1) + (__end2 - __begin2), __comp);
2047*e4b17023SJohn Marino       else
2048*e4b17023SJohn Marino         return __gnu_parallel::__merge_advance(
2049*e4b17023SJohn Marino                  __begin1, __end1, __begin2, __end2, __result,
2050*e4b17023SJohn Marino                  (__end1 - __begin1) + (__end2 - __begin2), __comp);
2051*e4b17023SJohn Marino   }
2052*e4b17023SJohn Marino 
2053*e4b17023SJohn Marino   // Public interface
2054*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
2055*e4b17023SJohn Marino            typename _OutputIterator, typename _Compare>
2056*e4b17023SJohn Marino     inline _OutputIterator
2057*e4b17023SJohn Marino     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
2058*e4b17023SJohn Marino           _IIter2 __end2, _OutputIterator __result, _Compare __comp)
2059*e4b17023SJohn Marino     {
2060*e4b17023SJohn Marino       typedef typename iterator_traits<_IIter1>::value_type _ValueType;
2061*e4b17023SJohn Marino 
2062*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _IIterTraits1;
2063*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _IIterTraits2;
2064*e4b17023SJohn Marino       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
2065*e4b17023SJohn Marino       typedef typename _IIterTraits1::iterator_category
2066*e4b17023SJohn Marino         _IIterCategory1;
2067*e4b17023SJohn Marino       typedef typename _IIterTraits2::iterator_category
2068*e4b17023SJohn Marino         _IIterCategory2;
2069*e4b17023SJohn Marino       typedef typename _OIterTraits::iterator_category _OIterCategory;
2070*e4b17023SJohn Marino 
2071*e4b17023SJohn Marino       return __merge_switch(
2072*e4b17023SJohn Marino               __begin1, __end1, __begin2, __end2, __result, __comp,
2073*e4b17023SJohn Marino               _IIterCategory1(), _IIterCategory2(), _OIterCategory());
2074*e4b17023SJohn Marino   }
2075*e4b17023SJohn Marino 
2076*e4b17023SJohn Marino 
2077*e4b17023SJohn Marino   // Public interface, insert default comparator
2078*e4b17023SJohn Marino   template<typename _IIter1, typename _IIter2,
2079*e4b17023SJohn Marino            typename _OutputIterator>
2080*e4b17023SJohn Marino     inline _OutputIterator
2081*e4b17023SJohn Marino     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
2082*e4b17023SJohn Marino           _IIter2 __end2, _OutputIterator __result)
2083*e4b17023SJohn Marino     {
2084*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter1> _Iterator1Traits;
2085*e4b17023SJohn Marino       typedef std::iterator_traits<_IIter2> _Iterator2Traits;
2086*e4b17023SJohn Marino       typedef typename _Iterator1Traits::value_type _ValueType1;
2087*e4b17023SJohn Marino       typedef typename _Iterator2Traits::value_type _ValueType2;
2088*e4b17023SJohn Marino 
2089*e4b17023SJohn Marino       return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2,
2090*e4b17023SJohn Marino                   __result, __gnu_parallel::_Less<_ValueType1, _ValueType2>());
2091*e4b17023SJohn Marino     }
2092*e4b17023SJohn Marino 
2093*e4b17023SJohn Marino   // Sequential fallback
2094*e4b17023SJohn Marino   template<typename _RAIter>
2095*e4b17023SJohn Marino     inline void
2096*e4b17023SJohn Marino     nth_element(_RAIter __begin, _RAIter __nth,
2097*e4b17023SJohn Marino                 _RAIter __end, __gnu_parallel::sequential_tag)
2098*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); }
2099*e4b17023SJohn Marino 
2100*e4b17023SJohn Marino   // Sequential fallback
2101*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
2102*e4b17023SJohn Marino     inline void
2103*e4b17023SJohn Marino     nth_element(_RAIter __begin, _RAIter __nth,
2104*e4b17023SJohn Marino                 _RAIter __end, _Compare __comp,
2105*e4b17023SJohn Marino               __gnu_parallel::sequential_tag)
2106*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); }
2107*e4b17023SJohn Marino 
2108*e4b17023SJohn Marino   // Public interface
2109*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
2110*e4b17023SJohn Marino     inline void
2111*e4b17023SJohn Marino     nth_element(_RAIter __begin, _RAIter __nth,
2112*e4b17023SJohn Marino                 _RAIter __end, _Compare __comp)
2113*e4b17023SJohn Marino     {
2114*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
2115*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2116*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
2117*e4b17023SJohn Marino         __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
2118*e4b17023SJohn Marino       else
2119*e4b17023SJohn Marino         nth_element(__begin, __nth, __end, __comp,
2120*e4b17023SJohn Marino                     __gnu_parallel::sequential_tag());
2121*e4b17023SJohn Marino     }
2122*e4b17023SJohn Marino 
2123*e4b17023SJohn Marino   // Public interface, insert default comparator
2124*e4b17023SJohn Marino   template<typename _RAIter>
2125*e4b17023SJohn Marino     inline void
2126*e4b17023SJohn Marino     nth_element(_RAIter __begin, _RAIter __nth,
2127*e4b17023SJohn Marino                 _RAIter __end)
2128*e4b17023SJohn Marino     {
2129*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
2130*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
2131*e4b17023SJohn Marino       __gnu_parallel::nth_element(__begin, __nth, __end,
2132*e4b17023SJohn Marino                                   std::less<_ValueType>());
2133*e4b17023SJohn Marino     }
2134*e4b17023SJohn Marino 
2135*e4b17023SJohn Marino   // Sequential fallback
2136*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
2137*e4b17023SJohn Marino     inline void
2138*e4b17023SJohn Marino     partial_sort(_RAIter __begin, _RAIter __middle,
2139*e4b17023SJohn Marino                  _RAIter __end, _Compare __comp,
2140*e4b17023SJohn Marino                  __gnu_parallel::sequential_tag)
2141*e4b17023SJohn Marino     { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); }
2142*e4b17023SJohn Marino 
2143*e4b17023SJohn Marino   // Sequential fallback
2144*e4b17023SJohn Marino   template<typename _RAIter>
2145*e4b17023SJohn Marino     inline void
2146*e4b17023SJohn Marino     partial_sort(_RAIter __begin, _RAIter __middle,
2147*e4b17023SJohn Marino                  _RAIter __end, __gnu_parallel::sequential_tag)
2148*e4b17023SJohn Marino     { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); }
2149*e4b17023SJohn Marino 
2150*e4b17023SJohn Marino   // Public interface, parallel algorithm for random access iterators
2151*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
2152*e4b17023SJohn Marino     void
2153*e4b17023SJohn Marino     partial_sort(_RAIter __begin, _RAIter __middle,
2154*e4b17023SJohn Marino                  _RAIter __end, _Compare __comp)
2155*e4b17023SJohn Marino     {
2156*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
2157*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2158*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
2159*e4b17023SJohn Marino         __gnu_parallel::
2160*e4b17023SJohn Marino           __parallel_partial_sort(__begin, __middle, __end, __comp);
2161*e4b17023SJohn Marino       else
2162*e4b17023SJohn Marino         partial_sort(__begin, __middle, __end, __comp,
2163*e4b17023SJohn Marino                      __gnu_parallel::sequential_tag());
2164*e4b17023SJohn Marino     }
2165*e4b17023SJohn Marino 
2166*e4b17023SJohn Marino   // Public interface, insert default comparator
2167*e4b17023SJohn Marino   template<typename _RAIter>
2168*e4b17023SJohn Marino     inline void
2169*e4b17023SJohn Marino     partial_sort(_RAIter __begin, _RAIter __middle,
2170*e4b17023SJohn Marino                  _RAIter __end)
2171*e4b17023SJohn Marino     {
2172*e4b17023SJohn Marino       typedef iterator_traits<_RAIter> _TraitsType;
2173*e4b17023SJohn Marino       typedef typename _TraitsType::value_type _ValueType;
2174*e4b17023SJohn Marino       __gnu_parallel::partial_sort(__begin, __middle, __end,
2175*e4b17023SJohn Marino                                    std::less<_ValueType>());
2176*e4b17023SJohn Marino     }
2177*e4b17023SJohn Marino 
2178*e4b17023SJohn Marino   // Sequential fallback
2179*e4b17023SJohn Marino   template<typename _FIterator>
2180*e4b17023SJohn Marino     inline _FIterator
2181*e4b17023SJohn Marino     max_element(_FIterator __begin, _FIterator __end,
2182*e4b17023SJohn Marino                 __gnu_parallel::sequential_tag)
2183*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::max_element(__begin, __end); }
2184*e4b17023SJohn Marino 
2185*e4b17023SJohn Marino   // Sequential fallback
2186*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare>
2187*e4b17023SJohn Marino     inline _FIterator
2188*e4b17023SJohn Marino     max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2189*e4b17023SJohn Marino                 __gnu_parallel::sequential_tag)
2190*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); }
2191*e4b17023SJohn Marino 
2192*e4b17023SJohn Marino   // Sequential fallback for input iterator case
2193*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare, typename _IteratorTag>
2194*e4b17023SJohn Marino     inline _FIterator
2195*e4b17023SJohn Marino     __max_element_switch(_FIterator __begin, _FIterator __end,
2196*e4b17023SJohn Marino                        _Compare __comp, _IteratorTag)
2197*e4b17023SJohn Marino     { return max_element(__begin, __end, __comp,
2198*e4b17023SJohn Marino                          __gnu_parallel::sequential_tag()); }
2199*e4b17023SJohn Marino 
2200*e4b17023SJohn Marino   // Parallel algorithm for random access iterators
2201*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
2202*e4b17023SJohn Marino     _RAIter
2203*e4b17023SJohn Marino     __max_element_switch(_RAIter __begin, _RAIter __end,
2204*e4b17023SJohn Marino                        _Compare __comp, random_access_iterator_tag,
2205*e4b17023SJohn Marino                        __gnu_parallel::_Parallelism __parallelism_tag
2206*e4b17023SJohn Marino                        = __gnu_parallel::parallel_balanced)
2207*e4b17023SJohn Marino     {
2208*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
2209*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2210*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().max_element_minimal_n
2211*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
2212*e4b17023SJohn Marino         {
2213*e4b17023SJohn Marino           _RAIter __res(__begin);
2214*e4b17023SJohn Marino           __gnu_parallel::__identity_selector<_RAIter>
2215*e4b17023SJohn Marino             __functionality;
2216*e4b17023SJohn Marino           __gnu_parallel::
2217*e4b17023SJohn Marino             __for_each_template_random_access(
2218*e4b17023SJohn Marino               __begin, __end, __gnu_parallel::_Nothing(), __functionality,
2219*e4b17023SJohn Marino               __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
2220*e4b17023SJohn Marino               __res, __res, -1, __parallelism_tag);
2221*e4b17023SJohn Marino           return __res;
2222*e4b17023SJohn Marino         }
2223*e4b17023SJohn Marino       else
2224*e4b17023SJohn Marino         return max_element(__begin, __end, __comp,
2225*e4b17023SJohn Marino                            __gnu_parallel::sequential_tag());
2226*e4b17023SJohn Marino     }
2227*e4b17023SJohn Marino 
2228*e4b17023SJohn Marino   // Public interface, insert default comparator
2229*e4b17023SJohn Marino   template<typename _FIterator>
2230*e4b17023SJohn Marino     inline _FIterator
2231*e4b17023SJohn Marino     max_element(_FIterator __begin, _FIterator __end,
2232*e4b17023SJohn Marino                 __gnu_parallel::_Parallelism __parallelism_tag)
2233*e4b17023SJohn Marino     {
2234*e4b17023SJohn Marino       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2235*e4b17023SJohn Marino       return max_element(__begin, __end, std::less<_ValueType>(),
2236*e4b17023SJohn Marino                          __parallelism_tag);
2237*e4b17023SJohn Marino     }
2238*e4b17023SJohn Marino 
2239*e4b17023SJohn Marino   template<typename _FIterator>
2240*e4b17023SJohn Marino     inline _FIterator
2241*e4b17023SJohn Marino     max_element(_FIterator __begin, _FIterator __end)
2242*e4b17023SJohn Marino     {
2243*e4b17023SJohn Marino       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2244*e4b17023SJohn Marino       return __gnu_parallel::max_element(__begin, __end,
2245*e4b17023SJohn Marino                                          std::less<_ValueType>());
2246*e4b17023SJohn Marino     }
2247*e4b17023SJohn Marino 
2248*e4b17023SJohn Marino   // Public interface
2249*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare>
2250*e4b17023SJohn Marino     inline _FIterator
2251*e4b17023SJohn Marino     max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2252*e4b17023SJohn Marino                 __gnu_parallel::_Parallelism __parallelism_tag)
2253*e4b17023SJohn Marino     {
2254*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
2255*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
2256*e4b17023SJohn Marino       return __max_element_switch(__begin, __end, __comp, _IteratorCategory(),
2257*e4b17023SJohn Marino                                   __parallelism_tag);
2258*e4b17023SJohn Marino     }
2259*e4b17023SJohn Marino 
2260*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare>
2261*e4b17023SJohn Marino     inline _FIterator
2262*e4b17023SJohn Marino     max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
2263*e4b17023SJohn Marino     {
2264*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
2265*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
2266*e4b17023SJohn Marino       return __max_element_switch(__begin, __end, __comp, _IteratorCategory());
2267*e4b17023SJohn Marino     }
2268*e4b17023SJohn Marino 
2269*e4b17023SJohn Marino 
2270*e4b17023SJohn Marino   // Sequential fallback
2271*e4b17023SJohn Marino   template<typename _FIterator>
2272*e4b17023SJohn Marino     inline _FIterator
2273*e4b17023SJohn Marino     min_element(_FIterator __begin, _FIterator __end,
2274*e4b17023SJohn Marino                 __gnu_parallel::sequential_tag)
2275*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::min_element(__begin, __end); }
2276*e4b17023SJohn Marino 
2277*e4b17023SJohn Marino   // Sequential fallback
2278*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare>
2279*e4b17023SJohn Marino     inline _FIterator
2280*e4b17023SJohn Marino     min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2281*e4b17023SJohn Marino                 __gnu_parallel::sequential_tag)
2282*e4b17023SJohn Marino     { return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); }
2283*e4b17023SJohn Marino 
2284*e4b17023SJohn Marino   // Sequential fallback for input iterator case
2285*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare, typename _IteratorTag>
2286*e4b17023SJohn Marino     inline _FIterator
2287*e4b17023SJohn Marino     __min_element_switch(_FIterator __begin, _FIterator __end,
2288*e4b17023SJohn Marino                        _Compare __comp, _IteratorTag)
2289*e4b17023SJohn Marino     { return min_element(__begin, __end, __comp,
2290*e4b17023SJohn Marino                          __gnu_parallel::sequential_tag()); }
2291*e4b17023SJohn Marino 
2292*e4b17023SJohn Marino   // Parallel algorithm for random access iterators
2293*e4b17023SJohn Marino   template<typename _RAIter, typename _Compare>
2294*e4b17023SJohn Marino     _RAIter
2295*e4b17023SJohn Marino     __min_element_switch(_RAIter __begin, _RAIter __end,
2296*e4b17023SJohn Marino                        _Compare __comp, random_access_iterator_tag,
2297*e4b17023SJohn Marino                        __gnu_parallel::_Parallelism __parallelism_tag
2298*e4b17023SJohn Marino                        = __gnu_parallel::parallel_balanced)
2299*e4b17023SJohn Marino     {
2300*e4b17023SJohn Marino       if (_GLIBCXX_PARALLEL_CONDITION(
2301*e4b17023SJohn Marino             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2302*e4b17023SJohn Marino             >= __gnu_parallel::_Settings::get().min_element_minimal_n
2303*e4b17023SJohn Marino             && __gnu_parallel::__is_parallel(__parallelism_tag)))
2304*e4b17023SJohn Marino         {
2305*e4b17023SJohn Marino           _RAIter __res(__begin);
2306*e4b17023SJohn Marino           __gnu_parallel::__identity_selector<_RAIter>
2307*e4b17023SJohn Marino             __functionality;
2308*e4b17023SJohn Marino           __gnu_parallel::
2309*e4b17023SJohn Marino             __for_each_template_random_access(
2310*e4b17023SJohn Marino               __begin, __end, __gnu_parallel::_Nothing(), __functionality,
2311*e4b17023SJohn Marino               __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
2312*e4b17023SJohn Marino               __res, __res, -1, __parallelism_tag);
2313*e4b17023SJohn Marino           return __res;
2314*e4b17023SJohn Marino         }
2315*e4b17023SJohn Marino       else
2316*e4b17023SJohn Marino         return min_element(__begin, __end, __comp,
2317*e4b17023SJohn Marino                            __gnu_parallel::sequential_tag());
2318*e4b17023SJohn Marino     }
2319*e4b17023SJohn Marino 
2320*e4b17023SJohn Marino   // Public interface, insert default comparator
2321*e4b17023SJohn Marino   template<typename _FIterator>
2322*e4b17023SJohn Marino     inline _FIterator
2323*e4b17023SJohn Marino     min_element(_FIterator __begin, _FIterator __end,
2324*e4b17023SJohn Marino                 __gnu_parallel::_Parallelism __parallelism_tag)
2325*e4b17023SJohn Marino     {
2326*e4b17023SJohn Marino       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2327*e4b17023SJohn Marino       return min_element(__begin, __end, std::less<_ValueType>(),
2328*e4b17023SJohn Marino                          __parallelism_tag);
2329*e4b17023SJohn Marino     }
2330*e4b17023SJohn Marino 
2331*e4b17023SJohn Marino   template<typename _FIterator>
2332*e4b17023SJohn Marino     inline _FIterator
2333*e4b17023SJohn Marino     min_element(_FIterator __begin, _FIterator __end)
2334*e4b17023SJohn Marino     {
2335*e4b17023SJohn Marino       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2336*e4b17023SJohn Marino       return __gnu_parallel::min_element(__begin, __end,
2337*e4b17023SJohn Marino                                          std::less<_ValueType>());
2338*e4b17023SJohn Marino     }
2339*e4b17023SJohn Marino 
2340*e4b17023SJohn Marino   // Public interface
2341*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare>
2342*e4b17023SJohn Marino     inline _FIterator
2343*e4b17023SJohn Marino     min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2344*e4b17023SJohn Marino                 __gnu_parallel::_Parallelism __parallelism_tag)
2345*e4b17023SJohn Marino     {
2346*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
2347*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
2348*e4b17023SJohn Marino       return __min_element_switch(__begin, __end, __comp, _IteratorCategory(),
2349*e4b17023SJohn Marino                                 __parallelism_tag);
2350*e4b17023SJohn Marino     }
2351*e4b17023SJohn Marino 
2352*e4b17023SJohn Marino   template<typename _FIterator, typename _Compare>
2353*e4b17023SJohn Marino     inline _FIterator
2354*e4b17023SJohn Marino     min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
2355*e4b17023SJohn Marino     {
2356*e4b17023SJohn Marino       typedef iterator_traits<_FIterator> _TraitsType;
2357*e4b17023SJohn Marino       typedef typename _TraitsType::iterator_category _IteratorCategory;
2358*e4b17023SJohn Marino       return __min_element_switch(__begin, __end, __comp, _IteratorCategory());
2359*e4b17023SJohn Marino     }
2360*e4b17023SJohn Marino } // end namespace
2361*e4b17023SJohn Marino } // end namespace
2362*e4b17023SJohn Marino 
2363*e4b17023SJohn Marino #endif /* _GLIBCXX_PARALLEL_ALGO_H */
2364