3 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
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
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.
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.
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/>.
25 /** @file parallel/algo.h
26 * @brief Parallel STL function calls corresponding to the stl_algo.h header.
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.
35 // Written by Johannes Singler and Felix Putze.
37 #ifndef _GLIBCXX_PARALLEL_ALGO_H
38 #define _GLIBCXX_PARALLEL_ALGO_H 1
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>
65 // Sequential fallback
66 template<typename _IIter, typename _Function>
68 for_each(_IIter __begin, _IIter __end, _Function __f,
69 __gnu_parallel::sequential_tag)
70 { return _GLIBCXX_STD_P::for_each(__begin, __end, __f); }
73 // Sequential fallback for input iterator case
74 template<typename _IIter, typename _Function, typename _IteratorTag>
76 __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
78 { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }
80 // Parallel algorithm for random access iterators
81 template<typename _RAIter, typename _Function>
83 __for_each_switch(_RAIter __begin, _RAIter __end,
84 _Function __f, random_access_iterator_tag,
85 __gnu_parallel::_Parallelism __parallelism_tag
86 = __gnu_parallel::parallel_balanced)
88 if (_GLIBCXX_PARALLEL_CONDITION(
89 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
90 >= __gnu_parallel::_Settings::get().for_each_minimal_n
91 && __gnu_parallel::__is_parallel(__parallelism_tag)))
94 __gnu_parallel::__for_each_selector<_RAIter> __functionality;
96 return __gnu_parallel::
97 __for_each_template_random_access(
98 __begin, __end, __f, __functionality,
99 __gnu_parallel::_DummyReduct(), true, __dummy, -1,
103 return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
107 template<typename _Iterator, typename _Function>
109 for_each(_Iterator __begin, _Iterator __end, _Function __f,
110 __gnu_parallel::_Parallelism __parallelism_tag)
112 typedef std::iterator_traits<_Iterator> _IteratorTraits;
113 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
114 return __for_each_switch(__begin, __end, __f, _IteratorCategory(),
118 template<typename _Iterator, typename _Function>
120 for_each(_Iterator __begin, _Iterator __end, _Function __f)
122 typedef std::iterator_traits<_Iterator> _IteratorTraits;
123 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
124 return __for_each_switch(__begin, __end, __f, _IteratorCategory());
128 // Sequential fallback
129 template<typename _IIter, typename _Tp>
131 find(_IIter __begin, _IIter __end, const _Tp& __val,
132 __gnu_parallel::sequential_tag)
133 { return _GLIBCXX_STD_P::find(__begin, __end, __val); }
135 // Sequential fallback for input iterator case
136 template<typename _IIter, typename _Tp, typename _IteratorTag>
138 __find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
140 { return _GLIBCXX_STD_P::find(__begin, __end, __val); }
142 // Parallel find for random access iterators
143 template<typename _RAIter, typename _Tp>
145 __find_switch(_RAIter __begin, _RAIter __end,
146 const _Tp& __val, random_access_iterator_tag)
148 typedef iterator_traits<_RAIter> _TraitsType;
149 typedef typename _TraitsType::value_type _ValueType;
151 if (_GLIBCXX_PARALLEL_CONDITION(true))
153 binder2nd<__gnu_parallel::_EqualTo<_ValueType, const _Tp&> >
154 __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val);
155 return __gnu_parallel::__find_template(
156 __begin, __end, __begin, __comp,
157 __gnu_parallel::__find_if_selector()).first;
160 return _GLIBCXX_STD_P::find(__begin, __end, __val);
164 template<typename _IIter, typename _Tp>
166 find(_IIter __begin, _IIter __end, const _Tp& __val)
168 typedef std::iterator_traits<_IIter> _IteratorTraits;
169 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
170 return __find_switch(__begin, __end, __val, _IteratorCategory());
173 // Sequential fallback
174 template<typename _IIter, typename _Predicate>
176 find_if(_IIter __begin, _IIter __end, _Predicate __pred,
177 __gnu_parallel::sequential_tag)
178 { return _GLIBCXX_STD_P::find_if(__begin, __end, __pred); }
180 // Sequential fallback for input iterator case
181 template<typename _IIter, typename _Predicate, typename _IteratorTag>
183 __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
185 { return _GLIBCXX_STD_P::find_if(__begin, __end, __pred); }
187 // Parallel find_if for random access iterators
188 template<typename _RAIter, typename _Predicate>
190 __find_if_switch(_RAIter __begin, _RAIter __end,
191 _Predicate __pred, random_access_iterator_tag)
193 if (_GLIBCXX_PARALLEL_CONDITION(true))
194 return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
196 __find_if_selector()).first;
198 return _GLIBCXX_STD_P::find_if(__begin, __end, __pred);
202 template<typename _IIter, typename _Predicate>
204 find_if(_IIter __begin, _IIter __end, _Predicate __pred)
206 typedef std::iterator_traits<_IIter> _IteratorTraits;
207 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
208 return __find_if_switch(__begin, __end, __pred, _IteratorCategory());
211 // Sequential fallback
212 template<typename _IIter, typename _FIterator>
214 find_first_of(_IIter __begin1, _IIter __end1,
215 _FIterator __begin2, _FIterator __end2,
216 __gnu_parallel::sequential_tag)
217 { return _GLIBCXX_STD_P::find_first_of(__begin1, __end1, __begin2, __end2);
220 // Sequential fallback
221 template<typename _IIter, typename _FIterator,
222 typename _BinaryPredicate>
224 find_first_of(_IIter __begin1, _IIter __end1,
225 _FIterator __begin2, _FIterator __end2,
226 _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
227 { return _GLIBCXX_STD_P::find_first_of(
228 __begin1, __end1, __begin2, __end2, __comp); }
230 // Sequential fallback for input iterator type
231 template<typename _IIter, typename _FIterator,
232 typename _IteratorTag1, typename _IteratorTag2>
234 __find_first_of_switch(_IIter __begin1, _IIter __end1,
235 _FIterator __begin2, _FIterator __end2,
236 _IteratorTag1, _IteratorTag2)
237 { return find_first_of(__begin1, __end1, __begin2, __end2,
238 __gnu_parallel::sequential_tag()); }
240 // Parallel algorithm for random access iterators
241 template<typename _RAIter, typename _FIterator,
242 typename _BinaryPredicate, typename _IteratorTag>
244 __find_first_of_switch(_RAIter __begin1,
246 _FIterator __begin2, _FIterator __end2,
247 _BinaryPredicate __comp, random_access_iterator_tag,
250 return __gnu_parallel::
251 __find_template(__begin1, __end1, __begin1, __comp,
252 __gnu_parallel::__find_first_of_selector
253 <_FIterator>(__begin2, __end2)).first;
256 // Sequential fallback for input iterator type
257 template<typename _IIter, typename _FIterator,
258 typename _BinaryPredicate, typename _IteratorTag1,
259 typename _IteratorTag2>
261 __find_first_of_switch(_IIter __begin1, _IIter __end1,
262 _FIterator __begin2, _FIterator __end2,
263 _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
264 { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
265 __gnu_parallel::sequential_tag()); }
268 template<typename _IIter, typename _FIterator,
269 typename _BinaryPredicate>
271 find_first_of(_IIter __begin1, _IIter __end1,
272 _FIterator __begin2, _FIterator __end2,
273 _BinaryPredicate __comp)
275 typedef std::iterator_traits<_IIter> _IIterTraits;
276 typedef std::iterator_traits<_FIterator> iteratorf_traits;
277 typedef typename _IIterTraits::iterator_category _IIteratorCategory;
278 typedef typename iteratorf_traits::iterator_category iteratorf_category;
280 return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
281 _IIteratorCategory(), iteratorf_category());
284 // Public interface, insert default comparator
285 template<typename _IIter, typename _FIterator>
287 find_first_of(_IIter __begin1, _IIter __end1,
288 _FIterator __begin2, _FIterator __end2)
290 typedef std::iterator_traits<_IIter> _IIterTraits;
291 typedef std::iterator_traits<_FIterator> iteratorf_traits;
292 typedef typename _IIterTraits::value_type _IValueType;
293 typedef typename iteratorf_traits::value_type _FValueType;
295 return find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::
296 _EqualTo<_IValueType, _FValueType>());
299 // Sequential fallback
300 template<typename _IIter, typename _OutputIterator>
301 inline _OutputIterator
302 unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
303 __gnu_parallel::sequential_tag)
304 { return _GLIBCXX_STD_P::unique_copy(__begin1, __end1, __out); }
306 // Sequential fallback
307 template<typename _IIter, typename _OutputIterator,
309 inline _OutputIterator
310 unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
311 _Predicate __pred, __gnu_parallel::sequential_tag)
312 { return _GLIBCXX_STD_P::unique_copy(__begin1, __end1, __out, __pred); }
314 // Sequential fallback for input iterator case
315 template<typename _IIter, typename _OutputIterator,
316 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
317 inline _OutputIterator
318 __unique_copy_switch(_IIter __begin, _IIter __last,
319 _OutputIterator __out, _Predicate __pred,
320 _IteratorTag1, _IteratorTag2)
321 { return _GLIBCXX_STD_P::unique_copy(__begin, __last, __out, __pred); }
323 // Parallel unique_copy for random access iterators
324 template<typename _RAIter, typename RandomAccessOutputIterator,
326 RandomAccessOutputIterator
327 __unique_copy_switch(_RAIter __begin, _RAIter __last,
328 RandomAccessOutputIterator __out, _Predicate __pred,
329 random_access_iterator_tag, random_access_iterator_tag)
331 if (_GLIBCXX_PARALLEL_CONDITION(
332 static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
333 > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
334 return __gnu_parallel::__parallel_unique_copy(
335 __begin, __last, __out, __pred);
337 return _GLIBCXX_STD_P::unique_copy(__begin, __last, __out, __pred);
341 template<typename _IIter, typename _OutputIterator>
342 inline _OutputIterator
343 unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
345 typedef std::iterator_traits<_IIter> _IIterTraits;
346 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
347 typedef typename _IIterTraits::iterator_category _IIteratorCategory;
348 typedef typename _IIterTraits::value_type _ValueType;
349 typedef typename _OIterTraits::iterator_category _OIterCategory;
351 return __unique_copy_switch(
352 __begin1, __end1, __out, equal_to<_ValueType>(),
353 _IIteratorCategory(), _OIterCategory());
357 template<typename _IIter, typename _OutputIterator, typename _Predicate>
358 inline _OutputIterator
359 unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
362 typedef std::iterator_traits<_IIter> _IIterTraits;
363 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
364 typedef typename _IIterTraits::iterator_category _IIteratorCategory;
365 typedef typename _OIterTraits::iterator_category _OIterCategory;
367 return __unique_copy_switch(
368 __begin1, __end1, __out, __pred,
369 _IIteratorCategory(), _OIterCategory());
372 // Sequential fallback
373 template<typename _IIter1, typename _IIter2,
374 typename _OutputIterator>
375 inline _OutputIterator
376 set_union(_IIter1 __begin1, _IIter1 __end1,
377 _IIter2 __begin2, _IIter2 __end2,
378 _OutputIterator __out, __gnu_parallel::sequential_tag)
379 { return _GLIBCXX_STD_P::set_union(
380 __begin1, __end1, __begin2, __end2, __out); }
382 // Sequential fallback
383 template<typename _IIter1, typename _IIter2,
384 typename _OutputIterator, typename _Predicate>
385 inline _OutputIterator
386 set_union(_IIter1 __begin1, _IIter1 __end1,
387 _IIter2 __begin2, _IIter2 __end2,
388 _OutputIterator __out, _Predicate __pred,
389 __gnu_parallel::sequential_tag)
390 { return _GLIBCXX_STD_P::set_union(__begin1, __end1,
391 __begin2, __end2, __out, __pred); }
393 // Sequential fallback for input iterator case
394 template<typename _IIter1, typename _IIter2, typename _Predicate,
395 typename _OutputIterator, typename _IteratorTag1,
396 typename _IteratorTag2, typename _IteratorTag3>
397 inline _OutputIterator
399 _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
400 _OutputIterator __result, _Predicate __pred,
401 _IteratorTag1, _IteratorTag2, _IteratorTag3)
402 { return _GLIBCXX_STD_P::set_union(__begin1, __end1,
403 __begin2, __end2, __result, __pred); }
405 // Parallel set_union for random access iterators
406 template<typename _RAIter1, typename _RAIter2,
407 typename _Output_RAIter, typename _Predicate>
409 __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
410 _RAIter2 __begin2, _RAIter2 __end2,
411 _Output_RAIter __result, _Predicate __pred,
412 random_access_iterator_tag, random_access_iterator_tag,
413 random_access_iterator_tag)
415 if (_GLIBCXX_PARALLEL_CONDITION(
416 static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
417 >= __gnu_parallel::_Settings::get().set_union_minimal_n
418 || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
419 >= __gnu_parallel::_Settings::get().set_union_minimal_n))
420 return __gnu_parallel::__parallel_set_union(
421 __begin1, __end1, __begin2, __end2, __result, __pred);
423 return _GLIBCXX_STD_P::set_union(__begin1, __end1,
424 __begin2, __end2, __result, __pred);
428 template<typename _IIter1, typename _IIter2,
429 typename _OutputIterator>
430 inline _OutputIterator
431 set_union(_IIter1 __begin1, _IIter1 __end1,
432 _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
434 typedef std::iterator_traits<_IIter1> _IIterTraits1;
435 typedef std::iterator_traits<_IIter2> _IIterTraits2;
436 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
437 typedef typename _IIterTraits1::iterator_category
439 typedef typename _IIterTraits2::iterator_category
441 typedef typename _OIterTraits::iterator_category _OIterCategory;
442 typedef typename _IIterTraits1::value_type _ValueType1;
443 typedef typename _IIterTraits2::value_type _ValueType2;
445 return __set_union_switch(
446 __begin1, __end1, __begin2, __end2, __out,
447 __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
448 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
452 template<typename _IIter1, typename _IIter2,
453 typename _OutputIterator, typename _Predicate>
454 inline _OutputIterator
455 set_union(_IIter1 __begin1, _IIter1 __end1,
456 _IIter2 __begin2, _IIter2 __end2,
457 _OutputIterator __out, _Predicate __pred)
459 typedef std::iterator_traits<_IIter1> _IIterTraits1;
460 typedef std::iterator_traits<_IIter2> _IIterTraits2;
461 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
462 typedef typename _IIterTraits1::iterator_category
464 typedef typename _IIterTraits2::iterator_category
466 typedef typename _OIterTraits::iterator_category _OIterCategory;
468 return __set_union_switch(
469 __begin1, __end1, __begin2, __end2, __out, __pred,
470 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
473 // Sequential fallback.
474 template<typename _IIter1, typename _IIter2,
475 typename _OutputIterator>
476 inline _OutputIterator
477 set_intersection(_IIter1 __begin1, _IIter1 __end1,
478 _IIter2 __begin2, _IIter2 __end2,
479 _OutputIterator __out, __gnu_parallel::sequential_tag)
480 { return _GLIBCXX_STD_P::set_intersection(__begin1, __end1,
481 __begin2, __end2, __out); }
483 // Sequential fallback.
484 template<typename _IIter1, typename _IIter2,
485 typename _OutputIterator, typename _Predicate>
486 inline _OutputIterator
487 set_intersection(_IIter1 __begin1, _IIter1 __end1,
488 _IIter2 __begin2, _IIter2 __end2,
489 _OutputIterator __out, _Predicate __pred,
490 __gnu_parallel::sequential_tag)
491 { return _GLIBCXX_STD_P::set_intersection(
492 __begin1, __end1, __begin2, __end2, __out, __pred); }
494 // Sequential fallback for input iterator case
495 template<typename _IIter1, typename _IIter2,
496 typename _Predicate, typename _OutputIterator,
497 typename _IteratorTag1, typename _IteratorTag2,
498 typename _IteratorTag3>
499 inline _OutputIterator
500 __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
501 _IIter2 __begin2, _IIter2 __end2,
502 _OutputIterator __result, _Predicate __pred,
503 _IteratorTag1, _IteratorTag2, _IteratorTag3)
504 { return _GLIBCXX_STD_P::set_intersection(__begin1, __end1, __begin2,
505 __end2, __result, __pred); }
507 // Parallel set_intersection for random access iterators
508 template<typename _RAIter1, typename _RAIter2,
509 typename _Output_RAIter, typename _Predicate>
511 __set_intersection_switch(_RAIter1 __begin1,
515 _Output_RAIter __result,
517 random_access_iterator_tag,
518 random_access_iterator_tag,
519 random_access_iterator_tag)
521 if (_GLIBCXX_PARALLEL_CONDITION(
522 static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
523 >= __gnu_parallel::_Settings::get().set_union_minimal_n
524 || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
525 >= __gnu_parallel::_Settings::get().set_union_minimal_n))
526 return __gnu_parallel::__parallel_set_intersection(
527 __begin1, __end1, __begin2, __end2, __result, __pred);
529 return _GLIBCXX_STD_P::set_intersection(
530 __begin1, __end1, __begin2, __end2, __result, __pred);
534 template<typename _IIter1, typename _IIter2,
535 typename _OutputIterator>
536 inline _OutputIterator
537 set_intersection(_IIter1 __begin1, _IIter1 __end1,
538 _IIter2 __begin2, _IIter2 __end2,
539 _OutputIterator __out)
541 typedef std::iterator_traits<_IIter1> _IIterTraits1;
542 typedef std::iterator_traits<_IIter2> _IIterTraits2;
543 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
544 typedef typename _IIterTraits1::iterator_category
546 typedef typename _IIterTraits2::iterator_category
548 typedef typename _OIterTraits::iterator_category _OIterCategory;
549 typedef typename _IIterTraits1::value_type _ValueType1;
550 typedef typename _IIterTraits2::value_type _ValueType2;
552 return __set_intersection_switch(
553 __begin1, __end1, __begin2, __end2, __out,
554 __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
555 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
558 template<typename _IIter1, typename _IIter2,
559 typename _OutputIterator, typename _Predicate>
560 inline _OutputIterator
561 set_intersection(_IIter1 __begin1, _IIter1 __end1,
562 _IIter2 __begin2, _IIter2 __end2,
563 _OutputIterator __out, _Predicate __pred)
565 typedef std::iterator_traits<_IIter1> _IIterTraits1;
566 typedef std::iterator_traits<_IIter2> _IIterTraits2;
567 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
568 typedef typename _IIterTraits1::iterator_category
570 typedef typename _IIterTraits2::iterator_category
572 typedef typename _OIterTraits::iterator_category _OIterCategory;
574 return __set_intersection_switch(
575 __begin1, __end1, __begin2, __end2, __out, __pred,
576 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
579 // Sequential fallback
580 template<typename _IIter1, typename _IIter2,
581 typename _OutputIterator>
582 inline _OutputIterator
583 set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
584 _IIter2 __begin2, _IIter2 __end2,
585 _OutputIterator __out,
586 __gnu_parallel::sequential_tag)
587 { return _GLIBCXX_STD_P::set_symmetric_difference(
588 __begin1, __end1, __begin2, __end2, __out); }
590 // Sequential fallback
591 template<typename _IIter1, typename _IIter2,
592 typename _OutputIterator, typename _Predicate>
593 inline _OutputIterator
594 set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
595 _IIter2 __begin2, _IIter2 __end2,
596 _OutputIterator __out, _Predicate __pred,
597 __gnu_parallel::sequential_tag)
598 { return _GLIBCXX_STD_P::set_symmetric_difference(
599 __begin1, __end1, __begin2, __end2, __out, __pred); }
601 // Sequential fallback for input iterator case
602 template<typename _IIter1, typename _IIter2,
603 typename _Predicate, typename _OutputIterator,
604 typename _IteratorTag1, typename _IteratorTag2,
605 typename _IteratorTag3>
606 inline _OutputIterator
607 __set_symmetric_difference_switch(
608 _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
609 _OutputIterator __result, _Predicate __pred,
610 _IteratorTag1, _IteratorTag2, _IteratorTag3)
611 { return _GLIBCXX_STD_P::set_symmetric_difference(
612 __begin1, __end1, __begin2, __end2, __result, __pred); }
614 // Parallel set_symmetric_difference for random access iterators
615 template<typename _RAIter1, typename _RAIter2,
616 typename _Output_RAIter, typename _Predicate>
618 __set_symmetric_difference_switch(_RAIter1 __begin1,
622 _Output_RAIter __result,
624 random_access_iterator_tag,
625 random_access_iterator_tag,
626 random_access_iterator_tag)
628 if (_GLIBCXX_PARALLEL_CONDITION(
629 static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
630 >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
631 || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
632 >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
633 return __gnu_parallel::__parallel_set_symmetric_difference(
634 __begin1, __end1, __begin2, __end2, __result, __pred);
636 return _GLIBCXX_STD_P::set_symmetric_difference(
637 __begin1, __end1, __begin2, __end2, __result, __pred);
641 template<typename _IIter1, typename _IIter2,
642 typename _OutputIterator>
643 inline _OutputIterator
644 set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
645 _IIter2 __begin2, _IIter2 __end2,
646 _OutputIterator __out)
648 typedef std::iterator_traits<_IIter1> _IIterTraits1;
649 typedef std::iterator_traits<_IIter2> _IIterTraits2;
650 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
651 typedef typename _IIterTraits1::iterator_category
653 typedef typename _IIterTraits2::iterator_category
655 typedef typename _OIterTraits::iterator_category _OIterCategory;
656 typedef typename _IIterTraits1::value_type _ValueType1;
657 typedef typename _IIterTraits2::value_type _ValueType2;
659 return __set_symmetric_difference_switch(
660 __begin1, __end1, __begin2, __end2, __out,
661 __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
662 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
666 template<typename _IIter1, typename _IIter2,
667 typename _OutputIterator, typename _Predicate>
668 inline _OutputIterator
669 set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
670 _IIter2 __begin2, _IIter2 __end2,
671 _OutputIterator __out, _Predicate __pred)
673 typedef std::iterator_traits<_IIter1> _IIterTraits1;
674 typedef std::iterator_traits<_IIter2> _IIterTraits2;
675 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
676 typedef typename _IIterTraits1::iterator_category
678 typedef typename _IIterTraits2::iterator_category
680 typedef typename _OIterTraits::iterator_category _OIterCategory;
682 return __set_symmetric_difference_switch(
683 __begin1, __end1, __begin2, __end2, __out, __pred,
684 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
687 // Sequential fallback.
688 template<typename _IIter1, typename _IIter2,
689 typename _OutputIterator>
690 inline _OutputIterator
691 set_difference(_IIter1 __begin1, _IIter1 __end1,
692 _IIter2 __begin2, _IIter2 __end2,
693 _OutputIterator __out, __gnu_parallel::sequential_tag)
694 { return _GLIBCXX_STD_P::set_difference(
695 __begin1,__end1, __begin2, __end2, __out); }
697 // Sequential fallback.
698 template<typename _IIter1, typename _IIter2,
699 typename _OutputIterator, typename _Predicate>
700 inline _OutputIterator
701 set_difference(_IIter1 __begin1, _IIter1 __end1,
702 _IIter2 __begin2, _IIter2 __end2,
703 _OutputIterator __out, _Predicate __pred,
704 __gnu_parallel::sequential_tag)
705 { return _GLIBCXX_STD_P::set_difference(__begin1, __end1,
706 __begin2, __end2, __out, __pred); }
708 // Sequential fallback for input iterator case.
709 template<typename _IIter1, typename _IIter2, typename _Predicate,
710 typename _OutputIterator, typename _IteratorTag1,
711 typename _IteratorTag2, typename _IteratorTag3>
712 inline _OutputIterator
713 __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
714 _IIter2 __begin2, _IIter2 __end2,
715 _OutputIterator __result, _Predicate __pred,
716 _IteratorTag1, _IteratorTag2, _IteratorTag3)
717 { return _GLIBCXX_STD_P::set_difference(
718 __begin1, __end1, __begin2, __end2, __result, __pred); }
720 // Parallel set_difference for random access iterators
721 template<typename _RAIter1, typename _RAIter2,
722 typename _Output_RAIter, typename _Predicate>
724 __set_difference_switch(_RAIter1 __begin1,
728 _Output_RAIter __result, _Predicate __pred,
729 random_access_iterator_tag,
730 random_access_iterator_tag,
731 random_access_iterator_tag)
733 if (_GLIBCXX_PARALLEL_CONDITION(
734 static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
735 >= __gnu_parallel::_Settings::get().set_difference_minimal_n
736 || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
737 >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
738 return __gnu_parallel::__parallel_set_difference(
739 __begin1, __end1, __begin2, __end2, __result, __pred);
741 return _GLIBCXX_STD_P::set_difference(
742 __begin1, __end1, __begin2, __end2, __result, __pred);
746 template<typename _IIter1, typename _IIter2,
747 typename _OutputIterator>
748 inline _OutputIterator
749 set_difference(_IIter1 __begin1, _IIter1 __end1,
750 _IIter2 __begin2, _IIter2 __end2,
751 _OutputIterator __out)
753 typedef std::iterator_traits<_IIter1> _IIterTraits1;
754 typedef std::iterator_traits<_IIter2> _IIterTraits2;
755 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
756 typedef typename _IIterTraits1::iterator_category
758 typedef typename _IIterTraits2::iterator_category
760 typedef typename _OIterTraits::iterator_category _OIterCategory;
761 typedef typename _IIterTraits1::value_type _ValueType1;
762 typedef typename _IIterTraits2::value_type _ValueType2;
764 return __set_difference_switch(
765 __begin1, __end1, __begin2, __end2, __out,
766 __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
767 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
771 template<typename _IIter1, typename _IIter2,
772 typename _OutputIterator, typename _Predicate>
773 inline _OutputIterator
774 set_difference(_IIter1 __begin1, _IIter1 __end1,
775 _IIter2 __begin2, _IIter2 __end2,
776 _OutputIterator __out, _Predicate __pred)
778 typedef std::iterator_traits<_IIter1> _IIterTraits1;
779 typedef std::iterator_traits<_IIter2> _IIterTraits2;
780 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
781 typedef typename _IIterTraits1::iterator_category
783 typedef typename _IIterTraits2::iterator_category
785 typedef typename _OIterTraits::iterator_category _OIterCategory;
787 return __set_difference_switch(
788 __begin1, __end1, __begin2, __end2, __out, __pred,
789 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
792 // Sequential fallback
793 template<typename _FIterator>
795 adjacent_find(_FIterator __begin, _FIterator __end,
796 __gnu_parallel::sequential_tag)
797 { return _GLIBCXX_STD_P::adjacent_find(__begin, __end); }
799 // Sequential fallback
800 template<typename _FIterator, typename _BinaryPredicate>
802 adjacent_find(_FIterator __begin, _FIterator __end,
803 _BinaryPredicate __binary_pred,
804 __gnu_parallel::sequential_tag)
805 { return _GLIBCXX_STD_P::adjacent_find(__begin, __end, __binary_pred); }
807 // Parallel algorithm for random access iterators
808 template<typename _RAIter>
810 __adjacent_find_switch(_RAIter __begin, _RAIter __end,
811 random_access_iterator_tag)
813 typedef iterator_traits<_RAIter> _TraitsType;
814 typedef typename _TraitsType::value_type _ValueType;
816 if (_GLIBCXX_PARALLEL_CONDITION(true))
818 _RAIter __spot = __gnu_parallel::
820 __begin, __end - 1, __begin, equal_to<_ValueType>(),
821 __gnu_parallel::__adjacent_find_selector())
823 if (__spot == (__end - 1))
829 return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
832 // Sequential fallback for input iterator case
833 template<typename _FIterator, typename _IteratorTag>
835 __adjacent_find_switch(_FIterator __begin, _FIterator __end,
837 { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }
840 template<typename _FIterator>
842 adjacent_find(_FIterator __begin, _FIterator __end)
844 typedef iterator_traits<_FIterator> _TraitsType;
845 typedef typename _TraitsType::iterator_category _IteratorCategory;
846 return __adjacent_find_switch(__begin, __end, _IteratorCategory());
849 // Sequential fallback for input iterator case
850 template<typename _FIterator, typename _BinaryPredicate,
851 typename _IteratorTag>
853 __adjacent_find_switch(_FIterator __begin, _FIterator __end,
854 _BinaryPredicate __pred, _IteratorTag)
855 { return adjacent_find(__begin, __end, __pred,
856 __gnu_parallel::sequential_tag()); }
858 // Parallel algorithm for random access iterators
859 template<typename _RAIter, typename _BinaryPredicate>
861 __adjacent_find_switch(_RAIter __begin, _RAIter __end,
862 _BinaryPredicate __pred, random_access_iterator_tag)
864 if (_GLIBCXX_PARALLEL_CONDITION(true))
865 return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
867 __adjacent_find_selector()).first;
869 return adjacent_find(__begin, __end, __pred,
870 __gnu_parallel::sequential_tag());
874 template<typename _FIterator, typename _BinaryPredicate>
876 adjacent_find(_FIterator __begin, _FIterator __end,
877 _BinaryPredicate __pred)
879 typedef iterator_traits<_FIterator> _TraitsType;
880 typedef typename _TraitsType::iterator_category _IteratorCategory;
881 return __adjacent_find_switch(__begin, __end, __pred,
882 _IteratorCategory());
885 // Sequential fallback
886 template<typename _IIter, typename _Tp>
887 inline typename iterator_traits<_IIter>::difference_type
888 count(_IIter __begin, _IIter __end, const _Tp& __value,
889 __gnu_parallel::sequential_tag)
890 { return _GLIBCXX_STD_P::count(__begin, __end, __value); }
892 // Parallel code for random access iterators
893 template<typename _RAIter, typename _Tp>
894 typename iterator_traits<_RAIter>::difference_type
895 __count_switch(_RAIter __begin, _RAIter __end,
896 const _Tp& __value, random_access_iterator_tag,
897 __gnu_parallel::_Parallelism __parallelism_tag
898 = __gnu_parallel::parallel_unbalanced)
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;
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)))
910 __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
912 _DifferenceType __res = 0;
914 __for_each_template_random_access(
915 __begin, __end, __value, __functionality,
916 std::plus<_SequenceIndex>(), __res, __res, -1,
921 return count(__begin, __end, __value,
922 __gnu_parallel::sequential_tag());
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,
930 { return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
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)
939 typedef iterator_traits<_IIter> _TraitsType;
940 typedef typename _TraitsType::iterator_category _IteratorCategory;
941 return __count_switch(__begin, __end, __value, _IteratorCategory(),
945 template<typename _IIter, typename _Tp>
946 inline typename iterator_traits<_IIter>::difference_type
947 count(_IIter __begin, _IIter __end, const _Tp& __value)
949 typedef iterator_traits<_IIter> _TraitsType;
950 typedef typename _TraitsType::iterator_category _IteratorCategory;
951 return __count_switch(__begin, __end, __value, _IteratorCategory());
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_P::count_if(__begin, __end, __pred); }
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 = __gnu_parallel::parallel_unbalanced)
970 typedef iterator_traits<_RAIter> _TraitsType;
971 typedef typename _TraitsType::value_type _ValueType;
972 typedef typename _TraitsType::difference_type _DifferenceType;
973 typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
975 if (_GLIBCXX_PARALLEL_CONDITION(
976 static_cast<_SequenceIndex>(__end - __begin)
977 >= __gnu_parallel::_Settings::get().count_minimal_n
978 && __gnu_parallel::__is_parallel(__parallelism_tag)))
980 _DifferenceType __res = 0;
982 __count_if_selector<_RAIter, _DifferenceType>
985 __for_each_template_random_access(
986 __begin, __end, __pred, __functionality,
987 std::plus<_SequenceIndex>(), __res, __res, -1,
992 return count_if(__begin, __end, __pred,
993 __gnu_parallel::sequential_tag());
996 // Sequential fallback for input iterator case.
997 template<typename _IIter, typename _Predicate, typename _IteratorTag>
998 inline typename iterator_traits<_IIter>::difference_type
999 __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
1001 { return count_if(__begin, __end, __pred,
1002 __gnu_parallel::sequential_tag()); }
1004 // Public interface.
1005 template<typename _IIter, typename _Predicate>
1006 inline typename iterator_traits<_IIter>::difference_type
1007 count_if(_IIter __begin, _IIter __end, _Predicate __pred,
1008 __gnu_parallel::_Parallelism __parallelism_tag)
1010 typedef iterator_traits<_IIter> _TraitsType;
1011 typedef typename _TraitsType::iterator_category _IteratorCategory;
1012 return __count_if_switch(__begin, __end, __pred, _IteratorCategory(),
1016 template<typename _IIter, typename _Predicate>
1017 inline typename iterator_traits<_IIter>::difference_type
1018 count_if(_IIter __begin, _IIter __end, _Predicate __pred)
1020 typedef iterator_traits<_IIter> _TraitsType;
1021 typedef typename _TraitsType::iterator_category _IteratorCategory;
1022 return __count_if_switch(__begin, __end, __pred, _IteratorCategory());
1026 // Sequential fallback.
1027 template<typename _FIterator1, typename _FIterator2>
1029 search(_FIterator1 __begin1, _FIterator1 __end1,
1030 _FIterator2 __begin2, _FIterator2 __end2,
1031 __gnu_parallel::sequential_tag)
1032 { return _GLIBCXX_STD_P::search(__begin1, __end1, __begin2, __end2); }
1034 // Parallel algorithm for random access iterator
1035 template<typename _RAIter1, typename _RAIter2>
1037 __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
1038 _RAIter2 __begin2, _RAIter2 __end2,
1039 random_access_iterator_tag, random_access_iterator_tag)
1041 typedef std::iterator_traits<_RAIter1> _Iterator1Traits;
1042 typedef typename _Iterator1Traits::value_type _ValueType1;
1043 typedef std::iterator_traits<_RAIter2> _Iterator2Traits;
1044 typedef typename _Iterator2Traits::value_type _ValueType2;
1046 if (_GLIBCXX_PARALLEL_CONDITION(true))
1047 return __gnu_parallel::
1049 __begin1, __end1, __begin2, __end2,
1050 __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>());
1052 return search(__begin1, __end1, __begin2, __end2,
1053 __gnu_parallel::sequential_tag());
1056 // Sequential fallback for input iterator case
1057 template<typename _FIterator1, typename _FIterator2,
1058 typename _IteratorTag1, typename _IteratorTag2>
1060 __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
1061 _FIterator2 __begin2, _FIterator2 __end2,
1062 _IteratorTag1, _IteratorTag2)
1063 { return search(__begin1, __end1, __begin2, __end2,
1064 __gnu_parallel::sequential_tag()); }
1066 // Public interface.
1067 template<typename _FIterator1, typename _FIterator2>
1069 search(_FIterator1 __begin1, _FIterator1 __end1,
1070 _FIterator2 __begin2, _FIterator2 __end2)
1072 typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
1073 typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
1074 typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
1075 typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
1077 return __search_switch(__begin1, __end1, __begin2, __end2,
1078 _IteratorCategory1(), _IteratorCategory2());
1081 // Public interface.
1082 template<typename _FIterator1, typename _FIterator2,
1083 typename _BinaryPredicate>
1085 search(_FIterator1 __begin1, _FIterator1 __end1,
1086 _FIterator2 __begin2, _FIterator2 __end2,
1087 _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
1088 { return _GLIBCXX_STD_P::search(
1089 __begin1, __end1, __begin2, __end2, __pred); }
1091 // Parallel algorithm for random access iterator.
1092 template<typename _RAIter1, typename _RAIter2,
1093 typename _BinaryPredicate>
1095 __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
1096 _RAIter2 __begin2, _RAIter2 __end2,
1097 _BinaryPredicate __pred,
1098 random_access_iterator_tag, random_access_iterator_tag)
1100 if (_GLIBCXX_PARALLEL_CONDITION(true))
1101 return __gnu_parallel::__search_template(__begin1, __end1,
1102 __begin2, __end2, __pred);
1104 return search(__begin1, __end1, __begin2, __end2, __pred,
1105 __gnu_parallel::sequential_tag());
1108 // Sequential fallback for input iterator case
1109 template<typename _FIterator1, typename _FIterator2,
1110 typename _BinaryPredicate, typename _IteratorTag1,
1111 typename _IteratorTag2>
1113 __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
1114 _FIterator2 __begin2, _FIterator2 __end2,
1115 _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
1116 { return search(__begin1, __end1, __begin2, __end2, __pred,
1117 __gnu_parallel::sequential_tag()); }
1120 template<typename _FIterator1, typename _FIterator2,
1121 typename _BinaryPredicate>
1123 search(_FIterator1 __begin1, _FIterator1 __end1,
1124 _FIterator2 __begin2, _FIterator2 __end2,
1125 _BinaryPredicate __pred)
1127 typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
1128 typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
1129 typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
1130 typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
1131 return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
1132 _IteratorCategory1(), _IteratorCategory2());
1135 // Sequential fallback
1136 template<typename _FIterator, typename _Integer, typename _Tp>
1138 search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1139 const _Tp& __val, __gnu_parallel::sequential_tag)
1140 { return _GLIBCXX_STD_P::search_n(__begin, __end, __count, __val); }
1142 // Sequential fallback
1143 template<typename _FIterator, typename _Integer, typename _Tp,
1144 typename _BinaryPredicate>
1146 search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1147 const _Tp& __val, _BinaryPredicate __binary_pred,
1148 __gnu_parallel::sequential_tag)
1149 { return _GLIBCXX_STD_P::search_n(
1150 __begin, __end, __count, __val, __binary_pred); }
1152 // Public interface.
1153 template<typename _FIterator, typename _Integer, typename _Tp>
1155 search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1158 typedef typename iterator_traits<_FIterator>::value_type _ValueType;
1159 return search_n(__begin, __end, __count, __val,
1160 __gnu_parallel::_EqualTo<_ValueType, _Tp>());
1163 // Parallel algorithm for random access iterators.
1164 template<typename _RAIter, typename _Integer,
1165 typename _Tp, typename _BinaryPredicate>
1167 __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count,
1168 const _Tp& __val, _BinaryPredicate __binary_pred,
1169 random_access_iterator_tag)
1171 if (_GLIBCXX_PARALLEL_CONDITION(true))
1173 __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count);
1174 return __gnu_parallel::__search_template(
1175 __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
1178 return std::__search_n(__begin, __end, __count, __val,
1179 __binary_pred, random_access_iterator_tag());
1182 // Sequential fallback for input iterator case.
1183 template<typename _FIterator, typename _Integer, typename _Tp,
1184 typename _BinaryPredicate, typename _IteratorTag>
1186 __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count,
1187 const _Tp& __val, _BinaryPredicate __binary_pred,
1189 { return __search_n(__begin, __end, __count, __val, __binary_pred,
1192 // Public interface.
1193 template<typename _FIterator, typename _Integer, typename _Tp,
1194 typename _BinaryPredicate>
1196 search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1197 const _Tp& __val, _BinaryPredicate __binary_pred)
1199 return __search_n_switch(__begin, __end, __count, __val, __binary_pred,
1200 typename std::iterator_traits<_FIterator>::
1201 iterator_category());
1205 // Sequential fallback.
1206 template<typename _IIter, typename _OutputIterator,
1207 typename _UnaryOperation>
1208 inline _OutputIterator
1209 transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1210 _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
1211 { return _GLIBCXX_STD_P::transform(__begin, __end, __result, __unary_op); }
1213 // Parallel unary transform for random access iterators.
1214 template<typename _RAIter1, typename _RAIter2,
1215 typename _UnaryOperation>
1217 __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
1218 _RAIter2 __result, _UnaryOperation __unary_op,
1219 random_access_iterator_tag, random_access_iterator_tag,
1220 __gnu_parallel::_Parallelism __parallelism_tag
1221 = __gnu_parallel::parallel_balanced)
1223 if (_GLIBCXX_PARALLEL_CONDITION(
1224 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1225 >= __gnu_parallel::_Settings::get().transform_minimal_n
1226 && __gnu_parallel::__is_parallel(__parallelism_tag)))
1228 bool __dummy = true;
1229 typedef __gnu_parallel::_IteratorPair<_RAIter1,
1230 _RAIter2, random_access_iterator_tag> _ItTrip;
1231 _ItTrip begin_pair(__begin, __result),
1232 end_pair(__end, __result + (__end - __begin));
1233 __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
1235 __for_each_template_random_access(
1236 begin_pair, end_pair, __unary_op, __functionality,
1237 __gnu_parallel::_DummyReduct(),
1238 __dummy, __dummy, -1, __parallelism_tag);
1239 return __functionality._M_finish_iterator;
1242 return transform(__begin, __end, __result, __unary_op,
1243 __gnu_parallel::sequential_tag());
1246 // Sequential fallback for input iterator case.
1247 template<typename _RAIter1, typename _RAIter2,
1248 typename _UnaryOperation, typename _IteratorTag1,
1249 typename _IteratorTag2>
1251 __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
1252 _RAIter2 __result, _UnaryOperation __unary_op,
1253 _IteratorTag1, _IteratorTag2)
1254 { return transform(__begin, __end, __result, __unary_op,
1255 __gnu_parallel::sequential_tag()); }
1257 // Public interface.
1258 template<typename _IIter, typename _OutputIterator,
1259 typename _UnaryOperation>
1260 inline _OutputIterator
1261 transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1262 _UnaryOperation __unary_op,
1263 __gnu_parallel::_Parallelism __parallelism_tag)
1265 typedef std::iterator_traits<_IIter> _IIterTraits;
1266 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1267 typedef typename _IIterTraits::iterator_category _IIteratorCategory;
1268 typedef typename _OIterTraits::iterator_category _OIterCategory;
1270 return __transform1_switch(__begin, __end, __result, __unary_op,
1271 _IIteratorCategory(), _OIterCategory(),
1275 template<typename _IIter, typename _OutputIterator,
1276 typename _UnaryOperation>
1277 inline _OutputIterator
1278 transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1279 _UnaryOperation __unary_op)
1281 typedef std::iterator_traits<_IIter> _IIterTraits;
1282 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1283 typedef typename _IIterTraits::iterator_category _IIteratorCategory;
1284 typedef typename _OIterTraits::iterator_category _OIterCategory;
1286 return __transform1_switch(__begin, __end, __result, __unary_op,
1287 _IIteratorCategory(), _OIterCategory());
1291 // Sequential fallback
1292 template<typename _IIter1, typename _IIter2,
1293 typename _OutputIterator, typename _BinaryOperation>
1294 inline _OutputIterator
1295 transform(_IIter1 __begin1, _IIter1 __end1,
1296 _IIter2 __begin2, _OutputIterator __result,
1297 _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
1298 { return _GLIBCXX_STD_P::transform(__begin1, __end1,
1299 __begin2, __result, __binary_op); }
1301 // Parallel binary transform for random access iterators.
1302 template<typename _RAIter1, typename _RAIter2,
1303 typename _RAIter3, typename _BinaryOperation>
1305 __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
1307 _RAIter3 __result, _BinaryOperation __binary_op,
1308 random_access_iterator_tag, random_access_iterator_tag,
1309 random_access_iterator_tag,
1310 __gnu_parallel::_Parallelism __parallelism_tag
1311 = __gnu_parallel::parallel_balanced)
1313 if (_GLIBCXX_PARALLEL_CONDITION(
1314 (__end1 - __begin1) >=
1315 __gnu_parallel::_Settings::get().transform_minimal_n
1316 && __gnu_parallel::__is_parallel(__parallelism_tag)))
1318 bool __dummy = true;
1319 typedef __gnu_parallel::_IteratorTriple<_RAIter1,
1321 random_access_iterator_tag> _ItTrip;
1322 _ItTrip __begin_triple(__begin1, __begin2, __result),
1323 __end_triple(__end1, __begin2 + (__end1 - __begin1),
1324 __result + (__end1 - __begin1));
1325 __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
1327 __for_each_template_random_access(__begin_triple, __end_triple,
1328 __binary_op, __functionality,
1329 __gnu_parallel::_DummyReduct(),
1330 __dummy, __dummy, -1,
1332 return __functionality._M_finish_iterator;
1335 return transform(__begin1, __end1, __begin2, __result, __binary_op,
1336 __gnu_parallel::sequential_tag());
1339 // Sequential fallback for input iterator case.
1340 template<typename _IIter1, typename _IIter2,
1341 typename _OutputIterator, typename _BinaryOperation,
1342 typename _Tag1, typename _Tag2, typename _Tag3>
1343 inline _OutputIterator
1344 __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
1345 _IIter2 __begin2, _OutputIterator __result,
1346 _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
1347 { return transform(__begin1, __end1, __begin2, __result, __binary_op,
1348 __gnu_parallel::sequential_tag()); }
1350 // Public interface.
1351 template<typename _IIter1, typename _IIter2,
1352 typename _OutputIterator, typename _BinaryOperation>
1353 inline _OutputIterator
1354 transform(_IIter1 __begin1, _IIter1 __end1,
1355 _IIter2 __begin2, _OutputIterator __result,
1356 _BinaryOperation __binary_op,
1357 __gnu_parallel::_Parallelism __parallelism_tag)
1359 typedef std::iterator_traits<_IIter1> _IIterTraits1;
1360 typedef typename _IIterTraits1::iterator_category
1362 typedef std::iterator_traits<_IIter2> _IIterTraits2;
1363 typedef typename _IIterTraits2::iterator_category
1365 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1366 typedef typename _OIterTraits::iterator_category _OIterCategory;
1368 return __transform2_switch(
1369 __begin1, __end1, __begin2, __result, __binary_op,
1370 _IIterCategory1(), _IIterCategory2(), _OIterCategory(),
1374 template<typename _IIter1, typename _IIter2,
1375 typename _OutputIterator, typename _BinaryOperation>
1376 inline _OutputIterator
1377 transform(_IIter1 __begin1, _IIter1 __end1,
1378 _IIter2 __begin2, _OutputIterator __result,
1379 _BinaryOperation __binary_op)
1381 typedef std::iterator_traits<_IIter1> _IIterTraits1;
1382 typedef typename _IIterTraits1::iterator_category
1384 typedef std::iterator_traits<_IIter2> _IIterTraits2;
1385 typedef typename _IIterTraits2::iterator_category
1387 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
1388 typedef typename _OIterTraits::iterator_category _OIterCategory;
1390 return __transform2_switch(
1391 __begin1, __end1, __begin2, __result, __binary_op,
1392 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
1395 // Sequential fallback
1396 template<typename _FIterator, typename _Tp>
1398 replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1399 const _Tp& __new_value, __gnu_parallel::sequential_tag)
1400 { _GLIBCXX_STD_P::replace(__begin, __end, __old_value, __new_value); }
1402 // Sequential fallback for input iterator case
1403 template<typename _FIterator, typename _Tp, typename _IteratorTag>
1405 __replace_switch(_FIterator __begin, _FIterator __end,
1406 const _Tp& __old_value, const _Tp& __new_value,
1408 { replace(__begin, __end, __old_value, __new_value,
1409 __gnu_parallel::sequential_tag()); }
1411 // Parallel replace for random access iterators
1412 template<typename _RAIter, typename _Tp>
1414 __replace_switch(_RAIter __begin, _RAIter __end,
1415 const _Tp& __old_value, const _Tp& __new_value,
1416 random_access_iterator_tag,
1417 __gnu_parallel::_Parallelism __parallelism_tag
1418 = __gnu_parallel::parallel_balanced)
1420 // XXX parallel version is where?
1421 replace(__begin, __end, __old_value, __new_value,
1422 __gnu_parallel::sequential_tag());
1426 template<typename _FIterator, typename _Tp>
1428 replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1429 const _Tp& __new_value,
1430 __gnu_parallel::_Parallelism __parallelism_tag)
1432 typedef iterator_traits<_FIterator> _TraitsType;
1433 typedef typename _TraitsType::iterator_category _IteratorCategory;
1434 __replace_switch(__begin, __end, __old_value, __new_value,
1435 _IteratorCategory(),
1439 template<typename _FIterator, typename _Tp>
1441 replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1442 const _Tp& __new_value)
1444 typedef iterator_traits<_FIterator> _TraitsType;
1445 typedef typename _TraitsType::iterator_category _IteratorCategory;
1446 __replace_switch(__begin, __end, __old_value, __new_value,
1447 _IteratorCategory());
1451 // Sequential fallback
1452 template<typename _FIterator, typename _Predicate, typename _Tp>
1454 replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
1455 const _Tp& __new_value, __gnu_parallel::sequential_tag)
1456 { _GLIBCXX_STD_P::replace_if(__begin, __end, __pred, __new_value); }
1458 // Sequential fallback for input iterator case
1459 template<typename _FIterator, typename _Predicate, typename _Tp,
1460 typename _IteratorTag>
1462 __replace_if_switch(_FIterator __begin, _FIterator __end,
1463 _Predicate __pred, const _Tp& __new_value, _IteratorTag)
1464 { replace_if(__begin, __end, __pred, __new_value,
1465 __gnu_parallel::sequential_tag()); }
1467 // Parallel algorithm for random access iterators.
1468 template<typename _RAIter, typename _Predicate, typename _Tp>
1470 __replace_if_switch(_RAIter __begin, _RAIter __end,
1471 _Predicate __pred, const _Tp& __new_value,
1472 random_access_iterator_tag,
1473 __gnu_parallel::_Parallelism __parallelism_tag
1474 = __gnu_parallel::parallel_balanced)
1476 if (_GLIBCXX_PARALLEL_CONDITION(
1477 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1478 >= __gnu_parallel::_Settings::get().replace_minimal_n
1479 && __gnu_parallel::__is_parallel(__parallelism_tag)))
1483 __replace_if_selector<_RAIter, _Predicate, _Tp>
1484 __functionality(__new_value);
1486 __for_each_template_random_access(
1487 __begin, __end, __pred, __functionality,
1488 __gnu_parallel::_DummyReduct(),
1489 true, __dummy, -1, __parallelism_tag);
1492 replace_if(__begin, __end, __pred, __new_value,
1493 __gnu_parallel::sequential_tag());
1496 // Public interface.
1497 template<typename _FIterator, typename _Predicate, typename _Tp>
1499 replace_if(_FIterator __begin, _FIterator __end,
1500 _Predicate __pred, const _Tp& __new_value,
1501 __gnu_parallel::_Parallelism __parallelism_tag)
1503 typedef std::iterator_traits<_FIterator> _IteratorTraits;
1504 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1505 __replace_if_switch(__begin, __end, __pred, __new_value,
1506 _IteratorCategory(), __parallelism_tag);
1509 template<typename _FIterator, typename _Predicate, typename _Tp>
1511 replace_if(_FIterator __begin, _FIterator __end,
1512 _Predicate __pred, const _Tp& __new_value)
1514 typedef std::iterator_traits<_FIterator> _IteratorTraits;
1515 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1516 __replace_if_switch(__begin, __end, __pred, __new_value,
1517 _IteratorCategory());
1520 // Sequential fallback
1521 template<typename _FIterator, typename _Generator>
1523 generate(_FIterator __begin, _FIterator __end, _Generator __gen,
1524 __gnu_parallel::sequential_tag)
1525 { _GLIBCXX_STD_P::generate(__begin, __end, __gen); }
1527 // Sequential fallback for input iterator case.
1528 template<typename _FIterator, typename _Generator, typename _IteratorTag>
1530 __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen,
1532 { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }
1534 // Parallel algorithm for random access iterators.
1535 template<typename _RAIter, typename _Generator>
1537 __generate_switch(_RAIter __begin, _RAIter __end,
1538 _Generator __gen, random_access_iterator_tag,
1539 __gnu_parallel::_Parallelism __parallelism_tag
1540 = __gnu_parallel::parallel_balanced)
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)))
1548 __gnu_parallel::__generate_selector<_RAIter>
1551 __for_each_template_random_access(
1552 __begin, __end, __gen, __functionality,
1553 __gnu_parallel::_DummyReduct(),
1554 true, __dummy, -1, __parallelism_tag);
1557 generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
1560 // Public interface.
1561 template<typename _FIterator, typename _Generator>
1563 generate(_FIterator __begin, _FIterator __end,
1564 _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
1566 typedef std::iterator_traits<_FIterator> _IteratorTraits;
1567 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1568 __generate_switch(__begin, __end, __gen, _IteratorCategory(),
1572 template<typename _FIterator, typename _Generator>
1574 generate(_FIterator __begin, _FIterator __end, _Generator __gen)
1576 typedef std::iterator_traits<_FIterator> _IteratorTraits;
1577 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1578 __generate_switch(__begin, __end, __gen, _IteratorCategory());
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_P::generate_n(__begin, __n, __gen); }
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,
1595 { return generate_n(__begin, __n, __gen,
1596 __gnu_parallel::sequential_tag()); }
1598 // Parallel algorithm for random access iterators.
1599 template<typename _RAIter, typename _Size, typename _Generator>
1601 __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen,
1602 random_access_iterator_tag,
1603 __gnu_parallel::_Parallelism __parallelism_tag
1604 = __gnu_parallel::parallel_balanced)
1606 // XXX parallel version is where?
1607 return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
1610 // Public interface.
1611 template<typename _OutputIterator, typename _Size, typename _Generator>
1612 inline _OutputIterator
1613 generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
1614 __gnu_parallel::_Parallelism __parallelism_tag)
1616 typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
1617 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1618 return __generate_n_switch(__begin, __n, __gen, _IteratorCategory(),
1622 template<typename _OutputIterator, typename _Size, typename _Generator>
1623 inline _OutputIterator
1624 generate_n(_OutputIterator __begin, _Size __n, _Generator __gen)
1626 typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
1627 typedef typename _IteratorTraits::iterator_category _IteratorCategory;
1628 return __generate_n_switch(__begin, __n, __gen, _IteratorCategory());
1632 // Sequential fallback.
1633 template<typename _RAIter>
1635 random_shuffle(_RAIter __begin, _RAIter __end,
1636 __gnu_parallel::sequential_tag)
1637 { _GLIBCXX_STD_P::random_shuffle(__begin, __end); }
1639 // Sequential fallback.
1640 template<typename _RAIter, typename _RandomNumberGenerator>
1642 random_shuffle(_RAIter __begin, _RAIter __end,
1643 _RandomNumberGenerator& __rand,
1644 __gnu_parallel::sequential_tag)
1645 { _GLIBCXX_STD_P::random_shuffle(__begin, __end, __rand); }
1648 /** @brief Functor wrapper for std::rand(). */
1649 template<typename _MustBeInt = int>
1653 operator()(int __limit)
1654 { return rand() % __limit; }
1657 // Fill in random number generator.
1658 template<typename _RAIter>
1660 random_shuffle(_RAIter __begin, _RAIter __end)
1663 // Parallelization still possible.
1664 __gnu_parallel::random_shuffle(__begin, __end, __r);
1667 // Parallel algorithm for random access iterators.
1668 template<typename _RAIter, typename _RandomNumberGenerator>
1670 random_shuffle(_RAIter __begin, _RAIter __end,
1671 _RandomNumberGenerator& __rand)
1673 if (__begin == __end)
1675 if (_GLIBCXX_PARALLEL_CONDITION(
1676 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1677 >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
1678 __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
1680 __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
1683 // Sequential fallback.
1684 template<typename _FIterator, typename _Predicate>
1686 partition(_FIterator __begin, _FIterator __end,
1687 _Predicate __pred, __gnu_parallel::sequential_tag)
1688 { return _GLIBCXX_STD_P::partition(__begin, __end, __pred); }
1690 // Sequential fallback for input iterator case.
1691 template<typename _FIterator, typename _Predicate, typename _IteratorTag>
1693 __partition_switch(_FIterator __begin, _FIterator __end,
1694 _Predicate __pred, _IteratorTag)
1695 { return partition(__begin, __end, __pred,
1696 __gnu_parallel::sequential_tag()); }
1698 // Parallel algorithm for random access iterators.
1699 template<typename _RAIter, typename _Predicate>
1701 __partition_switch(_RAIter __begin, _RAIter __end,
1702 _Predicate __pred, random_access_iterator_tag)
1704 if (_GLIBCXX_PARALLEL_CONDITION(
1705 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1706 >= __gnu_parallel::_Settings::get().partition_minimal_n))
1708 typedef typename std::iterator_traits<_RAIter>::
1709 difference_type _DifferenceType;
1710 _DifferenceType __middle = __gnu_parallel::
1711 __parallel_partition(__begin, __end, __pred,
1712 __gnu_parallel::__get_max_threads());
1713 return __begin + __middle;
1716 return partition(__begin, __end, __pred,
1717 __gnu_parallel::sequential_tag());
1720 // Public interface.
1721 template<typename _FIterator, typename _Predicate>
1723 partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
1725 typedef iterator_traits<_FIterator> _TraitsType;
1726 typedef typename _TraitsType::iterator_category _IteratorCategory;
1727 return __partition_switch(__begin, __end, __pred, _IteratorCategory());
1732 // Sequential fallback
1733 template<typename _RAIter>
1735 sort(_RAIter __begin, _RAIter __end,
1736 __gnu_parallel::sequential_tag)
1737 { _GLIBCXX_STD_P::sort(__begin, __end); }
1739 // Sequential fallback
1740 template<typename _RAIter, typename _Compare>
1742 sort(_RAIter __begin, _RAIter __end, _Compare __comp,
1743 __gnu_parallel::sequential_tag)
1744 { _GLIBCXX_STD_P::sort<_RAIter, _Compare>(__begin, __end,
1748 template<typename _RAIter, typename _Compare,
1749 typename _Parallelism>
1751 sort(_RAIter __begin, _RAIter __end, _Compare __comp,
1752 _Parallelism __parallelism)
1754 typedef iterator_traits<_RAIter> _TraitsType;
1755 typedef typename _TraitsType::value_type _ValueType;
1757 if (__begin != __end)
1759 if (_GLIBCXX_PARALLEL_CONDITION(
1760 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
1761 __gnu_parallel::_Settings::get().sort_minimal_n))
1762 __gnu_parallel::__parallel_sort<false>(
1763 __begin, __end, __comp, __parallelism);
1765 sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
1769 // Public interface, insert default comparator
1770 template<typename _RAIter>
1772 sort(_RAIter __begin, _RAIter __end)
1774 typedef iterator_traits<_RAIter> _TraitsType;
1775 typedef typename _TraitsType::value_type _ValueType;
1776 sort(__begin, __end, std::less<_ValueType>(),
1777 __gnu_parallel::default_parallel_tag());
1780 // Public interface, insert default comparator
1781 template<typename _RAIter>
1783 sort(_RAIter __begin, _RAIter __end,
1784 __gnu_parallel::default_parallel_tag __parallelism)
1786 typedef iterator_traits<_RAIter> _TraitsType;
1787 typedef typename _TraitsType::value_type _ValueType;
1788 sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1791 // Public interface, insert default comparator
1792 template<typename _RAIter>
1794 sort(_RAIter __begin, _RAIter __end,
1795 __gnu_parallel::parallel_tag __parallelism)
1797 typedef iterator_traits<_RAIter> _TraitsType;
1798 typedef typename _TraitsType::value_type _ValueType;
1799 sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1802 // Public interface, insert default comparator
1803 template<typename _RAIter>
1805 sort(_RAIter __begin, _RAIter __end,
1806 __gnu_parallel::multiway_mergesort_tag __parallelism)
1808 typedef iterator_traits<_RAIter> _TraitsType;
1809 typedef typename _TraitsType::value_type _ValueType;
1810 sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1813 // Public interface, insert default comparator
1814 template<typename _RAIter>
1816 sort(_RAIter __begin, _RAIter __end,
1817 __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
1819 typedef iterator_traits<_RAIter> _TraitsType;
1820 typedef typename _TraitsType::value_type _ValueType;
1821 sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1824 // Public interface, insert default comparator
1825 template<typename _RAIter>
1827 sort(_RAIter __begin, _RAIter __end,
1828 __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
1830 typedef iterator_traits<_RAIter> _TraitsType;
1831 typedef typename _TraitsType::value_type _ValueType;
1832 sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1835 // Public interface, insert default comparator
1836 template<typename _RAIter>
1838 sort(_RAIter __begin, _RAIter __end,
1839 __gnu_parallel::quicksort_tag __parallelism)
1841 typedef iterator_traits<_RAIter> _TraitsType;
1842 typedef typename _TraitsType::value_type _ValueType;
1843 sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1846 // Public interface, insert default comparator
1847 template<typename _RAIter>
1849 sort(_RAIter __begin, _RAIter __end,
1850 __gnu_parallel::balanced_quicksort_tag __parallelism)
1852 typedef iterator_traits<_RAIter> _TraitsType;
1853 typedef typename _TraitsType::value_type _ValueType;
1854 sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1858 template<typename _RAIter, typename _Compare>
1860 sort(_RAIter __begin, _RAIter __end, _Compare __comp)
1862 typedef iterator_traits<_RAIter> _TraitsType;
1863 typedef typename _TraitsType::value_type _ValueType;
1864 sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
1868 // stable_sort interface
1871 // Sequential fallback
1872 template<typename _RAIter>
1874 stable_sort(_RAIter __begin, _RAIter __end,
1875 __gnu_parallel::sequential_tag)
1876 { _GLIBCXX_STD_P::stable_sort(__begin, __end); }
1878 // Sequential fallback
1879 template<typename _RAIter, typename _Compare>
1881 stable_sort(_RAIter __begin, _RAIter __end,
1882 _Compare __comp, __gnu_parallel::sequential_tag)
1883 { _GLIBCXX_STD_P::stable_sort<_RAIter, _Compare>(
1884 __begin, __end, __comp); }
1887 template<typename _RAIter, typename _Compare,
1888 typename _Parallelism>
1890 stable_sort(_RAIter __begin, _RAIter __end,
1891 _Compare __comp, _Parallelism __parallelism)
1893 typedef iterator_traits<_RAIter> _TraitsType;
1894 typedef typename _TraitsType::value_type _ValueType;
1896 if (__begin != __end)
1898 if (_GLIBCXX_PARALLEL_CONDITION(
1899 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
1900 __gnu_parallel::_Settings::get().sort_minimal_n))
1901 __gnu_parallel::__parallel_sort<true>(
1902 __begin, __end, __comp, __parallelism);
1904 stable_sort(__begin, __end, __comp,
1905 __gnu_parallel::sequential_tag());
1909 // Public interface, insert default comparator
1910 template<typename _RAIter>
1912 stable_sort(_RAIter __begin, _RAIter __end)
1914 typedef iterator_traits<_RAIter> _TraitsType;
1915 typedef typename _TraitsType::value_type _ValueType;
1916 stable_sort(__begin, __end, std::less<_ValueType>(),
1917 __gnu_parallel::default_parallel_tag());
1920 // Public interface, insert default comparator
1921 template<typename _RAIter>
1923 stable_sort(_RAIter __begin, _RAIter __end,
1924 __gnu_parallel::default_parallel_tag __parallelism)
1926 typedef iterator_traits<_RAIter> _TraitsType;
1927 typedef typename _TraitsType::value_type _ValueType;
1928 stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1931 // Public interface, insert default comparator
1932 template<typename _RAIter>
1934 stable_sort(_RAIter __begin, _RAIter __end,
1935 __gnu_parallel::parallel_tag __parallelism)
1937 typedef iterator_traits<_RAIter> _TraitsType;
1938 typedef typename _TraitsType::value_type _ValueType;
1939 stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1942 // Public interface, insert default comparator
1943 template<typename _RAIter>
1945 stable_sort(_RAIter __begin, _RAIter __end,
1946 __gnu_parallel::multiway_mergesort_tag __parallelism)
1948 typedef iterator_traits<_RAIter> _TraitsType;
1949 typedef typename _TraitsType::value_type _ValueType;
1950 stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1953 // Public interface, insert default comparator
1954 template<typename _RAIter>
1956 stable_sort(_RAIter __begin, _RAIter __end,
1957 __gnu_parallel::quicksort_tag __parallelism)
1959 typedef iterator_traits<_RAIter> _TraitsType;
1960 typedef typename _TraitsType::value_type _ValueType;
1961 stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1964 // Public interface, insert default comparator
1965 template<typename _RAIter>
1967 stable_sort(_RAIter __begin, _RAIter __end,
1968 __gnu_parallel::balanced_quicksort_tag __parallelism)
1970 typedef iterator_traits<_RAIter> _TraitsType;
1971 typedef typename _TraitsType::value_type _ValueType;
1972 stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1976 template<typename _RAIter, typename _Compare>
1978 stable_sort(_RAIter __begin, _RAIter __end,
1981 typedef iterator_traits<_RAIter> _TraitsType;
1982 typedef typename _TraitsType::value_type _ValueType;
1984 __begin, __end, __comp, __gnu_parallel::default_parallel_tag());
1987 // Sequential fallback
1988 template<typename _IIter1, typename _IIter2,
1989 typename _OutputIterator>
1990 inline _OutputIterator
1991 merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
1992 _IIter2 __end2, _OutputIterator __result,
1993 __gnu_parallel::sequential_tag)
1994 { return _GLIBCXX_STD_P::merge(
1995 __begin1, __end1, __begin2, __end2, __result); }
1997 // Sequential fallback
1998 template<typename _IIter1, typename _IIter2,
1999 typename _OutputIterator, typename _Compare>
2000 inline _OutputIterator
2001 merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
2002 _IIter2 __end2, _OutputIterator __result, _Compare __comp,
2003 __gnu_parallel::sequential_tag)
2004 { return _GLIBCXX_STD_P::merge(
2005 __begin1, __end1, __begin2, __end2, __result, __comp); }
2007 // Sequential fallback for input iterator case
2008 template<typename _IIter1, typename _IIter2, typename _OutputIterator,
2009 typename _Compare, typename _IteratorTag1,
2010 typename _IteratorTag2, typename _IteratorTag3>
2011 inline _OutputIterator
2012 __merge_switch(_IIter1 __begin1, _IIter1 __end1,
2013 _IIter2 __begin2, _IIter2 __end2,
2014 _OutputIterator __result, _Compare __comp,
2015 _IteratorTag1, _IteratorTag2, _IteratorTag3)
2016 { return _GLIBCXX_STD_P::merge(__begin1, __end1, __begin2, __end2,
2017 __result, __comp); }
2019 // Parallel algorithm for random access iterators
2020 template<typename _IIter1, typename _IIter2,
2021 typename _OutputIterator, typename _Compare>
2023 __merge_switch(_IIter1 __begin1, _IIter1 __end1,
2024 _IIter2 __begin2, _IIter2 __end2,
2025 _OutputIterator __result, _Compare __comp,
2026 random_access_iterator_tag, random_access_iterator_tag,
2027 random_access_iterator_tag)
2029 if (_GLIBCXX_PARALLEL_CONDITION(
2030 (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
2031 >= __gnu_parallel::_Settings::get().merge_minimal_n
2032 || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
2033 >= __gnu_parallel::_Settings::get().merge_minimal_n)))
2034 return __gnu_parallel::__parallel_merge_advance(
2035 __begin1, __end1, __begin2, __end2, __result,
2036 (__end1 - __begin1) + (__end2 - __begin2), __comp);
2038 return __gnu_parallel::__merge_advance(
2039 __begin1, __end1, __begin2, __end2, __result,
2040 (__end1 - __begin1) + (__end2 - __begin2), __comp);
2044 template<typename _IIter1, typename _IIter2,
2045 typename _OutputIterator, typename _Compare>
2046 inline _OutputIterator
2047 merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
2048 _IIter2 __end2, _OutputIterator __result, _Compare __comp)
2050 typedef typename iterator_traits<_IIter1>::value_type _ValueType;
2052 typedef std::iterator_traits<_IIter1> _IIterTraits1;
2053 typedef std::iterator_traits<_IIter2> _IIterTraits2;
2054 typedef std::iterator_traits<_OutputIterator> _OIterTraits;
2055 typedef typename _IIterTraits1::iterator_category
2057 typedef typename _IIterTraits2::iterator_category
2059 typedef typename _OIterTraits::iterator_category _OIterCategory;
2061 return __merge_switch(
2062 __begin1, __end1, __begin2, __end2, __result, __comp,
2063 _IIterCategory1(), _IIterCategory2(), _OIterCategory());
2067 // Public interface, insert default comparator
2068 template<typename _IIter1, typename _IIter2,
2069 typename _OutputIterator>
2070 inline _OutputIterator
2071 merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
2072 _IIter2 __end2, _OutputIterator __result)
2074 typedef std::iterator_traits<_IIter1> _Iterator1Traits;
2075 typedef std::iterator_traits<_IIter2> _Iterator2Traits;
2076 typedef typename _Iterator1Traits::value_type _ValueType1;
2077 typedef typename _Iterator2Traits::value_type _ValueType2;
2079 return merge(__begin1, __end1, __begin2, __end2, __result,
2080 __gnu_parallel::_Less<_ValueType1, _ValueType2>());
2083 // Sequential fallback
2084 template<typename _RAIter>
2086 nth_element(_RAIter __begin, _RAIter __nth,
2087 _RAIter __end, __gnu_parallel::sequential_tag)
2088 { return _GLIBCXX_STD_P::nth_element(__begin, __nth, __end); }
2090 // Sequential fallback
2091 template<typename _RAIter, typename _Compare>
2093 nth_element(_RAIter __begin, _RAIter __nth,
2094 _RAIter __end, _Compare __comp,
2095 __gnu_parallel::sequential_tag)
2096 { return _GLIBCXX_STD_P::nth_element(__begin, __nth, __end, __comp); }
2099 template<typename _RAIter, typename _Compare>
2101 nth_element(_RAIter __begin, _RAIter __nth,
2102 _RAIter __end, _Compare __comp)
2104 if (_GLIBCXX_PARALLEL_CONDITION(
2105 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2106 >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
2107 __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
2109 nth_element(__begin, __nth, __end, __comp,
2110 __gnu_parallel::sequential_tag());
2113 // Public interface, insert default comparator
2114 template<typename _RAIter>
2116 nth_element(_RAIter __begin, _RAIter __nth,
2119 typedef iterator_traits<_RAIter> _TraitsType;
2120 typedef typename _TraitsType::value_type _ValueType;
2121 nth_element(__begin, __nth, __end, std::less<_ValueType>());
2124 // Sequential fallback
2125 template<typename _RAIter, typename _Compare>
2127 partial_sort(_RAIter __begin, _RAIter __middle,
2128 _RAIter __end, _Compare __comp,
2129 __gnu_parallel::sequential_tag)
2130 { _GLIBCXX_STD_P::partial_sort(__begin, __middle, __end, __comp); }
2132 // Sequential fallback
2133 template<typename _RAIter>
2135 partial_sort(_RAIter __begin, _RAIter __middle,
2136 _RAIter __end, __gnu_parallel::sequential_tag)
2137 { _GLIBCXX_STD_P::partial_sort(__begin, __middle, __end); }
2139 // Public interface, parallel algorithm for random access iterators
2140 template<typename _RAIter, typename _Compare>
2142 partial_sort(_RAIter __begin, _RAIter __middle,
2143 _RAIter __end, _Compare __comp)
2145 if (_GLIBCXX_PARALLEL_CONDITION(
2146 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2147 >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
2149 __parallel_partial_sort(__begin, __middle, __end, __comp);
2151 partial_sort(__begin, __middle, __end, __comp,
2152 __gnu_parallel::sequential_tag());
2155 // Public interface, insert default comparator
2156 template<typename _RAIter>
2158 partial_sort(_RAIter __begin, _RAIter __middle,
2161 typedef iterator_traits<_RAIter> _TraitsType;
2162 typedef typename _TraitsType::value_type _ValueType;
2163 partial_sort(__begin, __middle, __end, std::less<_ValueType>());
2166 // Sequential fallback
2167 template<typename _FIterator>
2169 max_element(_FIterator __begin, _FIterator __end,
2170 __gnu_parallel::sequential_tag)
2171 { return _GLIBCXX_STD_P::max_element(__begin, __end); }
2173 // Sequential fallback
2174 template<typename _FIterator, typename _Compare>
2176 max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2177 __gnu_parallel::sequential_tag)
2178 { return _GLIBCXX_STD_P::max_element(__begin, __end, __comp); }
2180 // Sequential fallback for input iterator case
2181 template<typename _FIterator, typename _Compare, typename _IteratorTag>
2183 __max_element_switch(_FIterator __begin, _FIterator __end,
2184 _Compare __comp, _IteratorTag)
2185 { return max_element(__begin, __end, __comp,
2186 __gnu_parallel::sequential_tag()); }
2188 // Parallel algorithm for random access iterators
2189 template<typename _RAIter, typename _Compare>
2191 __max_element_switch(_RAIter __begin, _RAIter __end,
2192 _Compare __comp, random_access_iterator_tag,
2193 __gnu_parallel::_Parallelism __parallelism_tag
2194 = __gnu_parallel::parallel_balanced)
2196 if (_GLIBCXX_PARALLEL_CONDITION(
2197 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2198 >= __gnu_parallel::_Settings::get().max_element_minimal_n
2199 && __gnu_parallel::__is_parallel(__parallelism_tag)))
2201 _RAIter __res(__begin);
2202 __gnu_parallel::__identity_selector<_RAIter>
2205 __for_each_template_random_access(
2206 __begin, __end, __gnu_parallel::_Nothing(), __functionality,
2207 __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
2208 __res, __res, -1, __parallelism_tag);
2212 return max_element(__begin, __end, __comp,
2213 __gnu_parallel::sequential_tag());
2216 // Public interface, insert default comparator
2217 template<typename _FIterator>
2219 max_element(_FIterator __begin, _FIterator __end,
2220 __gnu_parallel::_Parallelism __parallelism_tag)
2222 typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2223 return max_element(__begin, __end, std::less<_ValueType>(),
2227 template<typename _FIterator>
2229 max_element(_FIterator __begin, _FIterator __end)
2231 typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2232 return max_element(__begin, __end, std::less<_ValueType>());
2236 template<typename _FIterator, typename _Compare>
2238 max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2239 __gnu_parallel::_Parallelism __parallelism_tag)
2241 typedef iterator_traits<_FIterator> _TraitsType;
2242 typedef typename _TraitsType::iterator_category _IteratorCategory;
2243 return __max_element_switch(__begin, __end, __comp, _IteratorCategory(),
2247 template<typename _FIterator, typename _Compare>
2249 max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
2251 typedef iterator_traits<_FIterator> _TraitsType;
2252 typedef typename _TraitsType::iterator_category _IteratorCategory;
2253 return __max_element_switch(__begin, __end, __comp, _IteratorCategory());
2257 // Sequential fallback
2258 template<typename _FIterator>
2260 min_element(_FIterator __begin, _FIterator __end,
2261 __gnu_parallel::sequential_tag)
2262 { return _GLIBCXX_STD_P::min_element(__begin, __end); }
2264 // Sequential fallback
2265 template<typename _FIterator, typename _Compare>
2267 min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2268 __gnu_parallel::sequential_tag)
2269 { return _GLIBCXX_STD_P::min_element(__begin, __end, __comp); }
2271 // Sequential fallback for input iterator case
2272 template<typename _FIterator, typename _Compare, typename _IteratorTag>
2274 __min_element_switch(_FIterator __begin, _FIterator __end,
2275 _Compare __comp, _IteratorTag)
2276 { return min_element(__begin, __end, __comp,
2277 __gnu_parallel::sequential_tag()); }
2279 // Parallel algorithm for random access iterators
2280 template<typename _RAIter, typename _Compare>
2282 __min_element_switch(_RAIter __begin, _RAIter __end,
2283 _Compare __comp, random_access_iterator_tag,
2284 __gnu_parallel::_Parallelism __parallelism_tag
2285 = __gnu_parallel::parallel_balanced)
2287 if (_GLIBCXX_PARALLEL_CONDITION(
2288 static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2289 >= __gnu_parallel::_Settings::get().min_element_minimal_n
2290 && __gnu_parallel::__is_parallel(__parallelism_tag)))
2292 _RAIter __res(__begin);
2293 __gnu_parallel::__identity_selector<_RAIter>
2296 __for_each_template_random_access(
2297 __begin, __end, __gnu_parallel::_Nothing(), __functionality,
2298 __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
2299 __res, __res, -1, __parallelism_tag);
2303 return min_element(__begin, __end, __comp,
2304 __gnu_parallel::sequential_tag());
2307 // Public interface, insert default comparator
2308 template<typename _FIterator>
2310 min_element(_FIterator __begin, _FIterator __end,
2311 __gnu_parallel::_Parallelism __parallelism_tag)
2313 typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2314 return min_element(__begin, __end, std::less<_ValueType>(),
2318 template<typename _FIterator>
2320 min_element(_FIterator __begin, _FIterator __end)
2322 typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2323 return min_element(__begin, __end, std::less<_ValueType>());
2327 template<typename _FIterator, typename _Compare>
2329 min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2330 __gnu_parallel::_Parallelism __parallelism_tag)
2332 typedef iterator_traits<_FIterator> _TraitsType;
2333 typedef typename _TraitsType::iterator_category _IteratorCategory;
2334 return __min_element_switch(__begin, __end, __comp, _IteratorCategory(),
2338 template<typename _FIterator, typename _Compare>
2340 min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
2342 typedef iterator_traits<_FIterator> _TraitsType;
2343 typedef typename _TraitsType::iterator_category _IteratorCategory;
2344 return __min_element_switch(__begin, __end, __comp, _IteratorCategory());
2349 #endif /* _GLIBCXX_PARALLEL_ALGO_H */