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 InputIterator, typename Function>
68 for_each(InputIterator begin, InputIterator 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 InputIterator, typename Function, typename IteratorTag>
76 for_each_switch(InputIterator begin, InputIterator end, Function f,
78 { return for_each(begin, end, f, __gnu_parallel::sequential_tag()); }
80 // Parallel algorithm for random access iterators
81 template<typename RandomAccessIterator, typename Function>
83 for_each_switch(RandomAccessIterator begin, RandomAccessIterator 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::sequence_index_t>(end - begin)
90 >= __gnu_parallel::_Settings::get().for_each_minimal_n
91 && __gnu_parallel::is_parallel(parallelism_tag)))
94 __gnu_parallel::for_each_selector<RandomAccessIterator> functionality;
96 return __gnu_parallel::
97 for_each_template_random_access(begin, end, f, functionality,
98 __gnu_parallel::dummy_reduct(),
99 true, dummy, -1, parallelism_tag);
102 return for_each(begin, end, f, __gnu_parallel::sequential_tag());
106 template<typename Iterator, typename Function>
108 for_each(Iterator begin, Iterator end, Function f,
109 __gnu_parallel::_Parallelism parallelism_tag)
111 typedef std::iterator_traits<Iterator> iterator_traits;
112 typedef typename iterator_traits::iterator_category iterator_category;
113 return for_each_switch(begin, end, f, iterator_category(),
117 template<typename Iterator, typename Function>
119 for_each(Iterator begin, Iterator end, Function f)
121 typedef std::iterator_traits<Iterator> iterator_traits;
122 typedef typename iterator_traits::iterator_category iterator_category;
123 return for_each_switch(begin, end, f, iterator_category());
127 // Sequential fallback
128 template<typename InputIterator, typename T>
130 find(InputIterator begin, InputIterator end, const T& val,
131 __gnu_parallel::sequential_tag)
132 { return _GLIBCXX_STD_P::find(begin, end, val); }
134 // Sequential fallback for input iterator case
135 template<typename InputIterator, typename T, typename IteratorTag>
137 find_switch(InputIterator begin, InputIterator end, const T& val,
139 { return _GLIBCXX_STD_P::find(begin, end, val); }
141 // Parallel find for random access iterators
142 template<typename RandomAccessIterator, typename T>
144 find_switch(RandomAccessIterator begin, RandomAccessIterator end,
145 const T& val, random_access_iterator_tag)
147 typedef iterator_traits<RandomAccessIterator> traits_type;
148 typedef typename traits_type::value_type value_type;
150 if (_GLIBCXX_PARALLEL_CONDITION(true))
152 binder2nd<__gnu_parallel::equal_to<value_type, const T&> >
153 comp(__gnu_parallel::equal_to<value_type, const T&>(), val);
154 return __gnu_parallel::find_template(begin, end, begin, comp,
156 find_if_selector()).first;
159 return _GLIBCXX_STD_P::find(begin, end, val);
163 template<typename InputIterator, typename T>
165 find(InputIterator begin, InputIterator end, const T& val)
167 typedef std::iterator_traits<InputIterator> iterator_traits;
168 typedef typename iterator_traits::iterator_category iterator_category;
169 return find_switch(begin, end, val, iterator_category());
172 // Sequential fallback
173 template<typename InputIterator, typename Predicate>
175 find_if(InputIterator begin, InputIterator end, Predicate pred,
176 __gnu_parallel::sequential_tag)
177 { return _GLIBCXX_STD_P::find_if(begin, end, pred); }
179 // Sequential fallback for input iterator case
180 template<typename InputIterator, typename Predicate, typename IteratorTag>
182 find_if_switch(InputIterator begin, InputIterator end, Predicate pred,
184 { return _GLIBCXX_STD_P::find_if(begin, end, pred); }
186 // Parallel find_if for random access iterators
187 template<typename RandomAccessIterator, typename Predicate>
189 find_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
190 Predicate pred, random_access_iterator_tag)
192 if (_GLIBCXX_PARALLEL_CONDITION(true))
193 return __gnu_parallel::find_template(begin, end, begin, pred,
195 find_if_selector()).first;
197 return _GLIBCXX_STD_P::find_if(begin, end, pred);
201 template<typename InputIterator, typename Predicate>
203 find_if(InputIterator begin, InputIterator end, Predicate pred)
205 typedef std::iterator_traits<InputIterator> iterator_traits;
206 typedef typename iterator_traits::iterator_category iterator_category;
207 return find_if_switch(begin, end, pred, iterator_category());
210 // Sequential fallback
211 template<typename InputIterator, typename ForwardIterator>
213 find_first_of(InputIterator begin1, InputIterator end1,
214 ForwardIterator begin2, ForwardIterator end2,
215 __gnu_parallel::sequential_tag)
216 { return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2); }
218 // Sequential fallback
219 template<typename InputIterator, typename ForwardIterator,
220 typename BinaryPredicate>
222 find_first_of(InputIterator begin1, InputIterator end1,
223 ForwardIterator begin2, ForwardIterator end2,
224 BinaryPredicate comp, __gnu_parallel::sequential_tag)
225 { return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2, comp); }
227 // Sequential fallback for input iterator type
228 template<typename InputIterator, typename ForwardIterator,
229 typename IteratorTag1, typename IteratorTag2>
231 find_first_of_switch(InputIterator begin1, InputIterator end1,
232 ForwardIterator begin2, ForwardIterator end2,
233 IteratorTag1, IteratorTag2)
234 { return find_first_of(begin1, end1, begin2, end2,
235 __gnu_parallel::sequential_tag()); }
237 // Parallel algorithm for random access iterators
238 template<typename RandomAccessIterator, typename ForwardIterator,
239 typename BinaryPredicate, typename IteratorTag>
240 inline RandomAccessIterator
241 find_first_of_switch(RandomAccessIterator begin1,
242 RandomAccessIterator end1,
243 ForwardIterator begin2, ForwardIterator end2,
244 BinaryPredicate comp, random_access_iterator_tag,
247 return __gnu_parallel::
248 find_template(begin1, end1, begin1, comp,
249 __gnu_parallel::find_first_of_selector
250 <ForwardIterator>(begin2, end2)).first;
253 // Sequential fallback for input iterator type
254 template<typename InputIterator, typename ForwardIterator,
255 typename BinaryPredicate, typename IteratorTag1,
256 typename IteratorTag2>
258 find_first_of_switch(InputIterator begin1, InputIterator end1,
259 ForwardIterator begin2, ForwardIterator end2,
260 BinaryPredicate comp, IteratorTag1, IteratorTag2)
261 { return find_first_of(begin1, end1, begin2, end2, comp,
262 __gnu_parallel::sequential_tag()); }
265 template<typename InputIterator, typename ForwardIterator,
266 typename BinaryPredicate>
268 find_first_of(InputIterator begin1, InputIterator end1,
269 ForwardIterator begin2, ForwardIterator end2,
270 BinaryPredicate comp)
272 typedef std::iterator_traits<InputIterator> iteratori_traits;
273 typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
274 typedef typename iteratori_traits::iterator_category iteratori_category;
275 typedef typename iteratorf_traits::iterator_category iteratorf_category;
277 return find_first_of_switch(begin1, end1, begin2, end2, comp,
278 iteratori_category(), iteratorf_category());
281 // Public interface, insert default comparator
282 template<typename InputIterator, typename ForwardIterator>
284 find_first_of(InputIterator begin1, InputIterator end1,
285 ForwardIterator begin2, ForwardIterator end2)
287 typedef std::iterator_traits<InputIterator> iteratori_traits;
288 typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
289 typedef typename iteratori_traits::value_type valuei_type;
290 typedef typename iteratorf_traits::value_type valuef_type;
292 return find_first_of(begin1, end1, begin2, end2, __gnu_parallel::
293 equal_to<valuei_type, valuef_type>());
296 // Sequential fallback
297 template<typename InputIterator, typename OutputIterator>
298 inline OutputIterator
299 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
300 __gnu_parallel::sequential_tag)
301 { return _GLIBCXX_STD_P::unique_copy(begin1, end1, out); }
303 // Sequential fallback
304 template<typename InputIterator, typename OutputIterator,
306 inline OutputIterator
307 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
308 Predicate pred, __gnu_parallel::sequential_tag)
309 { return _GLIBCXX_STD_P::unique_copy(begin1, end1, out, pred); }
311 // Sequential fallback for input iterator case
312 template<typename InputIterator, typename OutputIterator,
313 typename Predicate, typename IteratorTag1, typename IteratorTag2>
314 inline OutputIterator
315 unique_copy_switch(InputIterator begin, InputIterator last,
316 OutputIterator out, Predicate pred,
317 IteratorTag1, IteratorTag2)
318 { return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred); }
320 // Parallel unique_copy for random access iterators
321 template<typename RandomAccessIterator, typename RandomAccessOutputIterator,
323 RandomAccessOutputIterator
324 unique_copy_switch(RandomAccessIterator begin, RandomAccessIterator last,
325 RandomAccessOutputIterator out, Predicate pred,
326 random_access_iterator_tag, random_access_iterator_tag)
328 if (_GLIBCXX_PARALLEL_CONDITION(
329 static_cast<__gnu_parallel::sequence_index_t>(last - begin)
330 > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
331 return __gnu_parallel::parallel_unique_copy(begin, last, out, pred);
333 return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred);
337 template<typename InputIterator, typename OutputIterator>
338 inline OutputIterator
339 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out)
341 typedef std::iterator_traits<InputIterator> iteratori_traits;
342 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
343 typedef typename iteratori_traits::iterator_category iteratori_category;
344 typedef typename iteratori_traits::value_type value_type;
345 typedef typename iteratoro_traits::iterator_category iteratoro_category;
347 return unique_copy_switch(begin1, end1, out, equal_to<value_type>(),
348 iteratori_category(), iteratoro_category());
352 template<typename InputIterator, typename OutputIterator, typename Predicate>
353 inline OutputIterator
354 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
357 typedef std::iterator_traits<InputIterator> iteratori_traits;
358 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
359 typedef typename iteratori_traits::iterator_category iteratori_category;
360 typedef typename iteratoro_traits::iterator_category iteratoro_category;
362 return unique_copy_switch(begin1, end1, out, pred, iteratori_category(),
363 iteratoro_category());
366 // Sequential fallback
367 template<typename InputIterator1, typename InputIterator2,
368 typename OutputIterator>
369 inline OutputIterator
370 set_union(InputIterator1 begin1, InputIterator1 end1,
371 InputIterator2 begin2, InputIterator2 end2,
372 OutputIterator out, __gnu_parallel::sequential_tag)
373 { return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, out); }
375 // Sequential fallback
376 template<typename InputIterator1, typename InputIterator2,
377 typename OutputIterator, typename Predicate>
378 inline OutputIterator
379 set_union(InputIterator1 begin1, InputIterator1 end1,
380 InputIterator2 begin2, InputIterator2 end2,
381 OutputIterator out, Predicate pred,
382 __gnu_parallel::sequential_tag)
383 { return _GLIBCXX_STD_P::set_union(begin1, end1,
384 begin2, end2, out, pred); }
386 // Sequential fallback for input iterator case
387 template<typename InputIterator1, typename InputIterator2,
388 typename Predicate, typename OutputIterator,
389 typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
390 inline OutputIterator
391 set_union_switch(InputIterator1 begin1, InputIterator1 end1,
392 InputIterator2 begin2, InputIterator2 end2,
393 OutputIterator result, Predicate pred, IteratorTag1,
394 IteratorTag2, IteratorTag3)
395 { return _GLIBCXX_STD_P::set_union(begin1, end1,
396 begin2, end2, result, pred); }
398 // Parallel set_union for random access iterators
399 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
400 typename OutputRandomAccessIterator, typename Predicate>
401 OutputRandomAccessIterator
402 set_union_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
403 RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
404 OutputRandomAccessIterator result, Predicate pred,
405 random_access_iterator_tag, random_access_iterator_tag,
406 random_access_iterator_tag)
408 if (_GLIBCXX_PARALLEL_CONDITION(
409 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
410 >= __gnu_parallel::_Settings::get().set_union_minimal_n
411 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
412 >= __gnu_parallel::_Settings::get().set_union_minimal_n))
413 return __gnu_parallel::parallel_set_union(begin1, end1,
414 begin2, end2, result, pred);
416 return _GLIBCXX_STD_P::set_union(begin1, end1,
417 begin2, end2, result, pred);
421 template<typename InputIterator1, typename InputIterator2,
422 typename OutputIterator>
423 inline OutputIterator
424 set_union(InputIterator1 begin1, InputIterator1 end1,
425 InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
427 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
428 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
429 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
430 typedef typename iteratori1_traits::iterator_category
432 typedef typename iteratori2_traits::iterator_category
434 typedef typename iteratoro_traits::iterator_category iteratoro_category;
435 typedef typename iteratori1_traits::value_type value1_type;
436 typedef typename iteratori2_traits::value_type value2_type;
438 return set_union_switch(begin1, end1, begin2, end2, out,
439 __gnu_parallel::less<value1_type, value2_type>(),
440 iteratori1_category(), iteratori2_category(),
441 iteratoro_category());
445 template<typename InputIterator1, typename InputIterator2,
446 typename OutputIterator, typename Predicate>
447 inline OutputIterator
448 set_union(InputIterator1 begin1, InputIterator1 end1,
449 InputIterator2 begin2, InputIterator2 end2,
450 OutputIterator out, Predicate pred)
452 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
453 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
454 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
455 typedef typename iteratori1_traits::iterator_category
457 typedef typename iteratori2_traits::iterator_category
459 typedef typename iteratoro_traits::iterator_category iteratoro_category;
461 return set_union_switch(begin1, end1, begin2, end2, out, pred,
462 iteratori1_category(), iteratori2_category(),
463 iteratoro_category());
466 // Sequential fallback.
467 template<typename InputIterator1, typename InputIterator2,
468 typename OutputIterator>
469 inline OutputIterator
470 set_intersection(InputIterator1 begin1, InputIterator1 end1,
471 InputIterator2 begin2, InputIterator2 end2,
472 OutputIterator out, __gnu_parallel::sequential_tag)
473 { return _GLIBCXX_STD_P::set_intersection(begin1, end1,
474 begin2, end2, out); }
476 // Sequential fallback.
477 template<typename InputIterator1, typename InputIterator2,
478 typename OutputIterator, typename Predicate>
479 inline OutputIterator
480 set_intersection(InputIterator1 begin1, InputIterator1 end1,
481 InputIterator2 begin2, InputIterator2 end2,
482 OutputIterator out, Predicate pred,
483 __gnu_parallel::sequential_tag)
484 { return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2, end2,
487 // Sequential fallback for input iterator case
488 template<typename InputIterator1, typename InputIterator2,
489 typename Predicate, typename OutputIterator,
490 typename IteratorTag1, typename IteratorTag2,
491 typename IteratorTag3>
492 inline OutputIterator
493 set_intersection_switch(InputIterator1 begin1, InputIterator1 end1,
494 InputIterator2 begin2, InputIterator2 end2,
495 OutputIterator result, Predicate pred,
496 IteratorTag1, IteratorTag2, IteratorTag3)
497 { return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2,
498 end2, result, pred); }
500 // Parallel set_intersection for random access iterators
501 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
502 typename OutputRandomAccessIterator, typename Predicate>
503 OutputRandomAccessIterator
504 set_intersection_switch(RandomAccessIterator1 begin1,
505 RandomAccessIterator1 end1,
506 RandomAccessIterator2 begin2,
507 RandomAccessIterator2 end2,
508 OutputRandomAccessIterator result,
510 random_access_iterator_tag,
511 random_access_iterator_tag,
512 random_access_iterator_tag)
514 if (_GLIBCXX_PARALLEL_CONDITION(
515 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
516 >= __gnu_parallel::_Settings::get().set_union_minimal_n
517 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
518 >= __gnu_parallel::_Settings::get().set_union_minimal_n))
519 return __gnu_parallel::parallel_set_intersection(begin1, end1, begin2,
522 return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2,
527 template<typename InputIterator1, typename InputIterator2,
528 typename OutputIterator>
529 inline OutputIterator
530 set_intersection(InputIterator1 begin1, InputIterator1 end1,
531 InputIterator2 begin2, InputIterator2 end2,
534 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
535 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
536 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
537 typedef typename iteratori1_traits::iterator_category
539 typedef typename iteratori2_traits::iterator_category
541 typedef typename iteratoro_traits::iterator_category iteratoro_category;
542 typedef typename iteratori1_traits::value_type value1_type;
543 typedef typename iteratori2_traits::value_type value2_type;
545 return set_intersection_switch(begin1, end1, begin2, end2, out,
547 less<value1_type, value2_type>(),
548 iteratori1_category(),
549 iteratori2_category(),
550 iteratoro_category());
553 template<typename InputIterator1, typename InputIterator2,
554 typename OutputIterator, typename Predicate>
555 inline OutputIterator
556 set_intersection(InputIterator1 begin1, InputIterator1 end1,
557 InputIterator2 begin2, InputIterator2 end2,
558 OutputIterator out, Predicate pred)
560 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
561 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
562 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
563 typedef typename iteratori1_traits::iterator_category
565 typedef typename iteratori2_traits::iterator_category
567 typedef typename iteratoro_traits::iterator_category iteratoro_category;
569 return set_intersection_switch(begin1, end1, begin2, end2, out, pred,
570 iteratori1_category(),
571 iteratori2_category(),
572 iteratoro_category());
575 // Sequential fallback
576 template<typename InputIterator1, typename InputIterator2,
577 typename OutputIterator>
578 inline OutputIterator
579 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
580 InputIterator2 begin2, InputIterator2 end2,
582 __gnu_parallel::sequential_tag)
583 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1,end1,
584 begin2, end2, out); }
586 // Sequential fallback
587 template<typename InputIterator1, typename InputIterator2,
588 typename OutputIterator, typename Predicate>
589 inline OutputIterator
590 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
591 InputIterator2 begin2, InputIterator2 end2,
592 OutputIterator out, Predicate pred,
593 __gnu_parallel::sequential_tag)
594 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1, begin2,
597 // Sequential fallback for input iterator case
598 template<typename InputIterator1, typename InputIterator2,
599 typename Predicate, typename OutputIterator,
600 typename IteratorTag1, typename IteratorTag2,
601 typename IteratorTag3>
602 inline OutputIterator
603 set_symmetric_difference_switch(InputIterator1 begin1,
605 InputIterator2 begin2,
607 OutputIterator result, Predicate pred,
608 IteratorTag1, IteratorTag2, IteratorTag3)
609 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1,
613 // Parallel set_symmetric_difference for random access iterators
614 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
615 typename OutputRandomAccessIterator, typename Predicate>
616 OutputRandomAccessIterator
617 set_symmetric_difference_switch(RandomAccessIterator1 begin1,
618 RandomAccessIterator1 end1,
619 RandomAccessIterator2 begin2,
620 RandomAccessIterator2 end2,
621 OutputRandomAccessIterator result,
623 random_access_iterator_tag,
624 random_access_iterator_tag,
625 random_access_iterator_tag)
627 if (_GLIBCXX_PARALLEL_CONDITION(
628 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
629 >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
630 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
631 >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
632 return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1,
636 return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1,
642 template<typename InputIterator1, typename InputIterator2,
643 typename OutputIterator>
644 inline OutputIterator
645 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
646 InputIterator2 begin2, InputIterator2 end2,
649 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
650 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
651 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
652 typedef typename iteratori1_traits::iterator_category
654 typedef typename iteratori2_traits::iterator_category
656 typedef typename iteratoro_traits::iterator_category iteratoro_category;
657 typedef typename iteratori1_traits::value_type value1_type;
658 typedef typename iteratori2_traits::value_type value2_type;
660 return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
662 less<value1_type, value2_type>(),
663 iteratori1_category(),
664 iteratori2_category(),
665 iteratoro_category());
669 template<typename InputIterator1, typename InputIterator2,
670 typename OutputIterator, typename Predicate>
671 inline OutputIterator
672 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
673 InputIterator2 begin2, InputIterator2 end2,
674 OutputIterator out, Predicate pred)
676 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
677 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
678 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
679 typedef typename iteratori1_traits::iterator_category
681 typedef typename iteratori2_traits::iterator_category
683 typedef typename iteratoro_traits::iterator_category iteratoro_category;
685 return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
686 pred, iteratori1_category(),
687 iteratori2_category(),
688 iteratoro_category());
691 // Sequential fallback.
692 template<typename InputIterator1, typename InputIterator2,
693 typename OutputIterator>
694 inline OutputIterator
695 set_difference(InputIterator1 begin1, InputIterator1 end1,
696 InputIterator2 begin2, InputIterator2 end2,
697 OutputIterator out, __gnu_parallel::sequential_tag)
698 { return _GLIBCXX_STD_P::set_difference(begin1,end1, begin2, end2, out); }
700 // Sequential fallback.
701 template<typename InputIterator1, typename InputIterator2,
702 typename OutputIterator, typename Predicate>
703 inline OutputIterator
704 set_difference(InputIterator1 begin1, InputIterator1 end1,
705 InputIterator2 begin2, InputIterator2 end2,
706 OutputIterator out, Predicate pred,
707 __gnu_parallel::sequential_tag)
708 { return _GLIBCXX_STD_P::set_difference(begin1, end1,
709 begin2, end2, out, pred); }
711 // Sequential fallback for input iterator case.
712 template<typename InputIterator1, typename InputIterator2,
713 typename Predicate, typename OutputIterator,
714 typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
715 inline OutputIterator
716 set_difference_switch(InputIterator1 begin1, InputIterator1 end1,
717 InputIterator2 begin2, InputIterator2 end2,
718 OutputIterator result, Predicate pred,
719 IteratorTag1, IteratorTag2, IteratorTag3)
720 { return _GLIBCXX_STD_P::set_difference(begin1, end1,
721 begin2, end2, result, pred); }
723 // Parallel set_difference for random access iterators
724 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
725 typename OutputRandomAccessIterator, typename Predicate>
726 OutputRandomAccessIterator
727 set_difference_switch(RandomAccessIterator1 begin1,
728 RandomAccessIterator1 end1,
729 RandomAccessIterator2 begin2,
730 RandomAccessIterator2 end2,
731 OutputRandomAccessIterator result, Predicate pred,
732 random_access_iterator_tag,
733 random_access_iterator_tag,
734 random_access_iterator_tag)
736 if (_GLIBCXX_PARALLEL_CONDITION(
737 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
738 >= __gnu_parallel::_Settings::get().set_difference_minimal_n
739 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
740 >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
741 return __gnu_parallel::parallel_set_difference(begin1, end1,
745 return _GLIBCXX_STD_P::set_difference(begin1, end1,
746 begin2, end2, result, pred);
750 template<typename InputIterator1, typename InputIterator2,
751 typename OutputIterator>
752 inline OutputIterator
753 set_difference(InputIterator1 begin1, InputIterator1 end1,
754 InputIterator2 begin2, InputIterator2 end2,
757 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
758 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
759 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
760 typedef typename iteratori1_traits::iterator_category
762 typedef typename iteratori2_traits::iterator_category
764 typedef typename iteratoro_traits::iterator_category iteratoro_category;
765 typedef typename iteratori1_traits::value_type value1_type;
766 typedef typename iteratori2_traits::value_type value2_type;
768 return set_difference_switch(begin1, end1, begin2, end2, out,
770 less<value1_type, value2_type>(),
771 iteratori1_category(),
772 iteratori2_category(),
773 iteratoro_category());
777 template<typename InputIterator1, typename InputIterator2,
778 typename OutputIterator, typename Predicate>
779 inline OutputIterator
780 set_difference(InputIterator1 begin1, InputIterator1 end1,
781 InputIterator2 begin2, InputIterator2 end2,
782 OutputIterator out, Predicate pred)
784 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
785 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
786 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
787 typedef typename iteratori1_traits::iterator_category
789 typedef typename iteratori2_traits::iterator_category
791 typedef typename iteratoro_traits::iterator_category iteratoro_category;
793 return set_difference_switch(begin1, end1, begin2, end2, out, pred,
794 iteratori1_category(),
795 iteratori2_category(),
796 iteratoro_category());
799 // Sequential fallback
800 template<typename ForwardIterator>
801 inline ForwardIterator
802 adjacent_find(ForwardIterator begin, ForwardIterator end,
803 __gnu_parallel::sequential_tag)
804 { return _GLIBCXX_STD_P::adjacent_find(begin, end); }
806 // Sequential fallback
807 template<typename ForwardIterator, typename BinaryPredicate>
808 inline ForwardIterator
809 adjacent_find(ForwardIterator begin, ForwardIterator end,
810 BinaryPredicate binary_pred, __gnu_parallel::sequential_tag)
811 { return _GLIBCXX_STD_P::adjacent_find(begin, end, binary_pred); }
813 // Parallel algorithm for random access iterators
814 template<typename RandomAccessIterator>
816 adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
817 random_access_iterator_tag)
819 typedef iterator_traits<RandomAccessIterator> traits_type;
820 typedef typename traits_type::value_type value_type;
822 if (_GLIBCXX_PARALLEL_CONDITION(true))
824 RandomAccessIterator spot = __gnu_parallel::
825 find_template(begin, end - 1, begin, equal_to<value_type>(),
826 __gnu_parallel::adjacent_find_selector()).first;
827 if (spot == (end - 1))
833 return adjacent_find(begin, end, __gnu_parallel::sequential_tag());
836 // Sequential fallback for input iterator case
837 template<typename ForwardIterator, typename IteratorTag>
838 inline ForwardIterator
839 adjacent_find_switch(ForwardIterator begin, ForwardIterator end,
841 { return adjacent_find(begin, end, __gnu_parallel::sequential_tag()); }
844 template<typename ForwardIterator>
845 inline ForwardIterator
846 adjacent_find(ForwardIterator begin, ForwardIterator end)
848 typedef iterator_traits<ForwardIterator> traits_type;
849 typedef typename traits_type::iterator_category iterator_category;
850 return adjacent_find_switch(begin, end, iterator_category());
853 // Sequential fallback for input iterator case
854 template<typename ForwardIterator, typename BinaryPredicate,
855 typename IteratorTag>
856 inline ForwardIterator
857 adjacent_find_switch(ForwardIterator begin, ForwardIterator end,
858 BinaryPredicate pred, IteratorTag)
859 { return adjacent_find(begin, end, pred,
860 __gnu_parallel::sequential_tag()); }
862 // Parallel algorithm for random access iterators
863 template<typename RandomAccessIterator, typename BinaryPredicate>
865 adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
866 BinaryPredicate pred, random_access_iterator_tag)
868 if (_GLIBCXX_PARALLEL_CONDITION(true))
869 return __gnu_parallel::find_template(begin, end, begin, pred,
871 adjacent_find_selector()).first;
873 return adjacent_find(begin, end, pred,
874 __gnu_parallel::sequential_tag());
878 template<typename ForwardIterator, typename BinaryPredicate>
879 inline ForwardIterator
880 adjacent_find(ForwardIterator begin, ForwardIterator end,
881 BinaryPredicate pred)
883 typedef iterator_traits<ForwardIterator> traits_type;
884 typedef typename traits_type::iterator_category iterator_category;
885 return adjacent_find_switch(begin, end, pred, iterator_category());
888 // Sequential fallback
889 template<typename InputIterator, typename T>
890 inline typename iterator_traits<InputIterator>::difference_type
891 count(InputIterator begin, InputIterator end, const T& value,
892 __gnu_parallel::sequential_tag)
893 { return _GLIBCXX_STD_P::count(begin, end, value); }
895 // Parallel code for random access iterators
896 template<typename RandomAccessIterator, typename T>
897 typename iterator_traits<RandomAccessIterator>::difference_type
898 count_switch(RandomAccessIterator begin, RandomAccessIterator end,
899 const T& value, random_access_iterator_tag,
900 __gnu_parallel::_Parallelism parallelism_tag
901 = __gnu_parallel::parallel_unbalanced)
903 typedef iterator_traits<RandomAccessIterator> traits_type;
904 typedef typename traits_type::value_type value_type;
905 typedef typename traits_type::difference_type difference_type;
906 typedef __gnu_parallel::sequence_index_t sequence_index_t;
908 if (_GLIBCXX_PARALLEL_CONDITION(
909 static_cast<sequence_index_t>(end - begin)
910 >= __gnu_parallel::_Settings::get().count_minimal_n
911 && __gnu_parallel::is_parallel(parallelism_tag)))
913 __gnu_parallel::count_selector<RandomAccessIterator, difference_type>
915 difference_type res = 0;
917 for_each_template_random_access(begin, end, value,
919 std::plus<sequence_index_t>(),
920 res, res, -1, parallelism_tag);
924 return count(begin, end, value, __gnu_parallel::sequential_tag());
927 // Sequential fallback for input iterator case.
928 template<typename InputIterator, typename T, typename IteratorTag>
929 inline typename iterator_traits<InputIterator>::difference_type
930 count_switch(InputIterator begin, InputIterator end, const T& value,
932 { return count(begin, end, value, __gnu_parallel::sequential_tag()); }
935 template<typename InputIterator, typename T>
936 inline typename iterator_traits<InputIterator>::difference_type
937 count(InputIterator begin, InputIterator end, const T& value,
938 __gnu_parallel::_Parallelism parallelism_tag)
940 typedef iterator_traits<InputIterator> traits_type;
941 typedef typename traits_type::iterator_category iterator_category;
942 return count_switch(begin, end, value, iterator_category(),
946 template<typename InputIterator, typename T>
947 inline typename iterator_traits<InputIterator>::difference_type
948 count(InputIterator begin, InputIterator end, const T& value)
950 typedef iterator_traits<InputIterator> traits_type;
951 typedef typename traits_type::iterator_category iterator_category;
952 return count_switch(begin, end, value, iterator_category());
956 // Sequential fallback.
957 template<typename InputIterator, typename Predicate>
958 inline typename iterator_traits<InputIterator>::difference_type
959 count_if(InputIterator begin, InputIterator end, Predicate pred,
960 __gnu_parallel::sequential_tag)
961 { return _GLIBCXX_STD_P::count_if(begin, end, pred); }
963 // Parallel count_if for random access iterators
964 template<typename RandomAccessIterator, typename Predicate>
965 typename iterator_traits<RandomAccessIterator>::difference_type
966 count_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
967 Predicate pred, random_access_iterator_tag,
968 __gnu_parallel::_Parallelism parallelism_tag
969 = __gnu_parallel::parallel_unbalanced)
971 typedef iterator_traits<RandomAccessIterator> traits_type;
972 typedef typename traits_type::value_type value_type;
973 typedef typename traits_type::difference_type difference_type;
974 typedef __gnu_parallel::sequence_index_t sequence_index_t;
976 if (_GLIBCXX_PARALLEL_CONDITION(
977 static_cast<sequence_index_t>(end - begin)
978 >= __gnu_parallel::_Settings::get().count_minimal_n
979 && __gnu_parallel::is_parallel(parallelism_tag)))
981 difference_type res = 0;
983 count_if_selector<RandomAccessIterator, difference_type>
986 for_each_template_random_access(begin, end, pred,
988 std::plus<sequence_index_t>(),
989 res, res, -1, parallelism_tag);
993 return count_if(begin, end, pred, __gnu_parallel::sequential_tag());
996 // Sequential fallback for input iterator case.
997 template<typename InputIterator, typename Predicate, typename IteratorTag>
998 inline typename iterator_traits<InputIterator>::difference_type
999 count_if_switch(InputIterator begin, InputIterator end, Predicate pred,
1001 { return count_if(begin, end, pred, __gnu_parallel::sequential_tag()); }
1003 // Public interface.
1004 template<typename InputIterator, typename Predicate>
1005 inline typename iterator_traits<InputIterator>::difference_type
1006 count_if(InputIterator begin, InputIterator end, Predicate pred,
1007 __gnu_parallel::_Parallelism parallelism_tag)
1009 typedef iterator_traits<InputIterator> traits_type;
1010 typedef typename traits_type::iterator_category iterator_category;
1011 return count_if_switch(begin, end, pred, iterator_category(),
1015 template<typename InputIterator, typename Predicate>
1016 inline typename iterator_traits<InputIterator>::difference_type
1017 count_if(InputIterator begin, InputIterator end, Predicate pred)
1019 typedef iterator_traits<InputIterator> traits_type;
1020 typedef typename traits_type::iterator_category iterator_category;
1021 return count_if_switch(begin, end, pred, iterator_category());
1025 // Sequential fallback.
1026 template<typename ForwardIterator1, typename ForwardIterator2>
1027 inline ForwardIterator1
1028 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1029 ForwardIterator2 begin2, ForwardIterator2 end2,
1030 __gnu_parallel::sequential_tag)
1031 { return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2); }
1033 // Parallel algorithm for random access iterator
1034 template<typename RandomAccessIterator1, typename RandomAccessIterator2>
1035 RandomAccessIterator1
1036 search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
1037 RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
1038 random_access_iterator_tag, random_access_iterator_tag)
1040 typedef std::iterator_traits<RandomAccessIterator1> iterator1_traits;
1041 typedef typename iterator1_traits::value_type value1_type;
1042 typedef std::iterator_traits<RandomAccessIterator2> iterator2_traits;
1043 typedef typename iterator2_traits::value_type value2_type;
1045 if (_GLIBCXX_PARALLEL_CONDITION(true))
1046 return __gnu_parallel::
1047 search_template(begin1, end1, begin2, end2, __gnu_parallel::
1048 equal_to<value1_type, value2_type>());
1050 return search(begin1, end1, begin2, end2,
1051 __gnu_parallel::sequential_tag());
1054 // Sequential fallback for input iterator case
1055 template<typename ForwardIterator1, typename ForwardIterator2,
1056 typename IteratorTag1, typename IteratorTag2>
1057 inline ForwardIterator1
1058 search_switch(ForwardIterator1 begin1, ForwardIterator1 end1,
1059 ForwardIterator2 begin2, ForwardIterator2 end2,
1060 IteratorTag1, IteratorTag2)
1061 { return search(begin1, end1, begin2, end2,
1062 __gnu_parallel::sequential_tag()); }
1064 // Public interface.
1065 template<typename ForwardIterator1, typename ForwardIterator2>
1066 inline ForwardIterator1
1067 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1068 ForwardIterator2 begin2, ForwardIterator2 end2)
1070 typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
1071 typedef typename iterator1_traits::iterator_category iterator1_category;
1072 typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
1073 typedef typename iterator2_traits::iterator_category iterator2_category;
1075 return search_switch(begin1, end1, begin2, end2,
1076 iterator1_category(), iterator2_category());
1079 // Public interface.
1080 template<typename ForwardIterator1, typename ForwardIterator2,
1081 typename BinaryPredicate>
1082 inline ForwardIterator1
1083 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1084 ForwardIterator2 begin2, ForwardIterator2 end2,
1085 BinaryPredicate pred, __gnu_parallel::sequential_tag)
1086 { return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2, pred); }
1088 // Parallel algorithm for random access iterator.
1089 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1090 typename BinaryPredicate>
1091 RandomAccessIterator1
1092 search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
1093 RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
1094 BinaryPredicate pred,
1095 random_access_iterator_tag, random_access_iterator_tag)
1097 if (_GLIBCXX_PARALLEL_CONDITION(true))
1098 return __gnu_parallel::search_template(begin1, end1,
1099 begin2, end2, pred);
1101 return search(begin1, end1, begin2, end2, pred,
1102 __gnu_parallel::sequential_tag());
1105 // Sequential fallback for input iterator case
1106 template<typename ForwardIterator1, typename ForwardIterator2,
1107 typename BinaryPredicate, typename IteratorTag1,
1108 typename IteratorTag2>
1109 inline ForwardIterator1
1110 search_switch(ForwardIterator1 begin1, ForwardIterator1 end1,
1111 ForwardIterator2 begin2, ForwardIterator2 end2,
1112 BinaryPredicate pred, IteratorTag1, IteratorTag2)
1113 { return search(begin1, end1, begin2, end2, pred,
1114 __gnu_parallel::sequential_tag()); }
1117 template<typename ForwardIterator1, typename ForwardIterator2,
1118 typename BinaryPredicate>
1119 inline ForwardIterator1
1120 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1121 ForwardIterator2 begin2, ForwardIterator2 end2,
1122 BinaryPredicate pred)
1124 typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
1125 typedef typename iterator1_traits::iterator_category iterator1_category;
1126 typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
1127 typedef typename iterator2_traits::iterator_category iterator2_category;
1128 return search_switch(begin1, end1, begin2, end2, pred,
1129 iterator1_category(), iterator2_category());
1132 // Sequential fallback
1133 template<typename ForwardIterator, typename Integer, typename T>
1134 inline ForwardIterator
1135 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1136 const T& val, __gnu_parallel::sequential_tag)
1137 { return _GLIBCXX_STD_P::search_n(begin, end, count, val); }
1139 // Sequential fallback
1140 template<typename ForwardIterator, typename Integer, typename T,
1141 typename BinaryPredicate>
1142 inline ForwardIterator
1143 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1144 const T& val, BinaryPredicate binary_pred,
1145 __gnu_parallel::sequential_tag)
1146 { return _GLIBCXX_STD_P::search_n(begin, end, count, val, binary_pred); }
1148 // Public interface.
1149 template<typename ForwardIterator, typename Integer, typename T>
1150 inline ForwardIterator
1151 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1154 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
1155 return search_n(begin, end, count, val,
1156 __gnu_parallel::equal_to<value_type, T>());
1159 // Parallel algorithm for random access iterators.
1160 template<typename RandomAccessIterator, typename Integer,
1161 typename T, typename BinaryPredicate>
1162 RandomAccessIterator
1163 search_n_switch(RandomAccessIterator begin, RandomAccessIterator end,
1164 Integer count, const T& val, BinaryPredicate binary_pred,
1165 random_access_iterator_tag)
1167 if (_GLIBCXX_PARALLEL_CONDITION(true))
1169 __gnu_parallel::pseudo_sequence<T, Integer> ps(val, count);
1170 return __gnu_parallel::search_template(begin, end, ps.begin(),
1171 ps.end(), binary_pred);
1174 return std::__search_n(begin, end, count, val,
1175 binary_pred, random_access_iterator_tag());
1178 // Sequential fallback for input iterator case.
1179 template<typename ForwardIterator, typename Integer, typename T,
1180 typename BinaryPredicate, typename IteratorTag>
1181 inline ForwardIterator
1182 search_n_switch(ForwardIterator begin, ForwardIterator end, Integer count,
1183 const T& val, BinaryPredicate binary_pred, IteratorTag)
1184 { return __search_n(begin, end, count, val, binary_pred, IteratorTag()); }
1186 // Public interface.
1187 template<typename ForwardIterator, typename Integer, typename T,
1188 typename BinaryPredicate>
1189 inline ForwardIterator
1190 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1191 const T& val, BinaryPredicate binary_pred)
1193 return search_n_switch(begin, end, count, val, binary_pred,
1194 typename std::iterator_traits<ForwardIterator>::
1195 iterator_category());
1199 // Sequential fallback.
1200 template<typename InputIterator, typename OutputIterator,
1201 typename UnaryOperation>
1202 inline OutputIterator
1203 transform(InputIterator begin, InputIterator end, OutputIterator result,
1204 UnaryOperation unary_op, __gnu_parallel::sequential_tag)
1205 { return _GLIBCXX_STD_P::transform(begin, end, result, unary_op); }
1207 // Parallel unary transform for random access iterators.
1208 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1209 typename UnaryOperation>
1210 RandomAccessIterator2
1211 transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end,
1212 RandomAccessIterator2 result, UnaryOperation unary_op,
1213 random_access_iterator_tag, random_access_iterator_tag,
1214 __gnu_parallel::_Parallelism parallelism_tag
1215 = __gnu_parallel::parallel_balanced)
1217 if (_GLIBCXX_PARALLEL_CONDITION(
1218 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1219 >= __gnu_parallel::_Settings::get().transform_minimal_n
1220 && __gnu_parallel::is_parallel(parallelism_tag)))
1223 typedef __gnu_parallel::iterator_pair<RandomAccessIterator1,
1224 RandomAccessIterator2, random_access_iterator_tag> ip;
1225 ip begin_pair(begin, result), end_pair(end, result + (end - begin));
1226 __gnu_parallel::transform1_selector<ip> functionality;
1228 for_each_template_random_access(begin_pair, end_pair,
1229 unary_op, functionality,
1230 __gnu_parallel::dummy_reduct(),
1231 dummy, dummy, -1, parallelism_tag);
1232 return functionality.finish_iterator;
1235 return transform(begin, end, result, unary_op,
1236 __gnu_parallel::sequential_tag());
1239 // Sequential fallback for input iterator case.
1240 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1241 typename UnaryOperation, typename IteratorTag1,
1242 typename IteratorTag2>
1243 inline RandomAccessIterator2
1244 transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end,
1245 RandomAccessIterator2 result, UnaryOperation unary_op,
1246 IteratorTag1, IteratorTag2)
1247 { return transform(begin, end, result, unary_op,
1248 __gnu_parallel::sequential_tag()); }
1250 // Public interface.
1251 template<typename InputIterator, typename OutputIterator,
1252 typename UnaryOperation>
1253 inline OutputIterator
1254 transform(InputIterator begin, InputIterator end, OutputIterator result,
1255 UnaryOperation unary_op,
1256 __gnu_parallel::_Parallelism parallelism_tag)
1258 typedef std::iterator_traits<InputIterator> iteratori_traits;
1259 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1260 typedef typename iteratori_traits::iterator_category iteratori_category;
1261 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1263 return transform1_switch(begin, end, result, unary_op,
1264 iteratori_category(), iteratoro_category(),
1268 template<typename InputIterator, typename OutputIterator,
1269 typename UnaryOperation>
1270 inline OutputIterator
1271 transform(InputIterator begin, InputIterator end, OutputIterator result,
1272 UnaryOperation unary_op)
1274 typedef std::iterator_traits<InputIterator> iteratori_traits;
1275 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1276 typedef typename iteratori_traits::iterator_category iteratori_category;
1277 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1279 return transform1_switch(begin, end, result, unary_op,
1280 iteratori_category(), iteratoro_category());
1284 // Sequential fallback
1285 template<typename InputIterator1, typename InputIterator2,
1286 typename OutputIterator, typename BinaryOperation>
1287 inline OutputIterator
1288 transform(InputIterator1 begin1, InputIterator1 end1,
1289 InputIterator2 begin2, OutputIterator result,
1290 BinaryOperation binary_op, __gnu_parallel::sequential_tag)
1291 { return _GLIBCXX_STD_P::transform(begin1, end1,
1292 begin2, result, binary_op); }
1294 // Parallel binary transform for random access iterators.
1295 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1296 typename RandomAccessIterator3, typename BinaryOperation>
1297 RandomAccessIterator3
1298 transform2_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
1299 RandomAccessIterator2 begin2,
1300 RandomAccessIterator3 result, BinaryOperation binary_op,
1301 random_access_iterator_tag, random_access_iterator_tag,
1302 random_access_iterator_tag,
1303 __gnu_parallel::_Parallelism parallelism_tag
1304 = __gnu_parallel::parallel_balanced)
1306 if (_GLIBCXX_PARALLEL_CONDITION(
1308 __gnu_parallel::_Settings::get().transform_minimal_n
1309 && __gnu_parallel::is_parallel(parallelism_tag)))
1312 typedef __gnu_parallel::iterator_triple<RandomAccessIterator1,
1313 RandomAccessIterator2, RandomAccessIterator3,
1314 random_access_iterator_tag> ip;
1315 ip begin_triple(begin1, begin2, result),
1316 end_triple(end1, begin2 + (end1 - begin1),
1317 result + (end1 - begin1));
1318 __gnu_parallel::transform2_selector<ip> functionality;
1320 for_each_template_random_access(begin_triple, end_triple,
1321 binary_op, functionality,
1322 __gnu_parallel::dummy_reduct(),
1325 return functionality.finish_iterator;
1328 return transform(begin1, end1, begin2, result, binary_op,
1329 __gnu_parallel::sequential_tag());
1332 // Sequential fallback for input iterator case.
1333 template<typename InputIterator1, typename InputIterator2,
1334 typename OutputIterator, typename BinaryOperation,
1335 typename tag1, typename tag2, typename tag3>
1336 inline OutputIterator
1337 transform2_switch(InputIterator1 begin1, InputIterator1 end1,
1338 InputIterator2 begin2, OutputIterator result,
1339 BinaryOperation binary_op, tag1, tag2, tag3)
1340 { return transform(begin1, end1, begin2, result, binary_op,
1341 __gnu_parallel::sequential_tag()); }
1343 // Public interface.
1344 template<typename InputIterator1, typename InputIterator2,
1345 typename OutputIterator, typename BinaryOperation>
1346 inline OutputIterator
1347 transform(InputIterator1 begin1, InputIterator1 end1,
1348 InputIterator2 begin2, OutputIterator result,
1349 BinaryOperation binary_op,
1350 __gnu_parallel::_Parallelism parallelism_tag)
1352 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
1353 typedef typename iteratori1_traits::iterator_category
1354 iteratori1_category;
1355 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
1356 typedef typename iteratori2_traits::iterator_category
1357 iteratori2_category;
1358 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1359 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1361 return transform2_switch(begin1, end1, begin2, result, binary_op,
1362 iteratori1_category(), iteratori2_category(),
1363 iteratoro_category(), parallelism_tag);
1366 template<typename InputIterator1, typename InputIterator2,
1367 typename OutputIterator, typename BinaryOperation>
1368 inline OutputIterator
1369 transform(InputIterator1 begin1, InputIterator1 end1,
1370 InputIterator2 begin2, OutputIterator result,
1371 BinaryOperation binary_op)
1373 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
1374 typedef typename iteratori1_traits::iterator_category
1375 iteratori1_category;
1376 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
1377 typedef typename iteratori2_traits::iterator_category
1378 iteratori2_category;
1379 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1380 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1382 return transform2_switch(begin1, end1, begin2, result, binary_op,
1383 iteratori1_category(), iteratori2_category(),
1384 iteratoro_category());
1387 // Sequential fallback
1388 template<typename ForwardIterator, typename T>
1390 replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
1391 const T& new_value, __gnu_parallel::sequential_tag)
1392 { _GLIBCXX_STD_P::replace(begin, end, old_value, new_value); }
1394 // Sequential fallback for input iterator case
1395 template<typename ForwardIterator, typename T, typename IteratorTag>
1397 replace_switch(ForwardIterator begin, ForwardIterator end,
1398 const T& old_value, const T& new_value, IteratorTag)
1399 { replace(begin, end, old_value, new_value,
1400 __gnu_parallel::sequential_tag()); }
1402 // Parallel replace for random access iterators
1403 template<typename RandomAccessIterator, typename T>
1405 replace_switch(RandomAccessIterator begin, RandomAccessIterator end,
1406 const T& old_value, const T& new_value,
1407 random_access_iterator_tag,
1408 __gnu_parallel::_Parallelism parallelism_tag
1409 = __gnu_parallel::parallel_balanced)
1411 // XXX parallel version is where?
1412 replace(begin, end, old_value, new_value,
1413 __gnu_parallel::sequential_tag());
1417 template<typename ForwardIterator, typename T>
1419 replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
1420 const T& new_value, __gnu_parallel::_Parallelism parallelism_tag)
1422 typedef iterator_traits<ForwardIterator> traits_type;
1423 typedef typename traits_type::iterator_category iterator_category;
1424 replace_switch(begin, end, old_value, new_value, iterator_category(),
1428 template<typename ForwardIterator, typename T>
1430 replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
1433 typedef iterator_traits<ForwardIterator> traits_type;
1434 typedef typename traits_type::iterator_category iterator_category;
1435 replace_switch(begin, end, old_value, new_value, iterator_category());
1439 // Sequential fallback
1440 template<typename ForwardIterator, typename Predicate, typename T>
1442 replace_if(ForwardIterator begin, ForwardIterator end, Predicate pred,
1443 const T& new_value, __gnu_parallel::sequential_tag)
1444 { _GLIBCXX_STD_P::replace_if(begin, end, pred, new_value); }
1446 // Sequential fallback for input iterator case
1447 template<typename ForwardIterator, typename Predicate, typename T,
1448 typename IteratorTag>
1450 replace_if_switch(ForwardIterator begin, ForwardIterator end,
1451 Predicate pred, const T& new_value, IteratorTag)
1452 { replace_if(begin, end, pred, new_value,
1453 __gnu_parallel::sequential_tag()); }
1455 // Parallel algorithm for random access iterators.
1456 template<typename RandomAccessIterator, typename Predicate, typename T>
1458 replace_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
1459 Predicate pred, const T& new_value,
1460 random_access_iterator_tag,
1461 __gnu_parallel::_Parallelism parallelism_tag
1462 = __gnu_parallel::parallel_balanced)
1464 if (_GLIBCXX_PARALLEL_CONDITION(
1465 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1466 >= __gnu_parallel::_Settings::get().replace_minimal_n
1467 && __gnu_parallel::is_parallel(parallelism_tag)))
1471 replace_if_selector<RandomAccessIterator, Predicate, T>
1472 functionality(new_value);
1474 for_each_template_random_access(begin, end, pred,
1476 __gnu_parallel::dummy_reduct(),
1477 true, dummy, -1, parallelism_tag);
1480 replace_if(begin, end, pred, new_value,
1481 __gnu_parallel::sequential_tag());
1484 // Public interface.
1485 template<typename ForwardIterator, typename Predicate, typename T>
1487 replace_if(ForwardIterator begin, ForwardIterator end,
1488 Predicate pred, const T& new_value,
1489 __gnu_parallel::_Parallelism parallelism_tag)
1491 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1492 typedef typename iterator_traits::iterator_category iterator_category;
1493 replace_if_switch(begin, end, pred, new_value, iterator_category(),
1497 template<typename ForwardIterator, typename Predicate, typename T>
1499 replace_if(ForwardIterator begin, ForwardIterator end,
1500 Predicate pred, const T& new_value)
1502 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1503 typedef typename iterator_traits::iterator_category iterator_category;
1504 replace_if_switch(begin, end, pred, new_value, iterator_category());
1507 // Sequential fallback
1508 template<typename ForwardIterator, typename Generator>
1510 generate(ForwardIterator begin, ForwardIterator end, Generator gen,
1511 __gnu_parallel::sequential_tag)
1512 { _GLIBCXX_STD_P::generate(begin, end, gen); }
1514 // Sequential fallback for input iterator case.
1515 template<typename ForwardIterator, typename Generator, typename IteratorTag>
1517 generate_switch(ForwardIterator begin, ForwardIterator end, Generator gen,
1519 { generate(begin, end, gen, __gnu_parallel::sequential_tag()); }
1521 // Parallel algorithm for random access iterators.
1522 template<typename RandomAccessIterator, typename Generator>
1524 generate_switch(RandomAccessIterator begin, RandomAccessIterator end,
1525 Generator gen, random_access_iterator_tag,
1526 __gnu_parallel::_Parallelism parallelism_tag
1527 = __gnu_parallel::parallel_balanced)
1529 if (_GLIBCXX_PARALLEL_CONDITION(
1530 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1531 >= __gnu_parallel::_Settings::get().generate_minimal_n
1532 && __gnu_parallel::is_parallel(parallelism_tag)))
1535 __gnu_parallel::generate_selector<RandomAccessIterator>
1538 for_each_template_random_access(begin, end, gen, functionality,
1539 __gnu_parallel::dummy_reduct(),
1540 true, dummy, -1, parallelism_tag);
1543 generate(begin, end, gen, __gnu_parallel::sequential_tag());
1546 // Public interface.
1547 template<typename ForwardIterator, typename Generator>
1549 generate(ForwardIterator begin, ForwardIterator end,
1550 Generator gen, __gnu_parallel::_Parallelism parallelism_tag)
1552 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1553 typedef typename iterator_traits::iterator_category iterator_category;
1554 generate_switch(begin, end, gen, iterator_category(), parallelism_tag);
1557 template<typename ForwardIterator, typename Generator>
1559 generate(ForwardIterator begin, ForwardIterator end, Generator gen)
1561 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1562 typedef typename iterator_traits::iterator_category iterator_category;
1563 generate_switch(begin, end, gen, iterator_category());
1567 // Sequential fallback.
1568 template<typename OutputIterator, typename Size, typename Generator>
1569 inline OutputIterator
1570 generate_n(OutputIterator begin, Size n, Generator gen,
1571 __gnu_parallel::sequential_tag)
1572 { return _GLIBCXX_STD_P::generate_n(begin, n, gen); }
1574 // Sequential fallback for input iterator case.
1575 template<typename OutputIterator, typename Size, typename Generator,
1576 typename IteratorTag>
1577 inline OutputIterator
1578 generate_n_switch(OutputIterator begin, Size n, Generator gen, IteratorTag)
1579 { return generate_n(begin, n, gen, __gnu_parallel::sequential_tag()); }
1581 // Parallel algorithm for random access iterators.
1582 template<typename RandomAccessIterator, typename Size, typename Generator>
1583 inline RandomAccessIterator
1584 generate_n_switch(RandomAccessIterator begin, Size n, Generator gen,
1585 random_access_iterator_tag,
1586 __gnu_parallel::_Parallelism parallelism_tag
1587 = __gnu_parallel::parallel_balanced)
1589 // XXX parallel version is where?
1590 return generate_n(begin, n, gen, __gnu_parallel::sequential_tag());
1593 // Public interface.
1594 template<typename OutputIterator, typename Size, typename Generator>
1595 inline OutputIterator
1596 generate_n(OutputIterator begin, Size n, Generator gen,
1597 __gnu_parallel::_Parallelism parallelism_tag)
1599 typedef std::iterator_traits<OutputIterator> iterator_traits;
1600 typedef typename iterator_traits::iterator_category iterator_category;
1601 return generate_n_switch(begin, n, gen, iterator_category(),
1605 template<typename OutputIterator, typename Size, typename Generator>
1606 inline OutputIterator
1607 generate_n(OutputIterator begin, Size n, Generator gen)
1609 typedef std::iterator_traits<OutputIterator> iterator_traits;
1610 typedef typename iterator_traits::iterator_category iterator_category;
1611 return generate_n_switch(begin, n, gen, iterator_category());
1615 // Sequential fallback.
1616 template<typename RandomAccessIterator>
1618 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
1619 __gnu_parallel::sequential_tag)
1620 { _GLIBCXX_STD_P::random_shuffle(begin, end); }
1622 // Sequential fallback.
1623 template<typename RandomAccessIterator, typename RandomNumberGenerator>
1625 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
1626 RandomNumberGenerator& rand, __gnu_parallel::sequential_tag)
1627 { _GLIBCXX_STD_P::random_shuffle(begin, end, rand); }
1630 /** @brief Functor wrapper for std::rand(). */
1631 template<typename must_be_int = int>
1632 struct c_rand_number
1635 operator()(int limit)
1636 { return rand() % limit; }
1639 // Fill in random number generator.
1640 template<typename RandomAccessIterator>
1642 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end)
1645 // Parallelization still possible.
1646 __gnu_parallel::random_shuffle(begin, end, r);
1649 // Parallel algorithm for random access iterators.
1650 template<typename RandomAccessIterator, typename RandomNumberGenerator>
1652 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
1653 RandomNumberGenerator& rand)
1657 if (_GLIBCXX_PARALLEL_CONDITION(
1658 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1659 >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
1660 __gnu_parallel::parallel_random_shuffle(begin, end, rand);
1662 __gnu_parallel::sequential_random_shuffle(begin, end, rand);
1665 // Sequential fallback.
1666 template<typename ForwardIterator, typename Predicate>
1667 inline ForwardIterator
1668 partition(ForwardIterator begin, ForwardIterator end,
1669 Predicate pred, __gnu_parallel::sequential_tag)
1670 { return _GLIBCXX_STD_P::partition(begin, end, pred); }
1672 // Sequential fallback for input iterator case.
1673 template<typename ForwardIterator, typename Predicate, typename IteratorTag>
1674 inline ForwardIterator
1675 partition_switch(ForwardIterator begin, ForwardIterator end,
1676 Predicate pred, IteratorTag)
1677 { return partition(begin, end, pred, __gnu_parallel::sequential_tag()); }
1679 // Parallel algorithm for random access iterators.
1680 template<typename RandomAccessIterator, typename Predicate>
1681 RandomAccessIterator
1682 partition_switch(RandomAccessIterator begin, RandomAccessIterator end,
1683 Predicate pred, random_access_iterator_tag)
1685 if (_GLIBCXX_PARALLEL_CONDITION(
1686 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1687 >= __gnu_parallel::_Settings::get().partition_minimal_n))
1689 typedef typename std::iterator_traits<RandomAccessIterator>::
1690 difference_type difference_type;
1691 difference_type middle = __gnu_parallel::
1692 parallel_partition(begin, end, pred,
1693 __gnu_parallel::get_max_threads());
1694 return begin + middle;
1697 return partition(begin, end, pred, __gnu_parallel::sequential_tag());
1700 // Public interface.
1701 template<typename ForwardIterator, typename Predicate>
1702 inline ForwardIterator
1703 partition(ForwardIterator begin, ForwardIterator end, Predicate pred)
1705 typedef iterator_traits<ForwardIterator> traits_type;
1706 typedef typename traits_type::iterator_category iterator_category;
1707 return partition_switch(begin, end, pred, iterator_category());
1712 // Sequential fallback
1713 template<typename RandomAccessIterator>
1715 sort(RandomAccessIterator begin, RandomAccessIterator end,
1716 __gnu_parallel::sequential_tag)
1717 { _GLIBCXX_STD_P::sort(begin, end); }
1719 // Sequential fallback
1720 template<typename RandomAccessIterator, typename Comparator>
1722 sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp,
1723 __gnu_parallel::sequential_tag)
1724 { _GLIBCXX_STD_P::sort<RandomAccessIterator, Comparator>(begin, end,
1728 template<typename RandomAccessIterator, typename Comparator,
1729 typename Parallelism>
1731 sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp,
1732 Parallelism parallelism)
1734 typedef iterator_traits<RandomAccessIterator> traits_type;
1735 typedef typename traits_type::value_type value_type;
1739 if (_GLIBCXX_PARALLEL_CONDITION(
1740 static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
1741 __gnu_parallel::_Settings::get().sort_minimal_n))
1742 __gnu_parallel::parallel_sort<false>(begin, end, comp, parallelism);
1744 sort(begin, end, comp, __gnu_parallel::sequential_tag());
1748 // Public interface, insert default comparator
1749 template<typename RandomAccessIterator>
1751 sort(RandomAccessIterator begin, RandomAccessIterator end)
1753 typedef iterator_traits<RandomAccessIterator> traits_type;
1754 typedef typename traits_type::value_type value_type;
1755 sort(begin, end, std::less<value_type>(),
1756 __gnu_parallel::default_parallel_tag());
1759 // Public interface, insert default comparator
1760 template<typename RandomAccessIterator>
1762 sort(RandomAccessIterator begin, RandomAccessIterator end,
1763 __gnu_parallel::default_parallel_tag parallelism)
1765 typedef iterator_traits<RandomAccessIterator> traits_type;
1766 typedef typename traits_type::value_type value_type;
1767 sort(begin, end, std::less<value_type>(), parallelism);
1770 // Public interface, insert default comparator
1771 template<typename RandomAccessIterator>
1773 sort(RandomAccessIterator begin, RandomAccessIterator end,
1774 __gnu_parallel::parallel_tag parallelism)
1776 typedef iterator_traits<RandomAccessIterator> traits_type;
1777 typedef typename traits_type::value_type value_type;
1778 sort(begin, end, std::less<value_type>(), parallelism);
1781 // Public interface, insert default comparator
1782 template<typename RandomAccessIterator>
1784 sort(RandomAccessIterator begin, RandomAccessIterator end,
1785 __gnu_parallel::multiway_mergesort_tag parallelism)
1787 typedef iterator_traits<RandomAccessIterator> traits_type;
1788 typedef typename traits_type::value_type value_type;
1789 sort(begin, end, std::less<value_type>(), parallelism);
1792 // Public interface, insert default comparator
1793 template<typename RandomAccessIterator>
1795 sort(RandomAccessIterator begin, RandomAccessIterator end,
1796 __gnu_parallel::multiway_mergesort_sampling_tag parallelism)
1798 typedef iterator_traits<RandomAccessIterator> traits_type;
1799 typedef typename traits_type::value_type value_type;
1800 sort(begin, end, std::less<value_type>(), parallelism);
1803 // Public interface, insert default comparator
1804 template<typename RandomAccessIterator>
1806 sort(RandomAccessIterator begin, RandomAccessIterator end,
1807 __gnu_parallel::multiway_mergesort_exact_tag parallelism)
1809 typedef iterator_traits<RandomAccessIterator> traits_type;
1810 typedef typename traits_type::value_type value_type;
1811 sort(begin, end, std::less<value_type>(), parallelism);
1814 // Public interface, insert default comparator
1815 template<typename RandomAccessIterator>
1817 sort(RandomAccessIterator begin, RandomAccessIterator end,
1818 __gnu_parallel::quicksort_tag parallelism)
1820 typedef iterator_traits<RandomAccessIterator> traits_type;
1821 typedef typename traits_type::value_type value_type;
1822 sort(begin, end, std::less<value_type>(), parallelism);
1825 // Public interface, insert default comparator
1826 template<typename RandomAccessIterator>
1828 sort(RandomAccessIterator begin, RandomAccessIterator end,
1829 __gnu_parallel::balanced_quicksort_tag parallelism)
1831 typedef iterator_traits<RandomAccessIterator> traits_type;
1832 typedef typename traits_type::value_type value_type;
1833 sort(begin, end, std::less<value_type>(), parallelism);
1837 template<typename RandomAccessIterator, typename Comparator>
1839 sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp)
1841 typedef iterator_traits<RandomAccessIterator> traits_type;
1842 typedef typename traits_type::value_type value_type;
1843 sort(begin, end, comp, __gnu_parallel::default_parallel_tag());
1847 // stable_sort interface
1850 // Sequential fallback
1851 template<typename RandomAccessIterator>
1853 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1854 __gnu_parallel::sequential_tag)
1855 { _GLIBCXX_STD_P::stable_sort(begin, end); }
1857 // Sequential fallback
1858 template<typename RandomAccessIterator, typename Comparator>
1860 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1861 Comparator comp, __gnu_parallel::sequential_tag)
1862 { _GLIBCXX_STD_P::stable_sort<RandomAccessIterator, Comparator>(
1863 begin, end, comp); }
1866 template<typename RandomAccessIterator, typename Comparator,
1867 typename Parallelism>
1869 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1870 Comparator comp, Parallelism parallelism)
1872 typedef iterator_traits<RandomAccessIterator> traits_type;
1873 typedef typename traits_type::value_type value_type;
1877 if (_GLIBCXX_PARALLEL_CONDITION(
1878 static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
1879 __gnu_parallel::_Settings::get().sort_minimal_n))
1880 __gnu_parallel::parallel_sort<true>(begin, end, comp, parallelism);
1882 stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
1886 // Public interface, insert default comparator
1887 template<typename RandomAccessIterator>
1889 stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
1891 typedef iterator_traits<RandomAccessIterator> traits_type;
1892 typedef typename traits_type::value_type value_type;
1893 stable_sort(begin, end, std::less<value_type>(),
1894 __gnu_parallel::default_parallel_tag());
1897 // Public interface, insert default comparator
1898 template<typename RandomAccessIterator>
1900 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1901 __gnu_parallel::default_parallel_tag parallelism)
1903 typedef iterator_traits<RandomAccessIterator> traits_type;
1904 typedef typename traits_type::value_type value_type;
1905 stable_sort(begin, end, std::less<value_type>(), parallelism);
1908 // Public interface, insert default comparator
1909 template<typename RandomAccessIterator>
1911 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1912 __gnu_parallel::parallel_tag parallelism)
1914 typedef iterator_traits<RandomAccessIterator> traits_type;
1915 typedef typename traits_type::value_type value_type;
1916 stable_sort(begin, end, std::less<value_type>(), parallelism);
1919 // Public interface, insert default comparator
1920 template<typename RandomAccessIterator>
1922 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1923 __gnu_parallel::multiway_mergesort_tag parallelism)
1925 typedef iterator_traits<RandomAccessIterator> traits_type;
1926 typedef typename traits_type::value_type value_type;
1927 stable_sort(begin, end, std::less<value_type>(), parallelism);
1930 // Public interface, insert default comparator
1931 template<typename RandomAccessIterator>
1933 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1934 __gnu_parallel::quicksort_tag parallelism)
1936 typedef iterator_traits<RandomAccessIterator> traits_type;
1937 typedef typename traits_type::value_type value_type;
1938 stable_sort(begin, end, std::less<value_type>(), parallelism);
1941 // Public interface, insert default comparator
1942 template<typename RandomAccessIterator>
1944 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1945 __gnu_parallel::balanced_quicksort_tag parallelism)
1947 typedef iterator_traits<RandomAccessIterator> traits_type;
1948 typedef typename traits_type::value_type value_type;
1949 stable_sort(begin, end, std::less<value_type>(), parallelism);
1953 template<typename RandomAccessIterator, typename Comparator>
1955 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1958 typedef iterator_traits<RandomAccessIterator> traits_type;
1959 typedef typename traits_type::value_type value_type;
1960 stable_sort(begin, end, comp, __gnu_parallel::default_parallel_tag());
1964 // // Sequential fallback
1965 // template<typename RandomAccessIterator>
1967 // stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1968 // __gnu_parallel::sequential_tag)
1969 // { return _GLIBCXX_STD_P::stable_sort(begin, end); }
1971 // // Sequential fallback
1972 // template<typename RandomAccessIterator, typename Comparator>
1974 // stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1975 // Comparator comp, __gnu_parallel::sequential_tag)
1976 // { return _GLIBCXX_STD_P::stable_sort(begin, end, comp); }
1978 // template<typename RandomAccessIterator>
1980 // stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
1982 // typedef iterator_traits<RandomAccessIterator> traits_type;
1983 // typedef typename traits_type::value_type value_type;
1984 // stable_sort(begin, end, std::less<value_type>());
1987 // // Parallel algorithm for random access iterators
1988 // template<typename RandomAccessIterator, typename Comparator>
1990 // stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1993 // if (begin != end)
1995 // if (_GLIBCXX_PARALLEL_CONDITION(
1996 // static_cast<__gnu_parallel::sequence_index_t>(end - begin) >=
1997 // __gnu_parallel::_Settings::get().sort_minimal_n))
1998 // __gnu_parallel::parallel_sort(begin, end, comp,
1999 // __gnu_parallel::parallel_tag());
2001 // stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
2005 // Sequential fallback
2006 template<typename InputIterator1, typename InputIterator2,
2007 typename OutputIterator>
2008 inline OutputIterator
2009 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
2010 InputIterator2 end2, OutputIterator result,
2011 __gnu_parallel::sequential_tag)
2012 { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result); }
2014 // Sequential fallback
2015 template<typename InputIterator1, typename InputIterator2,
2016 typename OutputIterator, typename Comparator>
2017 inline OutputIterator
2018 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
2019 InputIterator2 end2, OutputIterator result, Comparator comp,
2020 __gnu_parallel::sequential_tag)
2021 { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result, comp); }
2023 // Sequential fallback for input iterator case
2024 template<typename InputIterator1, typename InputIterator2,
2025 typename OutputIterator, typename Comparator,
2026 typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
2027 inline OutputIterator
2028 merge_switch(InputIterator1 begin1, InputIterator1 end1,
2029 InputIterator2 begin2, InputIterator2 end2,
2030 OutputIterator result, Comparator comp,
2031 IteratorTag1, IteratorTag2, IteratorTag3)
2032 { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2,
2035 // Parallel algorithm for random access iterators
2036 template<typename InputIterator1, typename InputIterator2,
2037 typename OutputIterator, typename Comparator>
2039 merge_switch(InputIterator1 begin1, InputIterator1 end1,
2040 InputIterator2 begin2, InputIterator2 end2,
2041 OutputIterator result, Comparator comp,
2042 random_access_iterator_tag, random_access_iterator_tag,
2043 random_access_iterator_tag)
2045 if (_GLIBCXX_PARALLEL_CONDITION(
2046 (static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
2047 >= __gnu_parallel::_Settings::get().merge_minimal_n
2048 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
2049 >= __gnu_parallel::_Settings::get().merge_minimal_n)))
2050 return __gnu_parallel::parallel_merge_advance(begin1, end1,
2052 result, (end1 - begin1)
2053 + (end2 - begin2), comp);
2055 return __gnu_parallel::merge_advance(begin1, end1, begin2, end2,
2056 result, (end1 - begin1)
2057 + (end2 - begin2), comp);
2061 template<typename InputIterator1, typename InputIterator2,
2062 typename OutputIterator, typename Comparator>
2063 inline OutputIterator
2064 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
2065 InputIterator2 end2, OutputIterator result, Comparator comp)
2067 typedef typename iterator_traits<InputIterator1>::value_type value_type;
2069 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
2070 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
2071 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
2072 typedef typename iteratori1_traits::iterator_category
2073 iteratori1_category;
2074 typedef typename iteratori2_traits::iterator_category
2075 iteratori2_category;
2076 typedef typename iteratoro_traits::iterator_category iteratoro_category;
2078 return merge_switch(begin1, end1, begin2, end2, result, comp,
2079 iteratori1_category(), iteratori2_category(),
2080 iteratoro_category());
2084 // Public interface, insert default comparator
2085 template<typename InputIterator1, typename InputIterator2,
2086 typename OutputIterator>
2087 inline OutputIterator
2088 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
2089 InputIterator2 end2, OutputIterator result)
2091 typedef std::iterator_traits<InputIterator1> iterator1_traits;
2092 typedef std::iterator_traits<InputIterator2> iterator2_traits;
2093 typedef typename iterator1_traits::value_type value1_type;
2094 typedef typename iterator2_traits::value_type value2_type;
2096 return merge(begin1, end1, begin2, end2, result,
2097 __gnu_parallel::less<value1_type, value2_type>());
2100 // Sequential fallback
2101 template<typename RandomAccessIterator>
2103 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
2104 RandomAccessIterator end, __gnu_parallel::sequential_tag)
2105 { return _GLIBCXX_STD_P::nth_element(begin, nth, end); }
2107 // Sequential fallback
2108 template<typename RandomAccessIterator, typename Comparator>
2110 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
2111 RandomAccessIterator end, Comparator comp,
2112 __gnu_parallel::sequential_tag)
2113 { return _GLIBCXX_STD_P::nth_element(begin, nth, end, comp); }
2116 template<typename RandomAccessIterator, typename Comparator>
2118 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
2119 RandomAccessIterator end, Comparator comp)
2121 if (_GLIBCXX_PARALLEL_CONDITION(
2122 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
2123 >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
2124 __gnu_parallel::parallel_nth_element(begin, nth, end, comp);
2126 nth_element(begin, nth, end, comp, __gnu_parallel::sequential_tag());
2129 // Public interface, insert default comparator
2130 template<typename RandomAccessIterator>
2132 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
2133 RandomAccessIterator end)
2135 typedef iterator_traits<RandomAccessIterator> traits_type;
2136 typedef typename traits_type::value_type value_type;
2137 nth_element(begin, nth, end, std::less<value_type>());
2140 // Sequential fallback
2141 template<typename RandomAccessIterator, typename _Compare>
2143 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
2144 RandomAccessIterator end, _Compare comp,
2145 __gnu_parallel::sequential_tag)
2146 { _GLIBCXX_STD_P::partial_sort(begin, middle, end, comp); }
2148 // Sequential fallback
2149 template<typename RandomAccessIterator>
2151 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
2152 RandomAccessIterator end, __gnu_parallel::sequential_tag)
2153 { _GLIBCXX_STD_P::partial_sort(begin, middle, end); }
2155 // Public interface, parallel algorithm for random access iterators
2156 template<typename RandomAccessIterator, typename _Compare>
2158 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
2159 RandomAccessIterator end, _Compare comp)
2161 if (_GLIBCXX_PARALLEL_CONDITION(
2162 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
2163 >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
2164 __gnu_parallel::parallel_partial_sort(begin, middle, end, comp);
2166 partial_sort(begin, middle, end, comp,
2167 __gnu_parallel::sequential_tag());
2170 // Public interface, insert default comparator
2171 template<typename RandomAccessIterator>
2173 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
2174 RandomAccessIterator end)
2176 typedef iterator_traits<RandomAccessIterator> traits_type;
2177 typedef typename traits_type::value_type value_type;
2178 partial_sort(begin, middle, end, std::less<value_type>());
2181 // Sequential fallback
2182 template<typename ForwardIterator>
2183 inline ForwardIterator
2184 max_element(ForwardIterator begin, ForwardIterator end,
2185 __gnu_parallel::sequential_tag)
2186 { return _GLIBCXX_STD_P::max_element(begin, end); }
2188 // Sequential fallback
2189 template<typename ForwardIterator, typename Comparator>
2190 inline ForwardIterator
2191 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
2192 __gnu_parallel::sequential_tag)
2193 { return _GLIBCXX_STD_P::max_element(begin, end, comp); }
2195 // Sequential fallback for input iterator case
2196 template<typename ForwardIterator, typename Comparator, typename IteratorTag>
2197 inline ForwardIterator
2198 max_element_switch(ForwardIterator begin, ForwardIterator end,
2199 Comparator comp, IteratorTag)
2200 { return max_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
2202 // Parallel algorithm for random access iterators
2203 template<typename RandomAccessIterator, typename Comparator>
2204 RandomAccessIterator
2205 max_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
2206 Comparator comp, random_access_iterator_tag,
2207 __gnu_parallel::_Parallelism parallelism_tag
2208 = __gnu_parallel::parallel_balanced)
2210 if (_GLIBCXX_PARALLEL_CONDITION(
2211 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
2212 >= __gnu_parallel::_Settings::get().max_element_minimal_n
2213 && __gnu_parallel::is_parallel(parallelism_tag)))
2215 RandomAccessIterator res(begin);
2216 __gnu_parallel::identity_selector<RandomAccessIterator>
2219 for_each_template_random_access(begin, end,
2220 __gnu_parallel::nothing(),
2223 max_element_reduct<Comparator,
2224 RandomAccessIterator>(comp),
2225 res, res, -1, parallelism_tag);
2229 return max_element(begin, end, comp, __gnu_parallel::sequential_tag());
2232 // Public interface, insert default comparator
2233 template<typename ForwardIterator>
2234 inline ForwardIterator
2235 max_element(ForwardIterator begin, ForwardIterator end,
2236 __gnu_parallel::_Parallelism parallelism_tag)
2238 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2239 return max_element(begin, end, std::less<value_type>(), parallelism_tag);
2242 template<typename ForwardIterator>
2243 inline ForwardIterator
2244 max_element(ForwardIterator begin, ForwardIterator end)
2246 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2247 return max_element(begin, end, std::less<value_type>());
2251 template<typename ForwardIterator, typename Comparator>
2252 inline ForwardIterator
2253 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
2254 __gnu_parallel::_Parallelism parallelism_tag)
2256 typedef iterator_traits<ForwardIterator> traits_type;
2257 typedef typename traits_type::iterator_category iterator_category;
2258 return max_element_switch(begin, end, comp, iterator_category(),
2262 template<typename ForwardIterator, typename Comparator>
2263 inline ForwardIterator
2264 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
2266 typedef iterator_traits<ForwardIterator> traits_type;
2267 typedef typename traits_type::iterator_category iterator_category;
2268 return max_element_switch(begin, end, comp, iterator_category());
2272 // Sequential fallback
2273 template<typename ForwardIterator>
2274 inline ForwardIterator
2275 min_element(ForwardIterator begin, ForwardIterator end,
2276 __gnu_parallel::sequential_tag)
2277 { return _GLIBCXX_STD_P::min_element(begin, end); }
2279 // Sequential fallback
2280 template<typename ForwardIterator, typename Comparator>
2281 inline ForwardIterator
2282 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
2283 __gnu_parallel::sequential_tag)
2284 { return _GLIBCXX_STD_P::min_element(begin, end, comp); }
2286 // Sequential fallback for input iterator case
2287 template<typename ForwardIterator, typename Comparator, typename IteratorTag>
2288 inline ForwardIterator
2289 min_element_switch(ForwardIterator begin, ForwardIterator end,
2290 Comparator comp, IteratorTag)
2291 { return min_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
2293 // Parallel algorithm for random access iterators
2294 template<typename RandomAccessIterator, typename Comparator>
2295 RandomAccessIterator
2296 min_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
2297 Comparator comp, random_access_iterator_tag,
2298 __gnu_parallel::_Parallelism parallelism_tag
2299 = __gnu_parallel::parallel_balanced)
2301 if (_GLIBCXX_PARALLEL_CONDITION(
2302 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
2303 >= __gnu_parallel::_Settings::get().min_element_minimal_n
2304 && __gnu_parallel::is_parallel(parallelism_tag)))
2306 RandomAccessIterator res(begin);
2307 __gnu_parallel::identity_selector<RandomAccessIterator>
2310 for_each_template_random_access(begin, end,
2311 __gnu_parallel::nothing(),
2314 min_element_reduct<Comparator,
2315 RandomAccessIterator>(comp),
2316 res, res, -1, parallelism_tag);
2320 return min_element(begin, end, comp, __gnu_parallel::sequential_tag());
2323 // Public interface, insert default comparator
2324 template<typename ForwardIterator>
2325 inline ForwardIterator
2326 min_element(ForwardIterator begin, ForwardIterator end,
2327 __gnu_parallel::_Parallelism parallelism_tag)
2329 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2330 return min_element(begin, end, std::less<value_type>(), parallelism_tag);
2333 template<typename ForwardIterator>
2334 inline ForwardIterator
2335 min_element(ForwardIterator begin, ForwardIterator end)
2337 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2338 return min_element(begin, end, std::less<value_type>());
2342 template<typename ForwardIterator, typename Comparator>
2343 inline ForwardIterator
2344 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
2345 __gnu_parallel::_Parallelism parallelism_tag)
2347 typedef iterator_traits<ForwardIterator> traits_type;
2348 typedef typename traits_type::iterator_category iterator_category;
2349 return min_element_switch(begin, end, comp, iterator_category(),
2353 template<typename ForwardIterator, typename Comparator>
2354 inline ForwardIterator
2355 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
2357 typedef iterator_traits<ForwardIterator> traits_type;
2358 typedef typename traits_type::iterator_category iterator_category;
2359 return min_element_switch(begin, end, comp, iterator_category());
2364 #endif /* _GLIBCXX_PARALLEL_ALGO_H */