3 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 // MA 02111-1307, USA.
21 // As a special exception, you may use this file as part of a free
22 // software library without restriction. Specifically, if other files
23 // instantiate templates or use macros or inline functions from this
24 // file, or you compile this file and link it with other files to
25 // produce an executable, this file does not by itself cause the
26 // resulting executable to be covered by the GNU General Public
27 // License. This exception does not however invalidate any other
28 // reasons why the executable file might be covered by the GNU General
31 /** @file parallel/algo.h
32 * @brief Parallel STL function calls corresponding to the stl_algo.h header.
34 * The functions defined here mainly do case switches and
35 * call the actual parallelized versions in other files.
36 * Inlining policy: Functions that basically only contain one function call,
37 * are declared inline.
38 * This file is a GNU parallel extension to the Standard C++ Library.
41 // Written by Johannes Singler and Felix Putze.
43 #ifndef _GLIBCXX_PARALLEL_ALGO_H
44 #define _GLIBCXX_PARALLEL_ALGO_H 1
46 #include <parallel/algorithmfwd.h>
47 #include <bits/stl_algobase.h>
48 #include <bits/stl_algo.h>
49 #include <parallel/iterator.h>
50 #include <parallel/base.h>
51 #include <parallel/sort.h>
52 #include <parallel/workstealing.h>
53 #include <parallel/par_loop.h>
54 #include <parallel/omp_loop.h>
55 #include <parallel/omp_loop_static.h>
56 #include <parallel/for_each_selectors.h>
57 #include <parallel/for_each.h>
58 #include <parallel/find.h>
59 #include <parallel/find_selectors.h>
60 #include <parallel/search.h>
61 #include <parallel/random_shuffle.h>
62 #include <parallel/partition.h>
63 #include <parallel/merge.h>
64 #include <parallel/unique_copy.h>
65 #include <parallel/set_operations.h>
71 // Sequential fallback
72 template<typename InputIterator, typename Function>
74 for_each(InputIterator begin, InputIterator end, Function f,
75 __gnu_parallel::sequential_tag)
76 { return _GLIBCXX_STD_P::for_each(begin, end, f); }
78 // Sequential fallback for input iterator case
79 template<typename InputIterator, typename Function, typename IteratorTag>
81 for_each_switch(InputIterator begin, InputIterator end, Function f,
83 { return for_each(begin, end, f, __gnu_parallel::sequential_tag()); }
85 // Parallel algorithm for random access iterators
86 template<typename RandomAccessIterator, typename Function>
88 for_each_switch(RandomAccessIterator begin, RandomAccessIterator end,
89 Function f, random_access_iterator_tag,
90 __gnu_parallel::_Parallelism parallelism_tag
91 = __gnu_parallel::parallel_balanced)
93 if (_GLIBCXX_PARALLEL_CONDITION(
94 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
95 >= __gnu_parallel::_Settings::get().for_each_minimal_n
96 && __gnu_parallel::is_parallel(parallelism_tag)))
99 __gnu_parallel::for_each_selector<RandomAccessIterator> functionality;
101 return __gnu_parallel::
102 for_each_template_random_access(begin, end, f, functionality,
103 __gnu_parallel::dummy_reduct(),
104 true, dummy, -1, parallelism_tag);
107 return for_each(begin, end, f, __gnu_parallel::sequential_tag());
111 template<typename Iterator, typename Function>
113 for_each(Iterator begin, Iterator end, Function f,
114 __gnu_parallel::_Parallelism parallelism_tag)
116 typedef std::iterator_traits<Iterator> iterator_traits;
117 typedef typename iterator_traits::iterator_category iterator_category;
118 return for_each_switch(begin, end, f, iterator_category(),
122 template<typename Iterator, typename Function>
124 for_each(Iterator begin, Iterator end, Function f)
126 typedef std::iterator_traits<Iterator> iterator_traits;
127 typedef typename iterator_traits::iterator_category iterator_category;
128 return for_each_switch(begin, end, f, iterator_category());
132 // Sequential fallback
133 template<typename InputIterator, typename T>
135 find(InputIterator begin, InputIterator end, const T& val,
136 __gnu_parallel::sequential_tag)
137 { return _GLIBCXX_STD_P::find(begin, end, val); }
139 // Sequential fallback for input iterator case
140 template<typename InputIterator, typename T, typename IteratorTag>
142 find_switch(InputIterator begin, InputIterator end, const T& val,
144 { return _GLIBCXX_STD_P::find(begin, end, val); }
146 // Parallel find for random access iterators
147 template<typename RandomAccessIterator, typename T>
149 find_switch(RandomAccessIterator begin, RandomAccessIterator end,
150 const T& val, random_access_iterator_tag)
152 typedef iterator_traits<RandomAccessIterator> traits_type;
153 typedef typename traits_type::value_type value_type;
155 if (_GLIBCXX_PARALLEL_CONDITION(true))
157 binder2nd<__gnu_parallel::equal_to<value_type, T> >
158 comp(__gnu_parallel::equal_to<value_type, T>(), val);
159 return __gnu_parallel::find_template(begin, end, begin, comp,
161 find_if_selector()).first;
164 return _GLIBCXX_STD_P::find(begin, end, val);
168 template<typename InputIterator, typename T>
170 find(InputIterator begin, InputIterator end, const T& val)
172 typedef std::iterator_traits<InputIterator> iterator_traits;
173 typedef typename iterator_traits::iterator_category iterator_category;
174 return find_switch(begin, end, val, iterator_category());
177 // Sequential fallback
178 template<typename InputIterator, typename Predicate>
180 find_if(InputIterator begin, InputIterator end, Predicate pred,
181 __gnu_parallel::sequential_tag)
182 { return _GLIBCXX_STD_P::find_if(begin, end, pred); }
184 // Sequential fallback for input iterator case
185 template<typename InputIterator, typename Predicate, typename IteratorTag>
187 find_if_switch(InputIterator begin, InputIterator end, Predicate pred,
189 { return _GLIBCXX_STD_P::find_if(begin, end, pred); }
191 // Parallel find_if for random access iterators
192 template<typename RandomAccessIterator, typename Predicate>
194 find_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
195 Predicate pred, random_access_iterator_tag)
197 if (_GLIBCXX_PARALLEL_CONDITION(true))
198 return __gnu_parallel::find_template(begin, end, begin, pred,
200 find_if_selector()).first;
202 return _GLIBCXX_STD_P::find_if(begin, end, pred);
206 template<typename InputIterator, typename Predicate>
208 find_if(InputIterator begin, InputIterator end, Predicate pred)
210 typedef std::iterator_traits<InputIterator> iterator_traits;
211 typedef typename iterator_traits::iterator_category iterator_category;
212 return find_if_switch(begin, end, pred, iterator_category());
215 // Sequential fallback
216 template<typename InputIterator, typename ForwardIterator>
218 find_first_of(InputIterator begin1, InputIterator end1,
219 ForwardIterator begin2, ForwardIterator end2,
220 __gnu_parallel::sequential_tag)
221 { return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2); }
223 // Sequential fallback
224 template<typename InputIterator, typename ForwardIterator,
225 typename BinaryPredicate>
227 find_first_of(InputIterator begin1, InputIterator end1,
228 ForwardIterator begin2, ForwardIterator end2,
229 BinaryPredicate comp, __gnu_parallel::sequential_tag)
230 { return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2, comp); }
232 // Sequential fallback for input iterator type
233 template<typename InputIterator, typename ForwardIterator,
234 typename IteratorTag1, typename IteratorTag2>
236 find_first_of_switch(InputIterator begin1, InputIterator end1,
237 ForwardIterator begin2, ForwardIterator end2,
238 IteratorTag1, IteratorTag2)
239 { return find_first_of(begin1, end1, begin2, end2,
240 __gnu_parallel::sequential_tag()); }
242 // Parallel algorithm for random access iterators
243 template<typename RandomAccessIterator, typename ForwardIterator,
244 typename BinaryPredicate, typename IteratorTag>
245 inline RandomAccessIterator
246 find_first_of_switch(RandomAccessIterator begin1,
247 RandomAccessIterator end1,
248 ForwardIterator begin2, ForwardIterator end2,
249 BinaryPredicate comp, random_access_iterator_tag,
252 return __gnu_parallel::
253 find_template(begin1, end1, begin1, comp,
254 __gnu_parallel::find_first_of_selector
255 <ForwardIterator>(begin2, end2)).first;
258 // Sequential fallback for input iterator type
259 template<typename InputIterator, typename ForwardIterator,
260 typename BinaryPredicate, typename IteratorTag1,
261 typename IteratorTag2>
263 find_first_of_switch(InputIterator begin1, InputIterator end1,
264 ForwardIterator begin2, ForwardIterator end2,
265 BinaryPredicate comp, IteratorTag1, IteratorTag2)
266 { return find_first_of(begin1, end1, begin2, end2, comp,
267 __gnu_parallel::sequential_tag()); }
270 template<typename InputIterator, typename ForwardIterator,
271 typename BinaryPredicate>
273 find_first_of(InputIterator begin1, InputIterator end1,
274 ForwardIterator begin2, ForwardIterator end2,
275 BinaryPredicate comp)
277 typedef std::iterator_traits<InputIterator> iteratori_traits;
278 typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
279 typedef typename iteratori_traits::iterator_category iteratori_category;
280 typedef typename iteratorf_traits::iterator_category iteratorf_category;
282 return find_first_of_switch(begin1, end1, begin2, end2, comp,
283 iteratori_category(), iteratorf_category());
286 // Public interface, insert default comparator
287 template<typename InputIterator, typename ForwardIterator>
289 find_first_of(InputIterator begin1, InputIterator end1,
290 ForwardIterator begin2, ForwardIterator end2)
292 typedef std::iterator_traits<InputIterator> iteratori_traits;
293 typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
294 typedef typename iteratori_traits::value_type valuei_type;
295 typedef typename iteratorf_traits::value_type valuef_type;
297 return find_first_of(begin1, end1, begin2, end2, __gnu_parallel::
298 equal_to<valuei_type, valuef_type>());
301 // Sequential fallback
302 template<typename InputIterator, typename OutputIterator>
303 inline OutputIterator
304 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
305 __gnu_parallel::sequential_tag)
306 { return _GLIBCXX_STD_P::unique_copy(begin1, end1, out); }
308 // Sequential fallback
309 template<typename InputIterator, typename OutputIterator,
311 inline OutputIterator
312 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
313 Predicate pred, __gnu_parallel::sequential_tag)
314 { return _GLIBCXX_STD_P::unique_copy(begin1, end1, out, pred); }
316 // Sequential fallback for input iterator case
317 template<typename InputIterator, typename OutputIterator,
318 typename Predicate, typename IteratorTag1, typename IteratorTag2>
319 inline OutputIterator
320 unique_copy_switch(InputIterator begin, InputIterator last,
321 OutputIterator out, Predicate pred,
322 IteratorTag1, IteratorTag2)
323 { return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred); }
325 // Parallel unique_copy for random access iterators
326 template<typename RandomAccessIterator, typename RandomAccessOutputIterator,
328 RandomAccessOutputIterator
329 unique_copy_switch(RandomAccessIterator begin, RandomAccessIterator last,
330 RandomAccessOutputIterator out, Predicate pred,
331 random_access_iterator_tag, random_access_iterator_tag)
333 if (_GLIBCXX_PARALLEL_CONDITION(
334 static_cast<__gnu_parallel::sequence_index_t>(last - begin)
335 > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
336 return __gnu_parallel::parallel_unique_copy(begin, last, out, pred);
338 return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred);
342 template<typename InputIterator, typename OutputIterator>
343 inline OutputIterator
344 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out)
346 typedef std::iterator_traits<InputIterator> iteratori_traits;
347 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
348 typedef typename iteratori_traits::iterator_category iteratori_category;
349 typedef typename iteratori_traits::value_type value_type;
350 typedef typename iteratoro_traits::iterator_category iteratoro_category;
352 return unique_copy_switch(begin1, end1, out, equal_to<value_type>(),
353 iteratori_category(), iteratoro_category());
357 template<typename InputIterator, typename OutputIterator, typename Predicate>
358 inline OutputIterator
359 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
362 typedef std::iterator_traits<InputIterator> iteratori_traits;
363 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
364 typedef typename iteratori_traits::iterator_category iteratori_category;
365 typedef typename iteratoro_traits::iterator_category iteratoro_category;
367 return unique_copy_switch(begin1, end1, out, pred, iteratori_category(),
368 iteratoro_category());
371 // Sequential fallback
372 template<typename InputIterator1, typename InputIterator2,
373 typename OutputIterator>
374 inline OutputIterator
375 set_union(InputIterator1 begin1, InputIterator1 end1,
376 InputIterator2 begin2, InputIterator2 end2,
377 OutputIterator out, __gnu_parallel::sequential_tag)
378 { return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, out); }
380 // Sequential fallback
381 template<typename InputIterator1, typename InputIterator2,
382 typename OutputIterator, typename Predicate>
383 inline OutputIterator
384 set_union(InputIterator1 begin1, InputIterator1 end1,
385 InputIterator2 begin2, InputIterator2 end2,
386 OutputIterator out, Predicate pred,
387 __gnu_parallel::sequential_tag)
388 { return _GLIBCXX_STD_P::set_union(begin1, end1,
389 begin2, end2, out, pred); }
391 // Sequential fallback for input iterator case
392 template<typename InputIterator1, typename InputIterator2,
393 typename Predicate, typename OutputIterator,
394 typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
395 inline OutputIterator
396 set_union_switch(InputIterator1 begin1, InputIterator1 end1,
397 InputIterator2 begin2, InputIterator2 end2,
398 OutputIterator result, Predicate pred, IteratorTag1,
399 IteratorTag2, IteratorTag3)
400 { return _GLIBCXX_STD_P::set_union(begin1, end1,
401 begin2, end2, result, pred); }
403 // Parallel set_union for random access iterators
404 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
405 typename OutputRandomAccessIterator, typename Predicate>
406 OutputRandomAccessIterator
407 set_union_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
408 RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
409 OutputRandomAccessIterator result, Predicate pred,
410 random_access_iterator_tag, random_access_iterator_tag,
411 random_access_iterator_tag)
413 if (_GLIBCXX_PARALLEL_CONDITION(
414 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
415 >= __gnu_parallel::_Settings::get().set_union_minimal_n
416 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
417 >= __gnu_parallel::_Settings::get().set_union_minimal_n))
418 return __gnu_parallel::parallel_set_union(begin1, end1,
419 begin2, end2, result, pred);
421 return _GLIBCXX_STD_P::set_union(begin1, end1,
422 begin2, end2, result, pred);
426 template<typename InputIterator1, typename InputIterator2,
427 typename OutputIterator>
428 inline OutputIterator
429 set_union(InputIterator1 begin1, InputIterator1 end1,
430 InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
432 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
433 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
434 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
435 typedef typename iteratori1_traits::iterator_category
437 typedef typename iteratori2_traits::iterator_category
439 typedef typename iteratoro_traits::iterator_category iteratoro_category;
440 typedef typename iteratori1_traits::value_type value1_type;
441 typedef typename iteratori2_traits::value_type value2_type;
443 return set_union_switch(begin1, end1, begin2, end2, out,
444 __gnu_parallel::less<value1_type, value2_type>(),
445 iteratori1_category(), iteratori2_category(),
446 iteratoro_category());
450 template<typename InputIterator1, typename InputIterator2,
451 typename OutputIterator, typename Predicate>
452 inline OutputIterator
453 set_union(InputIterator1 begin1, InputIterator1 end1,
454 InputIterator2 begin2, InputIterator2 end2,
455 OutputIterator out, Predicate pred)
457 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
458 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
459 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
460 typedef typename iteratori1_traits::iterator_category
462 typedef typename iteratori2_traits::iterator_category
464 typedef typename iteratoro_traits::iterator_category iteratoro_category;
466 return set_union_switch(begin1, end1, begin2, end2, out, pred,
467 iteratori1_category(), iteratori2_category(),
468 iteratoro_category());
471 // Sequential fallback.
472 template<typename InputIterator1, typename InputIterator2,
473 typename OutputIterator>
474 inline OutputIterator
475 set_intersection(InputIterator1 begin1, InputIterator1 end1,
476 InputIterator2 begin2, InputIterator2 end2,
477 OutputIterator out, __gnu_parallel::sequential_tag)
478 { return _GLIBCXX_STD_P::set_intersection(begin1, end1,
479 begin2, end2, out); }
481 // Sequential fallback.
482 template<typename InputIterator1, typename InputIterator2,
483 typename OutputIterator, typename Predicate>
484 inline OutputIterator
485 set_intersection(InputIterator1 begin1, InputIterator1 end1,
486 InputIterator2 begin2, InputIterator2 end2,
487 OutputIterator out, Predicate pred,
488 __gnu_parallel::sequential_tag)
489 { return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2, end2,
492 // Sequential fallback for input iterator case
493 template<typename InputIterator1, typename InputIterator2,
494 typename Predicate, typename OutputIterator,
495 typename IteratorTag1, typename IteratorTag2,
496 typename IteratorTag3>
497 inline OutputIterator
498 set_intersection_switch(InputIterator1 begin1, InputIterator1 end1,
499 InputIterator2 begin2, InputIterator2 end2,
500 OutputIterator result, Predicate pred,
501 IteratorTag1, IteratorTag2, IteratorTag3)
502 { return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2,
503 end2, result, pred); }
505 // Parallel set_intersection for random access iterators
506 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
507 typename OutputRandomAccessIterator, typename Predicate>
508 OutputRandomAccessIterator
509 set_intersection_switch(RandomAccessIterator1 begin1,
510 RandomAccessIterator1 end1,
511 RandomAccessIterator2 begin2,
512 RandomAccessIterator2 end2,
513 OutputRandomAccessIterator result,
515 random_access_iterator_tag,
516 random_access_iterator_tag,
517 random_access_iterator_tag)
519 if (_GLIBCXX_PARALLEL_CONDITION(
520 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
521 >= __gnu_parallel::_Settings::get().set_union_minimal_n
522 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
523 >= __gnu_parallel::_Settings::get().set_union_minimal_n))
524 return __gnu_parallel::parallel_set_intersection(begin1, end1, begin2,
527 return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2,
532 template<typename InputIterator1, typename InputIterator2,
533 typename OutputIterator>
534 inline OutputIterator
535 set_intersection(InputIterator1 begin1, InputIterator1 end1,
536 InputIterator2 begin2, InputIterator2 end2,
539 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
540 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
541 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
542 typedef typename iteratori1_traits::iterator_category
544 typedef typename iteratori2_traits::iterator_category
546 typedef typename iteratoro_traits::iterator_category iteratoro_category;
547 typedef typename iteratori1_traits::value_type value1_type;
548 typedef typename iteratori2_traits::value_type value2_type;
550 return set_intersection_switch(begin1, end1, begin2, end2, out,
552 less<value1_type, value2_type>(),
553 iteratori1_category(),
554 iteratori2_category(),
555 iteratoro_category());
558 template<typename InputIterator1, typename InputIterator2,
559 typename OutputIterator, typename Predicate>
560 inline OutputIterator
561 set_intersection(InputIterator1 begin1, InputIterator1 end1,
562 InputIterator2 begin2, InputIterator2 end2,
563 OutputIterator out, Predicate pred)
565 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
566 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
567 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
568 typedef typename iteratori1_traits::iterator_category
570 typedef typename iteratori2_traits::iterator_category
572 typedef typename iteratoro_traits::iterator_category iteratoro_category;
574 return set_intersection_switch(begin1, end1, begin2, end2, out, pred,
575 iteratori1_category(),
576 iteratori2_category(),
577 iteratoro_category());
580 // Sequential fallback
581 template<typename InputIterator1, typename InputIterator2,
582 typename OutputIterator>
583 inline OutputIterator
584 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
585 InputIterator2 begin2, InputIterator2 end2,
587 __gnu_parallel::sequential_tag)
588 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1,end1,
589 begin2, end2, out); }
591 // Sequential fallback
592 template<typename InputIterator1, typename InputIterator2,
593 typename OutputIterator, typename Predicate>
594 inline OutputIterator
595 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
596 InputIterator2 begin2, InputIterator2 end2,
597 OutputIterator out, Predicate pred,
598 __gnu_parallel::sequential_tag)
599 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1, begin2,
602 // Sequential fallback for input iterator case
603 template<typename InputIterator1, typename InputIterator2,
604 typename Predicate, typename OutputIterator,
605 typename IteratorTag1, typename IteratorTag2,
606 typename IteratorTag3>
607 inline OutputIterator
608 set_symmetric_difference_switch(InputIterator1 begin1,
610 InputIterator2 begin2,
612 OutputIterator result, Predicate pred,
613 IteratorTag1, IteratorTag2, IteratorTag3)
614 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1,
618 // Parallel set_symmetric_difference for random access iterators
619 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
620 typename OutputRandomAccessIterator, typename Predicate>
621 OutputRandomAccessIterator
622 set_symmetric_difference_switch(RandomAccessIterator1 begin1,
623 RandomAccessIterator1 end1,
624 RandomAccessIterator2 begin2,
625 RandomAccessIterator2 end2,
626 OutputRandomAccessIterator result,
628 random_access_iterator_tag,
629 random_access_iterator_tag,
630 random_access_iterator_tag)
632 if (_GLIBCXX_PARALLEL_CONDITION(
633 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
634 >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
635 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
636 >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
637 return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1,
641 return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1,
647 template<typename InputIterator1, typename InputIterator2,
648 typename OutputIterator>
649 inline OutputIterator
650 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
651 InputIterator2 begin2, InputIterator2 end2,
654 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
655 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
656 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
657 typedef typename iteratori1_traits::iterator_category
659 typedef typename iteratori2_traits::iterator_category
661 typedef typename iteratoro_traits::iterator_category iteratoro_category;
662 typedef typename iteratori1_traits::value_type value1_type;
663 typedef typename iteratori2_traits::value_type value2_type;
665 return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
667 less<value1_type, value2_type>(),
668 iteratori1_category(),
669 iteratori2_category(),
670 iteratoro_category());
674 template<typename InputIterator1, typename InputIterator2,
675 typename OutputIterator, typename Predicate>
676 inline OutputIterator
677 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
678 InputIterator2 begin2, InputIterator2 end2,
679 OutputIterator out, Predicate pred)
681 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
682 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
683 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
684 typedef typename iteratori1_traits::iterator_category
686 typedef typename iteratori2_traits::iterator_category
688 typedef typename iteratoro_traits::iterator_category iteratoro_category;
690 return set_symmetric_difference_switch(begin1, end1, begin2, end2, out,
691 pred, iteratori1_category(),
692 iteratori2_category(),
693 iteratoro_category());
696 // Sequential fallback.
697 template<typename InputIterator1, typename InputIterator2,
698 typename OutputIterator>
699 inline OutputIterator
700 set_difference(InputIterator1 begin1, InputIterator1 end1,
701 InputIterator2 begin2, InputIterator2 end2,
702 OutputIterator out, __gnu_parallel::sequential_tag)
703 { return _GLIBCXX_STD_P::set_difference(begin1,end1, begin2, end2, out); }
705 // Sequential fallback.
706 template<typename InputIterator1, typename InputIterator2,
707 typename OutputIterator, typename Predicate>
708 inline OutputIterator
709 set_difference(InputIterator1 begin1, InputIterator1 end1,
710 InputIterator2 begin2, InputIterator2 end2,
711 OutputIterator out, Predicate pred,
712 __gnu_parallel::sequential_tag)
713 { return _GLIBCXX_STD_P::set_difference(begin1, end1,
714 begin2, end2, out, pred); }
716 // Sequential fallback for input iterator case.
717 template<typename InputIterator1, typename InputIterator2,
718 typename Predicate, typename OutputIterator,
719 typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
720 inline OutputIterator
721 set_difference_switch(InputIterator1 begin1, InputIterator1 end1,
722 InputIterator2 begin2, InputIterator2 end2,
723 OutputIterator result, Predicate pred,
724 IteratorTag1, IteratorTag2, IteratorTag3)
725 { return _GLIBCXX_STD_P::set_difference(begin1, end1,
726 begin2, end2, result, pred); }
728 // Parallel set_difference for random access iterators
729 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
730 typename OutputRandomAccessIterator, typename Predicate>
731 OutputRandomAccessIterator
732 set_difference_switch(RandomAccessIterator1 begin1,
733 RandomAccessIterator1 end1,
734 RandomAccessIterator2 begin2,
735 RandomAccessIterator2 end2,
736 OutputRandomAccessIterator result, Predicate pred,
737 random_access_iterator_tag,
738 random_access_iterator_tag,
739 random_access_iterator_tag)
741 if (_GLIBCXX_PARALLEL_CONDITION(
742 static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
743 >= __gnu_parallel::_Settings::get().set_difference_minimal_n
744 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
745 >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
746 return __gnu_parallel::parallel_set_difference(begin1, end1,
750 return _GLIBCXX_STD_P::set_difference(begin1, end1,
751 begin2, end2, result, pred);
755 template<typename InputIterator1, typename InputIterator2,
756 typename OutputIterator>
757 inline OutputIterator
758 set_difference(InputIterator1 begin1, InputIterator1 end1,
759 InputIterator2 begin2, InputIterator2 end2,
762 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
763 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
764 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
765 typedef typename iteratori1_traits::iterator_category
767 typedef typename iteratori2_traits::iterator_category
769 typedef typename iteratoro_traits::iterator_category iteratoro_category;
770 typedef typename iteratori1_traits::value_type value1_type;
771 typedef typename iteratori2_traits::value_type value2_type;
773 return set_difference_switch(begin1, end1, begin2, end2, out,
775 less<value1_type, value2_type>(),
776 iteratori1_category(),
777 iteratori2_category(),
778 iteratoro_category());
782 template<typename InputIterator1, typename InputIterator2,
783 typename OutputIterator, typename Predicate>
784 inline OutputIterator
785 set_difference(InputIterator1 begin1, InputIterator1 end1,
786 InputIterator2 begin2, InputIterator2 end2,
787 OutputIterator out, Predicate pred)
789 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
790 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
791 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
792 typedef typename iteratori1_traits::iterator_category
794 typedef typename iteratori2_traits::iterator_category
796 typedef typename iteratoro_traits::iterator_category iteratoro_category;
798 return set_difference_switch(begin1, end1, begin2, end2, out, pred,
799 iteratori1_category(),
800 iteratori2_category(),
801 iteratoro_category());
804 // Sequential fallback
805 template<typename ForwardIterator>
806 inline ForwardIterator
807 adjacent_find(ForwardIterator begin, ForwardIterator end,
808 __gnu_parallel::sequential_tag)
809 { return _GLIBCXX_STD_P::adjacent_find(begin, end); }
811 // Sequential fallback
812 template<typename ForwardIterator, typename BinaryPredicate>
813 inline ForwardIterator
814 adjacent_find(ForwardIterator begin, ForwardIterator end,
815 BinaryPredicate binary_pred, __gnu_parallel::sequential_tag)
816 { return _GLIBCXX_STD_P::adjacent_find(begin, end, binary_pred); }
818 // Parallel algorithm for random access iterators
819 template<typename RandomAccessIterator>
821 adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
822 random_access_iterator_tag)
824 typedef iterator_traits<RandomAccessIterator> traits_type;
825 typedef typename traits_type::value_type value_type;
827 if (_GLIBCXX_PARALLEL_CONDITION(true))
829 RandomAccessIterator spot = __gnu_parallel::
830 find_template(begin, end - 1, begin, equal_to<value_type>(),
831 __gnu_parallel::adjacent_find_selector()).first;
832 if (spot == (end - 1))
838 return adjacent_find(begin, end, __gnu_parallel::sequential_tag());
841 // Sequential fallback for input iterator case
842 template<typename ForwardIterator, typename IteratorTag>
843 inline ForwardIterator
844 adjacent_find_switch(ForwardIterator begin, ForwardIterator end,
846 { return adjacent_find(begin, end, __gnu_parallel::sequential_tag()); }
849 template<typename ForwardIterator>
850 inline ForwardIterator
851 adjacent_find(ForwardIterator begin, ForwardIterator end)
853 typedef iterator_traits<ForwardIterator> traits_type;
854 typedef typename traits_type::iterator_category iterator_category;
855 return adjacent_find_switch(begin, end, iterator_category());
858 // Sequential fallback for input iterator case
859 template<typename ForwardIterator, typename BinaryPredicate,
860 typename IteratorTag>
861 inline ForwardIterator
862 adjacent_find_switch(ForwardIterator begin, ForwardIterator end,
863 BinaryPredicate pred, IteratorTag)
864 { return adjacent_find(begin, end, pred,
865 __gnu_parallel::sequential_tag()); }
867 // Parallel algorithm for random access iterators
868 template<typename RandomAccessIterator, typename BinaryPredicate>
870 adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end,
871 BinaryPredicate pred, random_access_iterator_tag)
873 if (_GLIBCXX_PARALLEL_CONDITION(true))
874 return __gnu_parallel::find_template(begin, end, begin, pred,
876 adjacent_find_selector()).first;
878 return adjacent_find(begin, end, pred,
879 __gnu_parallel::sequential_tag());
883 template<typename ForwardIterator, typename BinaryPredicate>
884 inline ForwardIterator
885 adjacent_find(ForwardIterator begin, ForwardIterator end,
886 BinaryPredicate pred)
888 typedef iterator_traits<ForwardIterator> traits_type;
889 typedef typename traits_type::iterator_category iterator_category;
890 return adjacent_find_switch(begin, end, pred, iterator_category());
893 // Sequential fallback
894 template<typename InputIterator, typename T>
895 inline typename iterator_traits<InputIterator>::difference_type
896 count(InputIterator begin, InputIterator end, const T& value,
897 __gnu_parallel::sequential_tag)
898 { return _GLIBCXX_STD_P::count(begin, end, value); }
900 // Parallel code for random access iterators
901 template<typename RandomAccessIterator, typename T>
902 typename iterator_traits<RandomAccessIterator>::difference_type
903 count_switch(RandomAccessIterator begin, RandomAccessIterator end,
904 const T& value, random_access_iterator_tag,
905 __gnu_parallel::_Parallelism parallelism_tag
906 = __gnu_parallel::parallel_unbalanced)
908 typedef iterator_traits<RandomAccessIterator> traits_type;
909 typedef typename traits_type::value_type value_type;
910 typedef typename traits_type::difference_type difference_type;
911 typedef __gnu_parallel::sequence_index_t sequence_index_t;
913 if (_GLIBCXX_PARALLEL_CONDITION(
914 static_cast<sequence_index_t>(end - begin)
915 >= __gnu_parallel::_Settings::get().count_minimal_n
916 && __gnu_parallel::is_parallel(parallelism_tag)))
918 __gnu_parallel::count_selector<RandomAccessIterator, difference_type>
920 difference_type res = 0;
922 for_each_template_random_access(begin, end, value,
924 std::plus<sequence_index_t>(),
925 res, res, -1, parallelism_tag);
929 return count(begin, end, value, __gnu_parallel::sequential_tag());
932 // Sequential fallback for input iterator case.
933 template<typename InputIterator, typename T, typename IteratorTag>
934 inline typename iterator_traits<InputIterator>::difference_type
935 count_switch(InputIterator begin, InputIterator end, const T& value,
937 { return count(begin, end, value, __gnu_parallel::sequential_tag()); }
940 template<typename InputIterator, typename T>
941 inline typename iterator_traits<InputIterator>::difference_type
942 count(InputIterator begin, InputIterator end, const T& value,
943 __gnu_parallel::_Parallelism parallelism_tag)
945 typedef iterator_traits<InputIterator> traits_type;
946 typedef typename traits_type::iterator_category iterator_category;
947 return count_switch(begin, end, value, iterator_category(),
951 template<typename InputIterator, typename T>
952 inline typename iterator_traits<InputIterator>::difference_type
953 count(InputIterator begin, InputIterator end, const T& value)
955 typedef iterator_traits<InputIterator> traits_type;
956 typedef typename traits_type::iterator_category iterator_category;
957 return count_switch(begin, end, value, iterator_category());
961 // Sequential fallback.
962 template<typename InputIterator, typename Predicate>
963 inline typename iterator_traits<InputIterator>::difference_type
964 count_if(InputIterator begin, InputIterator end, Predicate pred,
965 __gnu_parallel::sequential_tag)
966 { return _GLIBCXX_STD_P::count_if(begin, end, pred); }
968 // Parallel count_if for random access iterators
969 template<typename RandomAccessIterator, typename Predicate>
970 typename iterator_traits<RandomAccessIterator>::difference_type
971 count_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
972 Predicate pred, random_access_iterator_tag,
973 __gnu_parallel::_Parallelism parallelism_tag
974 = __gnu_parallel::parallel_unbalanced)
976 typedef iterator_traits<RandomAccessIterator> traits_type;
977 typedef typename traits_type::value_type value_type;
978 typedef typename traits_type::difference_type difference_type;
979 typedef __gnu_parallel::sequence_index_t sequence_index_t;
981 if (_GLIBCXX_PARALLEL_CONDITION(
982 static_cast<sequence_index_t>(end - begin)
983 >= __gnu_parallel::_Settings::get().count_minimal_n
984 && __gnu_parallel::is_parallel(parallelism_tag)))
986 difference_type res = 0;
988 count_if_selector<RandomAccessIterator, difference_type>
991 for_each_template_random_access(begin, end, pred,
993 std::plus<sequence_index_t>(),
994 res, res, -1, parallelism_tag);
998 return count_if(begin, end, pred, __gnu_parallel::sequential_tag());
1001 // Sequential fallback for input iterator case.
1002 template<typename InputIterator, typename Predicate, typename IteratorTag>
1003 inline typename iterator_traits<InputIterator>::difference_type
1004 count_if_switch(InputIterator begin, InputIterator end, Predicate pred,
1006 { return count_if(begin, end, pred, __gnu_parallel::sequential_tag()); }
1008 // Public interface.
1009 template<typename InputIterator, typename Predicate>
1010 inline typename iterator_traits<InputIterator>::difference_type
1011 count_if(InputIterator begin, InputIterator end, Predicate pred,
1012 __gnu_parallel::_Parallelism parallelism_tag)
1014 typedef iterator_traits<InputIterator> traits_type;
1015 typedef typename traits_type::iterator_category iterator_category;
1016 return count_if_switch(begin, end, pred, iterator_category(),
1020 template<typename InputIterator, typename Predicate>
1021 inline typename iterator_traits<InputIterator>::difference_type
1022 count_if(InputIterator begin, InputIterator end, Predicate pred)
1024 typedef iterator_traits<InputIterator> traits_type;
1025 typedef typename traits_type::iterator_category iterator_category;
1026 return count_if_switch(begin, end, pred, iterator_category());
1030 // Sequential fallback.
1031 template<typename ForwardIterator1, typename ForwardIterator2>
1032 inline ForwardIterator1
1033 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1034 ForwardIterator2 begin2, ForwardIterator2 end2,
1035 __gnu_parallel::sequential_tag)
1036 { return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2); }
1038 // Parallel algorithm for random access iterator
1039 template<typename RandomAccessIterator1, typename RandomAccessIterator2>
1040 RandomAccessIterator1
1041 search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
1042 RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
1043 random_access_iterator_tag, random_access_iterator_tag)
1045 typedef std::iterator_traits<RandomAccessIterator1> iterator1_traits;
1046 typedef typename iterator1_traits::value_type value1_type;
1047 typedef std::iterator_traits<RandomAccessIterator2> iterator2_traits;
1048 typedef typename iterator2_traits::value_type value2_type;
1050 if (_GLIBCXX_PARALLEL_CONDITION(true))
1051 return __gnu_parallel::
1052 search_template(begin1, end1, begin2, end2, __gnu_parallel::
1053 equal_to<value1_type, value2_type>());
1055 return search(begin1, end1, begin2, end2,
1056 __gnu_parallel::sequential_tag());
1059 // Sequential fallback for input iterator case
1060 template<typename ForwardIterator1, typename ForwardIterator2,
1061 typename IteratorTag1, typename IteratorTag2>
1062 inline ForwardIterator1
1063 search_switch(ForwardIterator1 begin1, ForwardIterator1 end1,
1064 ForwardIterator2 begin2, ForwardIterator2 end2,
1065 IteratorTag1, IteratorTag2)
1066 { return search(begin1, end1, begin2, end2,
1067 __gnu_parallel::sequential_tag()); }
1069 // Public interface.
1070 template<typename ForwardIterator1, typename ForwardIterator2>
1071 inline ForwardIterator1
1072 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1073 ForwardIterator2 begin2, ForwardIterator2 end2)
1075 typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
1076 typedef typename iterator1_traits::iterator_category iterator1_category;
1077 typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
1078 typedef typename iterator2_traits::iterator_category iterator2_category;
1080 return search_switch(begin1, end1, begin2, end2,
1081 iterator1_category(), iterator2_category());
1084 // Public interface.
1085 template<typename ForwardIterator1, typename ForwardIterator2,
1086 typename BinaryPredicate>
1087 inline ForwardIterator1
1088 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1089 ForwardIterator2 begin2, ForwardIterator2 end2,
1090 BinaryPredicate pred, __gnu_parallel::sequential_tag)
1091 { return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2, pred); }
1093 // Parallel algorithm for random access iterator.
1094 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1095 typename BinaryPredicate>
1096 RandomAccessIterator1
1097 search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
1098 RandomAccessIterator2 begin2, RandomAccessIterator2 end2,
1099 BinaryPredicate pred,
1100 random_access_iterator_tag, random_access_iterator_tag)
1102 if (_GLIBCXX_PARALLEL_CONDITION(true))
1103 return __gnu_parallel::search_template(begin1, end1,
1104 begin2, end2, pred);
1106 return search(begin1, end1, begin2, end2, pred,
1107 __gnu_parallel::sequential_tag());
1110 // Sequential fallback for input iterator case
1111 template<typename ForwardIterator1, typename ForwardIterator2,
1112 typename BinaryPredicate, typename IteratorTag1,
1113 typename IteratorTag2>
1114 inline ForwardIterator1
1115 search_switch(ForwardIterator1 begin1, ForwardIterator1 end1,
1116 ForwardIterator2 begin2, ForwardIterator2 end2,
1117 BinaryPredicate pred, IteratorTag1, IteratorTag2)
1118 { return search(begin1, end1, begin2, end2, pred,
1119 __gnu_parallel::sequential_tag()); }
1122 template<typename ForwardIterator1, typename ForwardIterator2,
1123 typename BinaryPredicate>
1124 inline ForwardIterator1
1125 search(ForwardIterator1 begin1, ForwardIterator1 end1,
1126 ForwardIterator2 begin2, ForwardIterator2 end2,
1127 BinaryPredicate pred)
1129 typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
1130 typedef typename iterator1_traits::iterator_category iterator1_category;
1131 typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
1132 typedef typename iterator2_traits::iterator_category iterator2_category;
1133 return search_switch(begin1, end1, begin2, end2, pred,
1134 iterator1_category(), iterator2_category());
1137 // Sequential fallback
1138 template<typename ForwardIterator, typename Integer, typename T>
1139 inline ForwardIterator
1140 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1141 const T& val, __gnu_parallel::sequential_tag)
1142 { return _GLIBCXX_STD_P::search_n(begin, end, count, val); }
1144 // Sequential fallback
1145 template<typename ForwardIterator, typename Integer, typename T,
1146 typename BinaryPredicate>
1147 inline ForwardIterator
1148 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1149 const T& val, BinaryPredicate binary_pred,
1150 __gnu_parallel::sequential_tag)
1151 { return _GLIBCXX_STD_P::search_n(begin, end, count, val, binary_pred); }
1153 // Public interface.
1154 template<typename ForwardIterator, typename Integer, typename T>
1155 inline ForwardIterator
1156 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1159 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
1160 return search_n(begin, end, count, val,
1161 __gnu_parallel::equal_to<value_type, T>());
1164 // Parallel algorithm for random access iterators.
1165 template<typename RandomAccessIterator, typename Integer,
1166 typename T, typename BinaryPredicate>
1167 RandomAccessIterator
1168 search_n_switch(RandomAccessIterator begin, RandomAccessIterator end,
1169 Integer count, const T& val, BinaryPredicate binary_pred,
1170 random_access_iterator_tag)
1172 if (_GLIBCXX_PARALLEL_CONDITION(true))
1174 __gnu_parallel::pseudo_sequence<T, Integer> ps(val, count);
1175 return __gnu_parallel::search_template(begin, end, ps.begin(),
1176 ps.end(), binary_pred);
1179 return std::__search_n(begin, end, count, val,
1180 binary_pred, random_access_iterator_tag());
1183 // Sequential fallback for input iterator case.
1184 template<typename ForwardIterator, typename Integer, typename T,
1185 typename BinaryPredicate, typename IteratorTag>
1186 inline ForwardIterator
1187 search_n_switch(ForwardIterator begin, ForwardIterator end, Integer count,
1188 const T& val, BinaryPredicate binary_pred, IteratorTag)
1189 { return __search_n(begin, end, count, val, binary_pred, IteratorTag()); }
1191 // Public interface.
1192 template<typename ForwardIterator, typename Integer, typename T,
1193 typename BinaryPredicate>
1194 inline ForwardIterator
1195 search_n(ForwardIterator begin, ForwardIterator end, Integer count,
1196 const T& val, BinaryPredicate binary_pred)
1198 return search_n_switch(begin, end, count, val, binary_pred,
1199 typename std::iterator_traits<ForwardIterator>::
1200 iterator_category());
1204 // Sequential fallback.
1205 template<typename InputIterator, typename OutputIterator,
1206 typename UnaryOperation>
1207 inline OutputIterator
1208 transform(InputIterator begin, InputIterator end, OutputIterator result,
1209 UnaryOperation unary_op, __gnu_parallel::sequential_tag)
1210 { return _GLIBCXX_STD_P::transform(begin, end, result, unary_op); }
1212 // Parallel unary transform for random access iterators.
1213 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1214 typename UnaryOperation>
1215 RandomAccessIterator2
1216 transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end,
1217 RandomAccessIterator2 result, UnaryOperation unary_op,
1218 random_access_iterator_tag, random_access_iterator_tag,
1219 __gnu_parallel::_Parallelism parallelism_tag
1220 = __gnu_parallel::parallel_balanced)
1222 if (_GLIBCXX_PARALLEL_CONDITION(
1223 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1224 >= __gnu_parallel::_Settings::get().transform_minimal_n
1225 && __gnu_parallel::is_parallel(parallelism_tag)))
1228 typedef __gnu_parallel::iterator_pair<RandomAccessIterator1,
1229 RandomAccessIterator2, random_access_iterator_tag> ip;
1230 ip begin_pair(begin, result), end_pair(end, result + (end - begin));
1231 __gnu_parallel::transform1_selector<ip> functionality;
1233 for_each_template_random_access(begin_pair, end_pair,
1234 unary_op, functionality,
1235 __gnu_parallel::dummy_reduct(),
1236 dummy, dummy, -1, parallelism_tag);
1237 return functionality.finish_iterator;
1240 return transform(begin, end, result, unary_op,
1241 __gnu_parallel::sequential_tag());
1244 // Sequential fallback for input iterator case.
1245 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1246 typename UnaryOperation, typename IteratorTag1,
1247 typename IteratorTag2>
1248 inline RandomAccessIterator2
1249 transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end,
1250 RandomAccessIterator2 result, UnaryOperation unary_op,
1251 IteratorTag1, IteratorTag2)
1252 { return transform(begin, end, result, unary_op,
1253 __gnu_parallel::sequential_tag()); }
1255 // Public interface.
1256 template<typename InputIterator, typename OutputIterator,
1257 typename UnaryOperation>
1258 inline OutputIterator
1259 transform(InputIterator begin, InputIterator end, OutputIterator result,
1260 UnaryOperation unary_op,
1261 __gnu_parallel::_Parallelism parallelism_tag)
1263 typedef std::iterator_traits<InputIterator> iteratori_traits;
1264 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1265 typedef typename iteratori_traits::iterator_category iteratori_category;
1266 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1268 return transform1_switch(begin, end, result, unary_op,
1269 iteratori_category(), iteratoro_category(),
1273 template<typename InputIterator, typename OutputIterator,
1274 typename UnaryOperation>
1275 inline OutputIterator
1276 transform(InputIterator begin, InputIterator end, OutputIterator result,
1277 UnaryOperation unary_op)
1279 typedef std::iterator_traits<InputIterator> iteratori_traits;
1280 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1281 typedef typename iteratori_traits::iterator_category iteratori_category;
1282 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1284 return transform1_switch(begin, end, result, unary_op,
1285 iteratori_category(), iteratoro_category());
1289 // Sequential fallback
1290 template<typename InputIterator1, typename InputIterator2,
1291 typename OutputIterator, typename BinaryOperation>
1292 inline OutputIterator
1293 transform(InputIterator1 begin1, InputIterator1 end1,
1294 InputIterator2 begin2, OutputIterator result,
1295 BinaryOperation binary_op, __gnu_parallel::sequential_tag)
1296 { return _GLIBCXX_STD_P::transform(begin1, end1,
1297 begin2, result, binary_op); }
1299 // Parallel binary transform for random access iterators.
1300 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
1301 typename RandomAccessIterator3, typename BinaryOperation>
1302 RandomAccessIterator3
1303 transform2_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
1304 RandomAccessIterator2 begin2,
1305 RandomAccessIterator3 result, BinaryOperation binary_op,
1306 random_access_iterator_tag, random_access_iterator_tag,
1307 random_access_iterator_tag,
1308 __gnu_parallel::_Parallelism parallelism_tag
1309 = __gnu_parallel::parallel_balanced)
1311 if (_GLIBCXX_PARALLEL_CONDITION(
1312 (end1 - begin1) >= __gnu_parallel::_Settings::get().transform_minimal_n
1313 && __gnu_parallel::is_parallel(parallelism_tag)))
1316 typedef __gnu_parallel::iterator_triple<RandomAccessIterator1,
1317 RandomAccessIterator2, RandomAccessIterator3,
1318 random_access_iterator_tag> ip;
1319 ip begin_triple(begin1, begin2, result),
1320 end_triple(end1, begin2 + (end1 - begin1),
1321 result + (end1 - begin1));
1322 __gnu_parallel::transform2_selector<ip> functionality;
1324 for_each_template_random_access(begin_triple, end_triple,
1325 binary_op, functionality,
1326 __gnu_parallel::dummy_reduct(),
1329 return functionality.finish_iterator;
1332 return transform(begin1, end1, begin2, result, binary_op,
1333 __gnu_parallel::sequential_tag());
1336 // Sequential fallback for input iterator case.
1337 template<typename InputIterator1, typename InputIterator2,
1338 typename OutputIterator, typename BinaryOperation,
1339 typename tag1, typename tag2, typename tag3>
1340 inline OutputIterator
1341 transform2_switch(InputIterator1 begin1, InputIterator1 end1,
1342 InputIterator2 begin2, OutputIterator result,
1343 BinaryOperation binary_op, tag1, tag2, tag3)
1344 { return transform(begin1, end1, begin2, result, binary_op,
1345 __gnu_parallel::sequential_tag()); }
1347 // Public interface.
1348 template<typename InputIterator1, typename InputIterator2,
1349 typename OutputIterator, typename BinaryOperation>
1350 inline OutputIterator
1351 transform(InputIterator1 begin1, InputIterator1 end1,
1352 InputIterator2 begin2, OutputIterator result,
1353 BinaryOperation binary_op,
1354 __gnu_parallel::_Parallelism parallelism_tag)
1356 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
1357 typedef typename iteratori1_traits::iterator_category
1358 iteratori1_category;
1359 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
1360 typedef typename iteratori2_traits::iterator_category
1361 iteratori2_category;
1362 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1363 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1365 return transform2_switch(begin1, end1, begin2, result, binary_op,
1366 iteratori1_category(), iteratori2_category(),
1367 iteratoro_category(), parallelism_tag);
1370 template<typename InputIterator1, typename InputIterator2,
1371 typename OutputIterator, typename BinaryOperation>
1372 inline OutputIterator
1373 transform(InputIterator1 begin1, InputIterator1 end1,
1374 InputIterator2 begin2, OutputIterator result,
1375 BinaryOperation binary_op)
1377 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
1378 typedef typename iteratori1_traits::iterator_category
1379 iteratori1_category;
1380 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
1381 typedef typename iteratori2_traits::iterator_category
1382 iteratori2_category;
1383 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1384 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1386 return transform2_switch(begin1, end1, begin2, result, binary_op,
1387 iteratori1_category(), iteratori2_category(),
1388 iteratoro_category());
1391 // Sequential fallback
1392 template<typename ForwardIterator, typename T>
1394 replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
1395 const T& new_value, __gnu_parallel::sequential_tag)
1396 { _GLIBCXX_STD_P::replace(begin, end, old_value, new_value); }
1398 // Sequential fallback for input iterator case
1399 template<typename ForwardIterator, typename T, typename IteratorTag>
1401 replace_switch(ForwardIterator begin, ForwardIterator end,
1402 const T& old_value, const T& new_value, IteratorTag)
1403 { replace(begin, end, old_value, new_value,
1404 __gnu_parallel::sequential_tag()); }
1406 // Parallel replace for random access iterators
1407 template<typename RandomAccessIterator, typename T>
1409 replace_switch(RandomAccessIterator begin, RandomAccessIterator end,
1410 const T& old_value, const T& new_value,
1411 random_access_iterator_tag,
1412 __gnu_parallel::_Parallelism parallelism_tag
1413 = __gnu_parallel::parallel_balanced)
1415 // XXX parallel version is where?
1416 replace(begin, end, old_value, new_value,
1417 __gnu_parallel::sequential_tag());
1421 template<typename ForwardIterator, typename T>
1423 replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
1424 const T& new_value, __gnu_parallel::_Parallelism parallelism_tag)
1426 typedef iterator_traits<ForwardIterator> traits_type;
1427 typedef typename traits_type::iterator_category iterator_category;
1428 replace_switch(begin, end, old_value, new_value, iterator_category(),
1432 template<typename ForwardIterator, typename T>
1434 replace(ForwardIterator begin, ForwardIterator end, const T& old_value,
1437 typedef iterator_traits<ForwardIterator> traits_type;
1438 typedef typename traits_type::iterator_category iterator_category;
1439 replace_switch(begin, end, old_value, new_value, iterator_category());
1443 // Sequential fallback
1444 template<typename ForwardIterator, typename Predicate, typename T>
1446 replace_if(ForwardIterator begin, ForwardIterator end, Predicate pred,
1447 const T& new_value, __gnu_parallel::sequential_tag)
1448 { _GLIBCXX_STD_P::replace_if(begin, end, pred, new_value); }
1450 // Sequential fallback for input iterator case
1451 template<typename ForwardIterator, typename Predicate, typename T,
1452 typename IteratorTag>
1454 replace_if_switch(ForwardIterator begin, ForwardIterator end,
1455 Predicate pred, const T& new_value, IteratorTag)
1456 { replace_if(begin, end, pred, new_value,
1457 __gnu_parallel::sequential_tag()); }
1459 // Parallel algorithm for random access iterators.
1460 template<typename RandomAccessIterator, typename Predicate, typename T>
1462 replace_if_switch(RandomAccessIterator begin, RandomAccessIterator end,
1463 Predicate pred, const T& new_value,
1464 random_access_iterator_tag,
1465 __gnu_parallel::_Parallelism parallelism_tag
1466 = __gnu_parallel::parallel_balanced)
1468 if (_GLIBCXX_PARALLEL_CONDITION(
1469 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1470 >= __gnu_parallel::_Settings::get().replace_minimal_n
1471 && __gnu_parallel::is_parallel(parallelism_tag)))
1475 replace_if_selector<RandomAccessIterator, Predicate, T>
1476 functionality(new_value);
1478 for_each_template_random_access(begin, end, pred,
1480 __gnu_parallel::dummy_reduct(),
1481 true, dummy, -1, parallelism_tag);
1484 replace_if(begin, end, pred, new_value,
1485 __gnu_parallel::sequential_tag());
1488 // Public interface.
1489 template<typename ForwardIterator, typename Predicate, typename T>
1491 replace_if(ForwardIterator begin, ForwardIterator end,
1492 Predicate pred, const T& new_value,
1493 __gnu_parallel::_Parallelism parallelism_tag)
1495 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1496 typedef typename iterator_traits::iterator_category iterator_category;
1497 replace_if_switch(begin, end, pred, new_value, iterator_category(),
1501 template<typename ForwardIterator, typename Predicate, typename T>
1503 replace_if(ForwardIterator begin, ForwardIterator end,
1504 Predicate pred, const T& new_value)
1506 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1507 typedef typename iterator_traits::iterator_category iterator_category;
1508 replace_if_switch(begin, end, pred, new_value, iterator_category());
1511 // Sequential fallback
1512 template<typename ForwardIterator, typename Generator>
1514 generate(ForwardIterator begin, ForwardIterator end, Generator gen,
1515 __gnu_parallel::sequential_tag)
1516 { _GLIBCXX_STD_P::generate(begin, end, gen); }
1518 // Sequential fallback for input iterator case.
1519 template<typename ForwardIterator, typename Generator, typename IteratorTag>
1521 generate_switch(ForwardIterator begin, ForwardIterator end, Generator gen,
1523 { generate(begin, end, gen, __gnu_parallel::sequential_tag()); }
1525 // Parallel algorithm for random access iterators.
1526 template<typename RandomAccessIterator, typename Generator>
1528 generate_switch(RandomAccessIterator begin, RandomAccessIterator end,
1529 Generator gen, random_access_iterator_tag,
1530 __gnu_parallel::_Parallelism parallelism_tag
1531 = __gnu_parallel::parallel_balanced)
1533 if (_GLIBCXX_PARALLEL_CONDITION(
1534 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1535 >= __gnu_parallel::_Settings::get().generate_minimal_n
1536 && __gnu_parallel::is_parallel(parallelism_tag)))
1539 __gnu_parallel::generate_selector<RandomAccessIterator>
1542 for_each_template_random_access(begin, end, gen, functionality,
1543 __gnu_parallel::dummy_reduct(),
1544 true, dummy, -1, parallelism_tag);
1547 generate(begin, end, gen, __gnu_parallel::sequential_tag());
1550 // Public interface.
1551 template<typename ForwardIterator, typename Generator>
1553 generate(ForwardIterator begin, ForwardIterator end,
1554 Generator gen, __gnu_parallel::_Parallelism parallelism_tag)
1556 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1557 typedef typename iterator_traits::iterator_category iterator_category;
1558 generate_switch(begin, end, gen, iterator_category(), parallelism_tag);
1561 template<typename ForwardIterator, typename Generator>
1563 generate(ForwardIterator begin, ForwardIterator end, Generator gen)
1565 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1566 typedef typename iterator_traits::iterator_category iterator_category;
1567 generate_switch(begin, end, gen, iterator_category());
1571 // Sequential fallback.
1572 template<typename OutputIterator, typename Size, typename Generator>
1573 inline OutputIterator
1574 generate_n(OutputIterator begin, Size n, Generator gen,
1575 __gnu_parallel::sequential_tag)
1576 { return _GLIBCXX_STD_P::generate_n(begin, n, gen); }
1578 // Sequential fallback for input iterator case.
1579 template<typename OutputIterator, typename Size, typename Generator,
1580 typename IteratorTag>
1581 inline OutputIterator
1582 generate_n_switch(OutputIterator begin, Size n, Generator gen, IteratorTag)
1583 { return generate_n(begin, n, gen, __gnu_parallel::sequential_tag()); }
1585 // Parallel algorithm for random access iterators.
1586 template<typename RandomAccessIterator, typename Size, typename Generator>
1587 inline RandomAccessIterator
1588 generate_n_switch(RandomAccessIterator begin, Size n, Generator gen,
1589 random_access_iterator_tag,
1590 __gnu_parallel::_Parallelism parallelism_tag
1591 = __gnu_parallel::parallel_balanced)
1593 // XXX parallel version is where?
1594 return generate_n(begin, n, gen, __gnu_parallel::sequential_tag());
1597 // Public interface.
1598 template<typename OutputIterator, typename Size, typename Generator>
1599 inline OutputIterator
1600 generate_n(OutputIterator begin, Size n, Generator gen,
1601 __gnu_parallel::_Parallelism parallelism_tag)
1603 typedef std::iterator_traits<OutputIterator> iterator_traits;
1604 typedef typename iterator_traits::iterator_category iterator_category;
1605 return generate_n_switch(begin, n, gen, iterator_category(),
1609 template<typename OutputIterator, typename Size, typename Generator>
1610 inline OutputIterator
1611 generate_n(OutputIterator begin, Size n, Generator gen)
1613 typedef std::iterator_traits<OutputIterator> iterator_traits;
1614 typedef typename iterator_traits::iterator_category iterator_category;
1615 return generate_n_switch(begin, n, gen, iterator_category());
1619 // Sequential fallback.
1620 template<typename RandomAccessIterator>
1622 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
1623 __gnu_parallel::sequential_tag)
1624 { _GLIBCXX_STD_P::random_shuffle(begin, end); }
1626 // Sequential fallback.
1627 template<typename RandomAccessIterator, typename RandomNumberGenerator>
1629 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
1630 RandomNumberGenerator& rand, __gnu_parallel::sequential_tag)
1631 { _GLIBCXX_STD_P::random_shuffle(begin, end, rand); }
1634 /** @brief Functor wrapper for std::rand(). */
1635 template<typename must_be_int = int>
1636 struct c_rand_number
1639 operator()(int limit)
1640 { return rand() % limit; }
1643 // Fill in random number generator.
1644 template<typename RandomAccessIterator>
1646 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end)
1649 // Parallelization still possible.
1650 __gnu_parallel::random_shuffle(begin, end, r);
1653 // Parallel algorithm for random access iterators.
1654 template<typename RandomAccessIterator, typename RandomNumberGenerator>
1656 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end,
1657 RandomNumberGenerator& rand)
1661 if (_GLIBCXX_PARALLEL_CONDITION(
1662 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1663 >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
1664 __gnu_parallel::parallel_random_shuffle(begin, end, rand);
1666 __gnu_parallel::sequential_random_shuffle(begin, end, rand);
1669 // Sequential fallback.
1670 template<typename ForwardIterator, typename Predicate>
1671 inline ForwardIterator
1672 partition(ForwardIterator begin, ForwardIterator end,
1673 Predicate pred, __gnu_parallel::sequential_tag)
1674 { return _GLIBCXX_STD_P::partition(begin, end, pred); }
1676 // Sequential fallback for input iterator case.
1677 template<typename ForwardIterator, typename Predicate, typename IteratorTag>
1678 inline ForwardIterator
1679 partition_switch(ForwardIterator begin, ForwardIterator end,
1680 Predicate pred, IteratorTag)
1681 { return partition(begin, end, pred, __gnu_parallel::sequential_tag()); }
1683 // Parallel algorithm for random access iterators.
1684 template<typename RandomAccessIterator, typename Predicate>
1685 RandomAccessIterator
1686 partition_switch(RandomAccessIterator begin, RandomAccessIterator end,
1687 Predicate pred, random_access_iterator_tag)
1689 if (_GLIBCXX_PARALLEL_CONDITION(
1690 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1691 >= __gnu_parallel::_Settings::get().partition_minimal_n))
1693 typedef typename std::iterator_traits<RandomAccessIterator>::
1694 difference_type difference_type;
1695 difference_type middle = __gnu_parallel::
1696 parallel_partition(begin, end, pred,
1697 __gnu_parallel::get_max_threads());
1698 return begin + middle;
1701 return partition(begin, end, pred, __gnu_parallel::sequential_tag());
1704 // Public interface.
1705 template<typename ForwardIterator, typename Predicate>
1706 inline ForwardIterator
1707 partition(ForwardIterator begin, ForwardIterator end, Predicate pred)
1709 typedef iterator_traits<ForwardIterator> traits_type;
1710 typedef typename traits_type::iterator_category iterator_category;
1711 return partition_switch(begin, end, pred, iterator_category());
1714 // Sequential fallback
1715 template<typename RandomAccessIterator>
1717 sort(RandomAccessIterator begin, RandomAccessIterator end,
1718 __gnu_parallel::sequential_tag)
1719 { _GLIBCXX_STD_P::sort(begin, end); }
1721 // Sequential fallback
1722 template<typename RandomAccessIterator, typename Comparator>
1724 sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp,
1725 __gnu_parallel::sequential_tag)
1726 { _GLIBCXX_STD_P::sort<RandomAccessIterator, Comparator>(begin, end,
1729 // Public interface, insert default comparator
1730 template<typename RandomAccessIterator>
1732 sort(RandomAccessIterator begin, RandomAccessIterator end)
1734 typedef iterator_traits<RandomAccessIterator> traits_type;
1735 typedef typename traits_type::value_type value_type;
1736 sort(begin, end, std::less<value_type>());
1739 template<typename RandomAccessIterator, typename Comparator>
1741 sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp)
1743 typedef iterator_traits<RandomAccessIterator> traits_type;
1744 typedef typename traits_type::value_type value_type;
1748 if (_GLIBCXX_PARALLEL_CONDITION(
1749 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1750 >= __gnu_parallel::_Settings::get().sort_minimal_n))
1751 __gnu_parallel::parallel_sort(begin, end, comp, false);
1753 sort(begin, end, comp, __gnu_parallel::sequential_tag());
1757 // Sequential fallback.
1758 template<typename RandomAccessIterator>
1760 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1761 __gnu_parallel::sequential_tag)
1762 { return _GLIBCXX_STD_P::stable_sort(begin, end); }
1764 // Sequential fallback.
1765 template<typename RandomAccessIterator, typename Comparator>
1767 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1768 Comparator comp, __gnu_parallel::sequential_tag)
1769 { return _GLIBCXX_STD_P::stable_sort(begin, end, comp); }
1771 template<typename RandomAccessIterator>
1773 stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
1775 typedef iterator_traits<RandomAccessIterator> traits_type;
1776 typedef typename traits_type::value_type value_type;
1777 stable_sort(begin, end, std::less<value_type>());
1780 // Parallel algorithm for random access iterators
1781 template<typename RandomAccessIterator, typename Comparator>
1783 stable_sort(RandomAccessIterator begin, RandomAccessIterator end,
1788 if (_GLIBCXX_PARALLEL_CONDITION(
1789 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1790 >= __gnu_parallel::_Settings::get().sort_minimal_n))
1791 __gnu_parallel::parallel_sort(begin, end, comp, true);
1793 stable_sort(begin, end, comp, __gnu_parallel::sequential_tag());
1797 // Sequential fallback
1798 template<typename InputIterator1, typename InputIterator2,
1799 typename OutputIterator>
1800 inline OutputIterator
1801 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
1802 InputIterator2 end2, OutputIterator result,
1803 __gnu_parallel::sequential_tag)
1804 { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result); }
1806 // Sequential fallback
1807 template<typename InputIterator1, typename InputIterator2,
1808 typename OutputIterator, typename Comparator>
1809 inline OutputIterator
1810 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
1811 InputIterator2 end2, OutputIterator result, Comparator comp,
1812 __gnu_parallel::sequential_tag)
1813 { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result, comp); }
1815 // Sequential fallback for input iterator case
1816 template<typename InputIterator1, typename InputIterator2,
1817 typename OutputIterator, typename Comparator,
1818 typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
1819 inline OutputIterator
1820 merge_switch(InputIterator1 begin1, InputIterator1 end1,
1821 InputIterator2 begin2, InputIterator2 end2,
1822 OutputIterator result, Comparator comp,
1823 IteratorTag1, IteratorTag2, IteratorTag3)
1824 { return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2,
1827 // Parallel algorithm for random access iterators
1828 template<typename InputIterator1, typename InputIterator2,
1829 typename OutputIterator, typename Comparator>
1831 merge_switch(InputIterator1 begin1, InputIterator1 end1,
1832 InputIterator2 begin2, InputIterator2 end2,
1833 OutputIterator result, Comparator comp,
1834 random_access_iterator_tag, random_access_iterator_tag,
1835 random_access_iterator_tag)
1837 if (_GLIBCXX_PARALLEL_CONDITION(
1838 (static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1)
1839 >= __gnu_parallel::_Settings::get().merge_minimal_n
1840 || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2)
1841 >= __gnu_parallel::_Settings::get().merge_minimal_n)))
1842 return __gnu_parallel::parallel_merge_advance(begin1, end1,
1844 result, (end1 - begin1)
1845 + (end2 - begin2), comp);
1847 return __gnu_parallel::merge_advance(begin1, end1, begin2, end2,
1848 result, (end1 - begin1)
1849 + (end2 - begin2), comp);
1853 template<typename InputIterator1, typename InputIterator2,
1854 typename OutputIterator, typename Comparator>
1855 inline OutputIterator
1856 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
1857 InputIterator2 end2, OutputIterator result, Comparator comp)
1859 typedef typename iterator_traits<InputIterator1>::value_type value_type;
1861 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
1862 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
1863 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1864 typedef typename iteratori1_traits::iterator_category
1865 iteratori1_category;
1866 typedef typename iteratori2_traits::iterator_category
1867 iteratori2_category;
1868 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1870 return merge_switch(begin1, end1, begin2, end2, result, comp,
1871 iteratori1_category(), iteratori2_category(),
1872 iteratoro_category());
1876 // Public interface, insert default comparator
1877 template<typename InputIterator1, typename InputIterator2,
1878 typename OutputIterator>
1879 inline OutputIterator
1880 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
1881 InputIterator2 end2, OutputIterator result)
1883 typedef std::iterator_traits<InputIterator1> iterator1_traits;
1884 typedef std::iterator_traits<InputIterator2> iterator2_traits;
1885 typedef typename iterator1_traits::value_type value1_type;
1886 typedef typename iterator2_traits::value_type value2_type;
1888 return merge(begin1, end1, begin2, end2, result,
1889 __gnu_parallel::less<value1_type, value2_type>());
1892 // Sequential fallback
1893 template<typename RandomAccessIterator>
1895 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
1896 RandomAccessIterator end, __gnu_parallel::sequential_tag)
1897 { return _GLIBCXX_STD_P::nth_element(begin, nth, end); }
1899 // Sequential fallback
1900 template<typename RandomAccessIterator, typename Comparator>
1902 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
1903 RandomAccessIterator end, Comparator comp,
1904 __gnu_parallel::sequential_tag)
1905 { return _GLIBCXX_STD_P::nth_element(begin, nth, end, comp); }
1908 template<typename RandomAccessIterator, typename Comparator>
1910 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
1911 RandomAccessIterator end, Comparator comp)
1913 if (_GLIBCXX_PARALLEL_CONDITION(
1914 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1915 >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
1916 __gnu_parallel::parallel_nth_element(begin, nth, end, comp);
1918 nth_element(begin, nth, end, comp, __gnu_parallel::sequential_tag());
1921 // Public interface, insert default comparator
1922 template<typename RandomAccessIterator>
1924 nth_element(RandomAccessIterator begin, RandomAccessIterator nth,
1925 RandomAccessIterator end)
1927 typedef iterator_traits<RandomAccessIterator> traits_type;
1928 typedef typename traits_type::value_type value_type;
1929 nth_element(begin, nth, end, std::less<value_type>());
1932 // Sequential fallback
1933 template<typename RandomAccessIterator, typename _Compare>
1935 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
1936 RandomAccessIterator end, _Compare comp,
1937 __gnu_parallel::sequential_tag)
1938 { _GLIBCXX_STD_P::partial_sort(begin, middle, end, comp); }
1940 // Sequential fallback
1941 template<typename RandomAccessIterator>
1943 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
1944 RandomAccessIterator end, __gnu_parallel::sequential_tag)
1945 { _GLIBCXX_STD_P::partial_sort(begin, middle, end); }
1947 // Public interface, parallel algorithm for random access iterators
1948 template<typename RandomAccessIterator, typename _Compare>
1950 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
1951 RandomAccessIterator end, _Compare comp)
1953 if (_GLIBCXX_PARALLEL_CONDITION(
1954 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
1955 >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
1956 __gnu_parallel::parallel_partial_sort(begin, middle, end, comp);
1958 partial_sort(begin, middle, end, comp,
1959 __gnu_parallel::sequential_tag());
1962 // Public interface, insert default comparator
1963 template<typename RandomAccessIterator>
1965 partial_sort(RandomAccessIterator begin, RandomAccessIterator middle,
1966 RandomAccessIterator end)
1968 typedef iterator_traits<RandomAccessIterator> traits_type;
1969 typedef typename traits_type::value_type value_type;
1970 partial_sort(begin, middle, end, std::less<value_type>());
1973 // Sequential fallback
1974 template<typename ForwardIterator>
1975 inline ForwardIterator
1976 max_element(ForwardIterator begin, ForwardIterator end,
1977 __gnu_parallel::sequential_tag)
1978 { return _GLIBCXX_STD_P::max_element(begin, end); }
1980 // Sequential fallback
1981 template<typename ForwardIterator, typename Comparator>
1982 inline ForwardIterator
1983 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
1984 __gnu_parallel::sequential_tag)
1985 { return _GLIBCXX_STD_P::max_element(begin, end, comp); }
1987 // Sequential fallback for input iterator case
1988 template<typename ForwardIterator, typename Comparator, typename IteratorTag>
1989 inline ForwardIterator
1990 max_element_switch(ForwardIterator begin, ForwardIterator end,
1991 Comparator comp, IteratorTag)
1992 { return max_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
1994 // Parallel algorithm for random access iterators
1995 template<typename RandomAccessIterator, typename Comparator>
1996 RandomAccessIterator
1997 max_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
1998 Comparator comp, random_access_iterator_tag,
1999 __gnu_parallel::_Parallelism parallelism_tag
2000 = __gnu_parallel::parallel_balanced)
2002 if (_GLIBCXX_PARALLEL_CONDITION(
2003 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
2004 >= __gnu_parallel::_Settings::get().max_element_minimal_n
2005 && __gnu_parallel::is_parallel(parallelism_tag)))
2007 RandomAccessIterator res(begin);
2008 __gnu_parallel::identity_selector<RandomAccessIterator>
2011 for_each_template_random_access(begin, end,
2012 __gnu_parallel::nothing(),
2015 max_element_reduct<Comparator,
2016 RandomAccessIterator>(comp),
2017 res, res, -1, parallelism_tag);
2021 return max_element(begin, end, comp, __gnu_parallel::sequential_tag());
2024 // Public interface, insert default comparator
2025 template<typename ForwardIterator>
2026 inline ForwardIterator
2027 max_element(ForwardIterator begin, ForwardIterator end,
2028 __gnu_parallel::_Parallelism parallelism_tag)
2030 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2031 return max_element(begin, end, std::less<value_type>(), parallelism_tag);
2034 template<typename ForwardIterator>
2035 inline ForwardIterator
2036 max_element(ForwardIterator begin, ForwardIterator end)
2038 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2039 return max_element(begin, end, std::less<value_type>());
2043 template<typename ForwardIterator, typename Comparator>
2044 inline ForwardIterator
2045 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
2046 __gnu_parallel::_Parallelism parallelism_tag)
2048 typedef iterator_traits<ForwardIterator> traits_type;
2049 typedef typename traits_type::iterator_category iterator_category;
2050 return max_element_switch(begin, end, comp, iterator_category(),
2054 template<typename ForwardIterator, typename Comparator>
2055 inline ForwardIterator
2056 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
2058 typedef iterator_traits<ForwardIterator> traits_type;
2059 typedef typename traits_type::iterator_category iterator_category;
2060 return max_element_switch(begin, end, comp, iterator_category());
2064 // Sequential fallback
2065 template<typename ForwardIterator>
2066 inline ForwardIterator
2067 min_element(ForwardIterator begin, ForwardIterator end,
2068 __gnu_parallel::sequential_tag)
2069 { return _GLIBCXX_STD_P::min_element(begin, end); }
2071 // Sequential fallback
2072 template<typename ForwardIterator, typename Comparator>
2073 inline ForwardIterator
2074 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
2075 __gnu_parallel::sequential_tag)
2076 { return _GLIBCXX_STD_P::min_element(begin, end, comp); }
2078 // Sequential fallback for input iterator case
2079 template<typename ForwardIterator, typename Comparator, typename IteratorTag>
2080 inline ForwardIterator
2081 min_element_switch(ForwardIterator begin, ForwardIterator end,
2082 Comparator comp, IteratorTag)
2083 { return min_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
2085 // Parallel algorithm for random access iterators
2086 template<typename RandomAccessIterator, typename Comparator>
2087 RandomAccessIterator
2088 min_element_switch(RandomAccessIterator begin, RandomAccessIterator end,
2089 Comparator comp, random_access_iterator_tag,
2090 __gnu_parallel::_Parallelism parallelism_tag
2091 = __gnu_parallel::parallel_balanced)
2093 if (_GLIBCXX_PARALLEL_CONDITION(
2094 static_cast<__gnu_parallel::sequence_index_t>(end - begin)
2095 >= __gnu_parallel::_Settings::get().min_element_minimal_n
2096 && __gnu_parallel::is_parallel(parallelism_tag)))
2098 RandomAccessIterator res(begin);
2099 __gnu_parallel::identity_selector<RandomAccessIterator>
2102 for_each_template_random_access(begin, end,
2103 __gnu_parallel::nothing(),
2106 min_element_reduct<Comparator,
2107 RandomAccessIterator>(comp),
2108 res, res, -1, parallelism_tag);
2112 return min_element(begin, end, comp, __gnu_parallel::sequential_tag());
2115 // Public interface, insert default comparator
2116 template<typename ForwardIterator>
2117 inline ForwardIterator
2118 min_element(ForwardIterator begin, ForwardIterator end,
2119 __gnu_parallel::_Parallelism parallelism_tag)
2121 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2122 return min_element(begin, end, std::less<value_type>(), parallelism_tag);
2125 template<typename ForwardIterator>
2126 inline ForwardIterator
2127 min_element(ForwardIterator begin, ForwardIterator end)
2129 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
2130 return min_element(begin, end, std::less<value_type>());
2134 template<typename ForwardIterator, typename Comparator>
2135 inline ForwardIterator
2136 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp,
2137 __gnu_parallel::_Parallelism parallelism_tag)
2139 typedef iterator_traits<ForwardIterator> traits_type;
2140 typedef typename traits_type::iterator_category iterator_category;
2141 return min_element_switch(begin, end, comp, iterator_category(),
2145 template<typename ForwardIterator, typename Comparator>
2146 inline ForwardIterator
2147 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp)
2149 typedef iterator_traits<ForwardIterator> traits_type;
2150 typedef typename traits_type::iterator_category iterator_category;
2151 return min_element_switch(begin, end, comp, iterator_category());
2156 #endif /* _GLIBCXX_ALGORITHM_H */