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