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