Merged with mainline at revision 128810.
[official-gcc.git] / libstdc++-v3 / include / parallel / algo.h
blobdcda79090b4f0eeaf0d6f4efe91b65659833e7ec
1 // -*- C++ -*-
3 // Copyright (C) 2007 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 2, or (at your option) any later
9 // version.
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
29 // Public License.
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>
67 namespace std
69 namespace __parallel
71 // Sequential fallback
72 template<typename InputIterator, typename Function>
73 inline Function
74 for_each(InputIterator begin, InputIterator end, Function f, __gnu_parallel::sequential_tag)
76 return _GLIBCXX_STD_P::for_each<InputIterator, Function>(begin, end, f);
79 // Sequential fallback for input iterator case
80 template<typename InputIterator, typename Function, typename IteratorTag>
81 Function
82 for_each_switch(InputIterator begin, InputIterator end, Function f, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
84 return for_each<InputIterator, Function>(begin, end, f, __gnu_parallel::sequential_tag());
87 // Parallel algorithm for random access iterators
88 template<typename RandomAccessIterator, typename Function>
89 Function
90 for_each_switch(RandomAccessIterator begin, RandomAccessIterator end, Function f, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
92 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::for_each_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
94 bool dummy;
95 __gnu_parallel::for_each_selector<RandomAccessIterator> functionality;
96 return __gnu_parallel::for_each_template_random_access(begin, end, f, functionality, __gnu_parallel::dummy_reduct(), true, dummy, -1, parallelism_tag);
98 else
99 return for_each<RandomAccessIterator, Function>(begin, end, f, __gnu_parallel::sequential_tag());
102 // Public interface
103 template<typename Iterator, typename Function>
104 inline Function
105 for_each(Iterator begin, Iterator end, Function f, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
107 typedef std::iterator_traits<Iterator> iterator_traits;
108 typedef typename iterator_traits::iterator_category iterator_category;
110 return for_each_switch(begin, end, f, iterator_category(), parallelism_tag);
114 // Sequential fallback
115 template<typename InputIterator, typename T>
116 inline InputIterator
117 find(InputIterator begin, InputIterator end, const T& val, __gnu_parallel::sequential_tag)
118 { return _GLIBCXX_STD_P::find<InputIterator, T>(begin, end, val); }
120 // Sequential fallback for input iterator case
121 template<typename InputIterator, typename T, typename IteratorTag>
122 inline InputIterator
123 find_switch(InputIterator begin, InputIterator end, const T& val, IteratorTag)
124 { return _GLIBCXX_STD_P::find(begin, end, val); }
126 // Parallel find for random access iterators
127 template<typename RandomAccessIterator, typename T>
128 RandomAccessIterator
129 find_switch(RandomAccessIterator begin, RandomAccessIterator end, const T& val, random_access_iterator_tag)
131 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
133 if (_GLIBCXX_PARALLEL_CONDITION(true))
135 binder2nd<__gnu_parallel::equal_to<value_type, T> > comp(__gnu_parallel::equal_to<value_type, T>(), val);
136 return __gnu_parallel::find_template(begin, end, begin, comp, __gnu_parallel::find_if_selector()).first;
138 else
139 return _GLIBCXX_STD_P::find(begin, end, val);
142 // Public interface
143 template<typename InputIterator, typename T>
144 inline InputIterator
145 find(InputIterator begin, InputIterator end, const T& val)
147 typedef std::iterator_traits<InputIterator> iterator_traits;
148 typedef typename iterator_traits::iterator_category iterator_category;
149 return find_switch(begin, end, val, iterator_category());
152 // Sequential fallback
153 template<typename InputIterator, typename Predicate>
154 inline InputIterator
155 find_if(InputIterator begin, InputIterator end, Predicate pred, __gnu_parallel::sequential_tag)
157 return _GLIBCXX_STD_P::find_if<InputIterator, Predicate>(begin, end, pred);
160 // Sequential fallback for input iterator case
161 template<typename InputIterator, typename Predicate, typename IteratorTag>
162 inline InputIterator
163 find_if_switch(InputIterator begin, InputIterator end, Predicate pred, IteratorTag)
165 return _GLIBCXX_STD_P::find_if(begin, end, pred);
168 // Parallel find_if for random access iterators
169 template<typename RandomAccessIterator, typename Predicate>
170 RandomAccessIterator
171 find_if_switch(RandomAccessIterator begin, RandomAccessIterator end, Predicate pred, random_access_iterator_tag)
173 if (_GLIBCXX_PARALLEL_CONDITION(true))
174 return __gnu_parallel::find_template(begin, end, begin, pred, __gnu_parallel::find_if_selector()).first;
175 else
176 return _GLIBCXX_STD_P::find_if(begin, end, pred);
179 // Public interface
180 template<typename InputIterator, typename Predicate>
181 inline InputIterator
182 find_if (InputIterator begin, InputIterator end, Predicate pred)
184 typedef std::iterator_traits<InputIterator> iterator_traits;
185 typedef typename iterator_traits::iterator_category iterator_category;
186 return find_if_switch(begin, end, pred, iterator_category());
189 // Sequential fallback
190 template<typename InputIterator, typename ForwardIterator>
191 inline InputIterator
192 find_first_of(InputIterator begin1, InputIterator end1, ForwardIterator begin2, ForwardIterator end2, __gnu_parallel::sequential_tag)
194 return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2);
197 // Sequential fallback
198 template<typename InputIterator, typename ForwardIterator,
199 typename BinaryPredicate>
200 inline InputIterator
201 find_first_of(InputIterator begin1, InputIterator end1,
202 ForwardIterator begin2, ForwardIterator end2,
203 BinaryPredicate comp, __gnu_parallel::sequential_tag)
205 return _GLIBCXX_STD_P::find_first_of(begin1, end1, begin2, end2, comp);
208 // Sequential fallback for input iterator type
209 template<typename InputIterator, typename ForwardIterator, typename IteratorTag1, typename IteratorTag2>
210 inline InputIterator
211 find_first_of_switch(InputIterator begin1, InputIterator end1,
212 ForwardIterator begin2, ForwardIterator end2, IteratorTag1, IteratorTag2)
214 return find_first_of(begin1, end1, begin2, end2, __gnu_parallel::sequential_tag());
217 // Parallel algorithm for random access iterators
218 template<typename RandomAccessIterator, typename ForwardIterator, typename BinaryPredicate, typename IteratorTag>
219 inline RandomAccessIterator
220 find_first_of_switch(RandomAccessIterator begin1, RandomAccessIterator end1,
221 ForwardIterator begin2, ForwardIterator end2, BinaryPredicate comp, random_access_iterator_tag, IteratorTag)
223 return __gnu_parallel::find_template(begin1, end1, begin1, comp, __gnu_parallel::find_first_of_selector<ForwardIterator>(begin2, end2)).first;
226 // Sequential fallback for input iterator type
227 template<typename InputIterator, typename ForwardIterator, typename BinaryPredicate, typename IteratorTag1, typename IteratorTag2>
228 inline
229 InputIterator
230 find_first_of_switch(InputIterator begin1, InputIterator end1,
231 ForwardIterator begin2, ForwardIterator end2, BinaryPredicate comp, IteratorTag1, IteratorTag2)
233 return find_first_of(begin1, end1, begin2, end2, comp, __gnu_parallel::sequential_tag());
236 // Public interface
237 template<typename InputIterator, typename ForwardIterator, typename BinaryPredicate>
238 inline InputIterator
239 find_first_of(InputIterator begin1, InputIterator end1,
240 ForwardIterator begin2, ForwardIterator end2, BinaryPredicate comp)
242 typedef std::iterator_traits<InputIterator> iteratori_traits;
243 typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
244 typedef typename iteratori_traits::iterator_category iteratori_category;
245 typedef typename iteratorf_traits::iterator_category iteratorf_category;
247 return find_first_of_switch(begin1, end1, begin2, end2, comp, iteratori_category(), iteratorf_category());
250 // Public interface, insert default comparator
251 template<typename InputIterator, typename ForwardIterator>
252 InputIterator
253 find_first_of(InputIterator begin1, InputIterator end1, ForwardIterator begin2, ForwardIterator end2)
255 typedef std::iterator_traits<InputIterator> iteratori_traits;
256 typedef std::iterator_traits<ForwardIterator> iteratorf_traits;
257 typedef typename iteratori_traits::value_type valuei_type;
258 typedef typename iteratorf_traits::value_type valuef_type;
260 return find_first_of(begin1, end1, begin2, end2, __gnu_parallel::equal_to<valuei_type, valuef_type>());
263 // Sequential fallback
264 template<typename InputIterator, typename OutputIterator>
265 inline OutputIterator
266 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
267 __gnu_parallel::sequential_tag)
269 return _GLIBCXX_STD_P::unique_copy<InputIterator, OutputIterator>(begin1, end1, out);
272 // Sequential fallback
273 template<typename InputIterator, typename OutputIterator, typename Predicate>
274 inline OutputIterator
275 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
276 Predicate pred, __gnu_parallel::sequential_tag)
278 return _GLIBCXX_STD_P::unique_copy<InputIterator, OutputIterator, Predicate>(begin1, end1, out, pred);
281 // Sequential fallback for input iterator case
282 template<typename InputIterator, typename OutputIterator, typename Predicate, typename IteratorTag1, typename IteratorTag2>
283 inline OutputIterator
284 unique_copy_switch(InputIterator begin, InputIterator last, OutputIterator out,
285 Predicate pred, IteratorTag1, IteratorTag2)
287 return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred);
290 // Parallel unique_copy for random access iterators
291 template<typename RandomAccessIterator, typename RandomAccessOutputIterator, typename Predicate>
292 RandomAccessOutputIterator
293 unique_copy_switch(RandomAccessIterator begin, RandomAccessIterator last, RandomAccessOutputIterator out,
294 Predicate pred, random_access_iterator_tag, random_access_iterator_tag)
296 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(last - begin) > __gnu_parallel::Settings::unique_copy_minimal_n))
297 return __gnu_parallel::parallel_unique_copy(begin, last, out, pred);
298 else
299 return _GLIBCXX_STD_P::unique_copy(begin, last, out, pred);
302 // Public interface
303 template<typename InputIterator, typename OutputIterator>
304 inline OutputIterator
305 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out)
307 typedef std::iterator_traits<InputIterator> iteratori_traits;
308 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
309 typedef typename iteratori_traits::iterator_category iteratori_category;
310 typedef typename iteratori_traits::value_type value_type;
311 typedef typename iteratoro_traits::iterator_category iteratoro_category;
313 return unique_copy_switch(begin1, end1, out, equal_to<value_type>(),
314 iteratori_category(), iteratoro_category());
317 // Public interface
318 template<typename InputIterator, typename OutputIterator, typename Predicate>
319 inline OutputIterator
320 unique_copy(InputIterator begin1, InputIterator end1, OutputIterator out,
321 Predicate pred)
323 typedef std::iterator_traits<InputIterator> iteratori_traits;
324 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
325 typedef typename iteratori_traits::iterator_category iteratori_category;
326 typedef typename iteratoro_traits::iterator_category iteratoro_category;
328 return unique_copy_switch(begin1, end1, out, pred, iteratori_category(), iteratoro_category());
331 // Sequential fallback
332 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
333 inline OutputIterator
334 set_union(InputIterator1 begin1, InputIterator1 end1,
335 InputIterator2 begin2, InputIterator2 end2,
336 OutputIterator out, __gnu_parallel::sequential_tag)
338 return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, out);
341 // Sequential fallback
342 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
343 inline OutputIterator
344 set_union(InputIterator1 begin1, InputIterator1 end1,
345 InputIterator2 begin2, InputIterator2 end2,
346 OutputIterator out, Predicate pred, __gnu_parallel::sequential_tag)
348 return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, out, pred);
351 // Sequential fallback for input iterator case
352 template<typename InputIterator1, typename InputIterator2, typename Predicate,
353 typename OutputIterator, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
354 inline OutputIterator
355 set_union_switch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
356 InputIterator2 end2, OutputIterator result, Predicate pred, IteratorTag1,
357 IteratorTag2, IteratorTag3)
359 return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, result, pred);
362 // Parallel set_union for random access iterators
363 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
364 typename OutputRandomAccessIterator, typename Predicate>
365 OutputRandomAccessIterator
366 set_union_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2,
367 RandomAccessIterator2 end2, OutputRandomAccessIterator result, Predicate pred,
368 random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
370 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) >= __gnu_parallel::Settings::set_union_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::set_union_minimal_n))
371 return __gnu_parallel::parallel_set_union(begin1, end1, begin2, end2, result, pred);
372 else
373 return _GLIBCXX_STD_P::set_union(begin1, end1, begin2, end2, result, pred);
376 // Public interface
377 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
378 inline OutputIterator
379 set_union(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
381 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
382 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
383 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
384 typedef typename iteratori1_traits::iterator_category iteratori1_category;
385 typedef typename iteratori2_traits::iterator_category iteratori2_category;
386 typedef typename iteratoro_traits::iterator_category iteratoro_category;
387 typedef typename iteratori1_traits::value_type value1_type;
388 typedef typename iteratori2_traits::value_type value2_type;
390 return set_union_switch(begin1, end1, begin2, end2, out, __gnu_parallel::less<value1_type, value2_type>(),
391 iteratori1_category(), iteratori2_category(), iteratoro_category());
394 // Public interface
395 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
396 inline OutputIterator
397 set_union(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
398 InputIterator2 end2, OutputIterator out, Predicate pred)
400 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
401 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
402 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
403 typedef typename iteratori1_traits::iterator_category iteratori1_category;
404 typedef typename iteratori2_traits::iterator_category iteratori2_category;
405 typedef typename iteratoro_traits::iterator_category iteratoro_category;
407 return set_union_switch(begin1, end1, begin2, end2, out, pred,
408 iteratori1_category(), iteratori2_category(), iteratoro_category());
411 // Sequential fallback.
412 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
413 inline OutputIterator
414 set_intersection(InputIterator1 begin1, InputIterator1 end1,
415 InputIterator2 begin2, InputIterator2 end2,
416 OutputIterator out, __gnu_parallel::sequential_tag)
418 return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2, end2, out);
421 // Sequential fallback.
422 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
423 inline OutputIterator
424 set_intersection(InputIterator1 begin1, InputIterator1 end1,
425 InputIterator2 begin2, InputIterator2 end2,
426 OutputIterator out, Predicate pred, __gnu_parallel::sequential_tag)
428 return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2, end2, out, pred);
431 // Sequential fallback for input iterator case
432 template<typename InputIterator1, typename InputIterator2, typename Predicate,
433 typename OutputIterator, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
434 inline OutputIterator
435 set_intersection_switch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
436 InputIterator2 end2, OutputIterator result, Predicate pred, IteratorTag1,
437 IteratorTag2, IteratorTag3)
439 return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2, end2, result, pred);
442 // Parallel set_intersection for random access iterators
443 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
444 typename OutputRandomAccessIterator, typename Predicate>
445 OutputRandomAccessIterator
446 set_intersection_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2,
447 RandomAccessIterator2 end2, OutputRandomAccessIterator result, Predicate pred,
448 random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
450 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) >= __gnu_parallel::Settings::set_union_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::set_union_minimal_n))
451 return __gnu_parallel::parallel_set_intersection(begin1, end1, begin2, end2, result, pred);
452 else
453 return _GLIBCXX_STD_P::set_intersection(begin1, end1, begin2, end2, result, pred);
456 // Public interface
457 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
458 inline OutputIterator
459 set_intersection(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
461 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
462 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
463 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
464 typedef typename iteratori1_traits::iterator_category iteratori1_category;
465 typedef typename iteratori2_traits::iterator_category iteratori2_category;
466 typedef typename iteratoro_traits::iterator_category iteratoro_category;
467 typedef typename iteratori1_traits::value_type value1_type;
468 typedef typename iteratori2_traits::value_type value2_type;
470 return set_intersection_switch(begin1, end1, begin2, end2, out, __gnu_parallel::less<value1_type, value2_type>(),
471 iteratori1_category(), iteratori2_category(), iteratoro_category());
474 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
475 inline OutputIterator
476 set_intersection(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
477 InputIterator2 end2, OutputIterator out, Predicate pred)
479 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
480 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
481 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
482 typedef typename iteratori1_traits::iterator_category iteratori1_category;
483 typedef typename iteratori2_traits::iterator_category iteratori2_category;
484 typedef typename iteratoro_traits::iterator_category iteratoro_category;
486 return set_intersection_switch(begin1, end1, begin2, end2, out, pred,
487 iteratori1_category(), iteratori2_category(), iteratoro_category());
490 // Sequential fallback
491 template<typename InputIterator1, typename InputIterator2,
492 typename OutputIterator>
493 inline OutputIterator
494 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
495 InputIterator2 begin2, InputIterator2 end2,
496 OutputIterator out, __gnu_parallel::sequential_tag)
498 return _GLIBCXX_STD_P::set_symmetric_difference(begin1,end1, begin2, end2, out);
501 // Sequential fallback
502 template<typename InputIterator1, typename InputIterator2,
503 typename OutputIterator, typename Predicate>
504 inline OutputIterator
505 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1,
506 InputIterator2 begin2, InputIterator2 end2,
507 OutputIterator out, Predicate pred, __gnu_parallel::sequential_tag)
509 return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1, begin2, end2, out, pred);
512 // Sequential fallback for input iterator case
513 template<typename InputIterator1, typename InputIterator2, typename Predicate, typename OutputIterator, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
514 inline OutputIterator
515 set_symmetric_difference_switch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator result, Predicate pred, IteratorTag1, IteratorTag2, IteratorTag3)
517 return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1, begin2, end2, result, pred);
520 // Parallel set_symmetric_difference for random access iterators
521 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
522 typename OutputRandomAccessIterator, typename Predicate>
523 OutputRandomAccessIterator
524 set_symmetric_difference_switch(RandomAccessIterator1 begin1,
525 RandomAccessIterator1 end1, RandomAccessIterator2 begin2,
526 RandomAccessIterator2 end2, OutputRandomAccessIterator result, Predicate pred,
527 random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
529 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n))
530 return __gnu_parallel::parallel_set_symmetric_difference(begin1, end1, begin2, end2, result, pred);
531 else
532 return _GLIBCXX_STD_P::set_symmetric_difference(begin1, end1, begin2, end2, result, pred);
535 // Public interface.
536 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
537 inline OutputIterator
538 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
540 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
541 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
542 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
543 typedef typename iteratori1_traits::iterator_category iteratori1_category;
544 typedef typename iteratori2_traits::iterator_category iteratori2_category;
545 typedef typename iteratoro_traits::iterator_category iteratoro_category;
546 typedef typename iteratori1_traits::value_type value1_type;
547 typedef typename iteratori2_traits::value_type value2_type;
549 return set_symmetric_difference_switch(begin1, end1, begin2, end2, out, __gnu_parallel::less<value1_type, value2_type>(),
550 iteratori1_category(), iteratori2_category(), iteratoro_category());
553 // Public interface.
554 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
555 inline OutputIterator
556 set_symmetric_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
557 InputIterator2 end2, OutputIterator out, Predicate pred)
559 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
560 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
561 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
562 typedef typename iteratori1_traits::iterator_category iteratori1_category;
563 typedef typename iteratori2_traits::iterator_category iteratori2_category;
564 typedef typename iteratoro_traits::iterator_category iteratoro_category;
566 return set_symmetric_difference_switch(begin1, end1, begin2, end2, out, pred,
567 iteratori1_category(), iteratori2_category(), iteratoro_category());
570 // Sequential fallback.
571 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
572 inline OutputIterator
573 set_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out, __gnu_parallel::sequential_tag)
575 return _GLIBCXX_STD_P::set_difference(begin1,end1, begin2, end2, out);
578 // Sequential fallback.
579 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
580 inline OutputIterator
581 set_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out, Predicate pred, __gnu_parallel::sequential_tag)
583 return _GLIBCXX_STD_P::set_difference(begin1, end1, begin2, end2, out, pred);
586 // Sequential fallback for input iterator case.
587 template<typename InputIterator1, typename InputIterator2, typename Predicate,
588 typename OutputIterator, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
589 inline OutputIterator
590 set_difference_switch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
591 InputIterator2 end2, OutputIterator result, Predicate pred, IteratorTag1, IteratorTag2, IteratorTag3)
593 return _GLIBCXX_STD_P::set_difference(begin1, end1, begin2, end2, result, pred);
596 // Parallel set_difference for random access iterators
597 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
598 typename OutputRandomAccessIterator, typename Predicate>
599 OutputRandomAccessIterator
600 set_difference_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2,
601 RandomAccessIterator2 end2, OutputRandomAccessIterator result, Predicate pred,
602 random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
604 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) >= __gnu_parallel::Settings::set_difference_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::set_difference_minimal_n))
605 return __gnu_parallel::parallel_set_difference(begin1, end1, begin2, end2, result, pred);
606 else
607 return _GLIBCXX_STD_P::set_difference(begin1, end1, begin2, end2, result, pred);
610 // Public interface
611 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
612 inline OutputIterator
613 set_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator out)
615 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
616 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
617 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
618 typedef typename iteratori1_traits::iterator_category iteratori1_category;
619 typedef typename iteratori2_traits::iterator_category iteratori2_category;
620 typedef typename iteratoro_traits::iterator_category iteratoro_category;
621 typedef typename iteratori1_traits::value_type value1_type;
622 typedef typename iteratori2_traits::value_type value2_type;
624 return set_difference_switch(begin1, end1, begin2, end2, out, __gnu_parallel::less<value1_type, value2_type>(),
625 iteratori1_category(), iteratori2_category(), iteratoro_category());
628 // Public interface
629 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Predicate>
630 inline OutputIterator
631 set_difference(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2,
632 InputIterator2 end2, OutputIterator out, Predicate pred)
634 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
635 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
636 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
637 typedef typename iteratori1_traits::iterator_category iteratori1_category;
638 typedef typename iteratori2_traits::iterator_category iteratori2_category;
639 typedef typename iteratoro_traits::iterator_category iteratoro_category;
641 return set_difference_switch(begin1, end1, begin2, end2, out, pred,
642 iteratori1_category(), iteratori2_category(), iteratoro_category());
645 // Sequential fallback
646 template<typename ForwardIterator>
647 inline ForwardIterator
648 adjacent_find(ForwardIterator begin, ForwardIterator end, __gnu_parallel::sequential_tag)
650 return _GLIBCXX_STD_P::adjacent_find<ForwardIterator>(begin, end);
653 // Sequential fallback
654 template<typename ForwardIterator, typename BinaryPredicate>
655 inline ForwardIterator
656 adjacent_find(ForwardIterator begin, ForwardIterator end, BinaryPredicate binary_pred, __gnu_parallel::sequential_tag)
658 return _GLIBCXX_STD_P::adjacent_find<ForwardIterator, BinaryPredicate>(begin, end, binary_pred);
661 // Parallel algorithm for random access iterators
662 template<typename RandomAccessIterator>
663 RandomAccessIterator
664 adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end, random_access_iterator_tag)
666 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
668 if (_GLIBCXX_PARALLEL_CONDITION(true))
670 RandomAccessIterator spot = __gnu_parallel::find_template(begin, end - 1, begin, equal_to<value_type>(), __gnu_parallel::adjacent_find_selector()).first;
671 if (spot == (end - 1))
672 return end;
673 else
674 return spot;
676 else
677 return adjacent_find<RandomAccessIterator>(begin, end, __gnu_parallel::sequential_tag());
680 // Sequential fallback for input iterator case
681 template<typename ForwardIterator, typename IteratorTag>
682 inline ForwardIterator
683 adjacent_find_switch(ForwardIterator begin, ForwardIterator end, IteratorTag)
685 return adjacent_find<ForwardIterator>(begin, end, __gnu_parallel::sequential_tag());
688 // Public interface
689 template<typename ForwardIterator>
690 inline ForwardIterator
691 adjacent_find(ForwardIterator begin, ForwardIterator end)
693 return adjacent_find_switch(begin, end, typename std::iterator_traits<ForwardIterator>::iterator_category());
696 // Sequential fallback for input iterator case
697 template<typename ForwardIterator, typename BinaryPredicate, typename IteratorTag>
698 inline ForwardIterator
699 adjacent_find_switch(ForwardIterator begin, ForwardIterator end, BinaryPredicate binary_pred, IteratorTag)
701 return adjacent_find<ForwardIterator, BinaryPredicate>(begin, end, binary_pred, __gnu_parallel::sequential_tag());
704 // Parallel algorithm for random access iterators
705 template<typename RandomAccessIterator, typename BinaryPredicate>
706 RandomAccessIterator
707 adjacent_find_switch(RandomAccessIterator begin, RandomAccessIterator end, BinaryPredicate binary_pred, random_access_iterator_tag)
709 if (_GLIBCXX_PARALLEL_CONDITION(true))
710 return __gnu_parallel::find_template(begin, end, begin, binary_pred, __gnu_parallel::adjacent_find_selector()).first;
711 else
712 return adjacent_find(begin, end, binary_pred, __gnu_parallel::sequential_tag());
715 // Public interface
716 template<typename ForwardIterator, typename BinaryPredicate>
717 inline ForwardIterator
718 adjacent_find(ForwardIterator begin, ForwardIterator end, BinaryPredicate binary_pred)
720 return adjacent_find_switch<ForwardIterator, BinaryPredicate>(begin, end, binary_pred, typename std::iterator_traits<ForwardIterator>::iterator_category());
723 // Sequential fallback
724 template<typename InputIterator, typename T>
725 inline typename iterator_traits<InputIterator>::difference_type
726 count(InputIterator begin, InputIterator end, const T& value, __gnu_parallel::sequential_tag)
728 return _GLIBCXX_STD_P::count<InputIterator, T>(begin, end, value);
731 // Parallel code for random access iterators
732 template<typename RandomAccessIterator, typename T>
733 typename iterator_traits<RandomAccessIterator>::difference_type
734 count_switch(RandomAccessIterator begin, RandomAccessIterator end, const T& value, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
736 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
737 typedef typename iterator_traits<RandomAccessIterator>::difference_type difference_type;
739 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::count_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
741 difference_type res = 0;
742 __gnu_parallel::count_selector<RandomAccessIterator, difference_type> functionality;
743 __gnu_parallel::for_each_template_random_access(begin, end, value, functionality, std::plus<__gnu_parallel::sequence_index_t>(), res, res, -1, parallelism_tag);
744 return res;
746 else
747 return count<RandomAccessIterator, T>(begin, end, value, __gnu_parallel::sequential_tag());
750 // Sequential fallback for input iterator case.
751 template<typename InputIterator, typename T, typename IteratorTag>
752 typename iterator_traits<InputIterator>::difference_type
753 count_switch(InputIterator begin, InputIterator end, const T& value, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
755 return count<InputIterator, T>(begin, end, value, __gnu_parallel::sequential_tag());
758 // Public interface.
759 template<typename InputIterator, typename T>
760 inline typename iterator_traits<InputIterator>::difference_type
761 count(InputIterator begin, InputIterator end, const T& value, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced)
763 return count_switch(begin, end, value, typename std::iterator_traits<InputIterator>::iterator_category(), parallelism_tag);
766 // Sequential fallback.
767 template<typename InputIterator, typename Predicate>
768 inline typename iterator_traits<InputIterator>::difference_type
769 count_if(InputIterator begin, InputIterator end, Predicate pred, __gnu_parallel::sequential_tag)
771 return _GLIBCXX_STD_P::count_if(begin, end, pred);
774 // Parallel count_if for random access iterators
775 template<typename RandomAccessIterator, typename Predicate>
776 typename iterator_traits<RandomAccessIterator>::difference_type
777 count_if_switch(RandomAccessIterator begin, RandomAccessIterator end, Predicate pred, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
779 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
780 typedef typename iterator_traits<RandomAccessIterator>::difference_type difference_type;
782 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::count_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
784 difference_type res = 0;
785 __gnu_parallel::count_if_selector<RandomAccessIterator, difference_type> functionality;
786 __gnu_parallel::for_each_template_random_access(begin, end, pred, functionality, std::plus<__gnu_parallel::sequence_index_t>(), res, res, -1, parallelism_tag);
787 return res;
789 else
790 return count_if<RandomAccessIterator, Predicate>(begin, end, pred, __gnu_parallel::sequential_tag());
793 // Sequential fallback for input iterator case.
794 template<typename InputIterator, typename Predicate, typename IteratorTag>
795 typename iterator_traits<InputIterator>::difference_type
796 count_if_switch(InputIterator begin, InputIterator end, Predicate pred, IteratorTag, __gnu_parallel::parallelism)
798 return count_if<InputIterator, Predicate>(begin, end, pred, __gnu_parallel::sequential_tag());
801 // Public interface.
802 template<typename InputIterator, typename Predicate>
803 inline typename iterator_traits<InputIterator>::difference_type
804 count_if(InputIterator begin, InputIterator end, Predicate pred, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_unbalanced)
806 typedef iterator_traits<InputIterator> traits_type;
807 typedef typename traits_type::iterator_category iterator_category;
808 return count_if_switch(begin, end, pred, iterator_category(), parallelism_tag);
812 // Sequential fallback.
813 template<typename ForwardIterator1, typename ForwardIterator2>
814 inline ForwardIterator1
815 search(ForwardIterator1 begin1, ForwardIterator1 end1, ForwardIterator2 begin2, ForwardIterator2 end2, __gnu_parallel::sequential_tag)
817 return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2);
820 // Parallel algorithm for random access iterator
821 template<typename RandomAccessIterator1, typename RandomAccessIterator2>
822 RandomAccessIterator1
823 search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator2 end2, random_access_iterator_tag, random_access_iterator_tag)
825 typedef std::iterator_traits<RandomAccessIterator1> iterator1_traits;
826 typedef typename iterator1_traits::value_type value1_type;
827 typedef std::iterator_traits<RandomAccessIterator2> iterator2_traits;
828 typedef typename iterator2_traits::value_type value2_type;
830 if (_GLIBCXX_PARALLEL_CONDITION(true))
831 return __gnu_parallel::search_template(begin1, end1, begin2, end2, __gnu_parallel::equal_to<value1_type, value2_type>());
832 else
833 return search(begin1, end1, begin2, end2, __gnu_parallel::sequential_tag());
836 // Sequential fallback for input iterator case
837 template<typename ForwardIterator1, typename ForwardIterator2, typename IteratorTag1, typename IteratorTag2>
838 inline ForwardIterator1
839 search_switch(ForwardIterator1 begin1, ForwardIterator1 end1, ForwardIterator2 begin2, ForwardIterator2 end2, IteratorTag1, IteratorTag2)
841 return search(begin1, end1, begin2, end2, __gnu_parallel::sequential_tag());
844 // Public interface.
845 template<typename ForwardIterator1, typename ForwardIterator2>
846 inline ForwardIterator1
847 search(ForwardIterator1 begin1, ForwardIterator1 end1, ForwardIterator2 begin2, ForwardIterator2 end2)
849 typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
850 typedef typename iterator1_traits::iterator_category iterator1_category;
851 typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
852 typedef typename iterator2_traits::iterator_category iterator2_category;
854 return search_switch(begin1, end1, begin2, end2, iterator1_category(), iterator2_category());
857 // Public interface.
858 template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
859 inline ForwardIterator1
860 search(ForwardIterator1 begin1, ForwardIterator1 end1, ForwardIterator2 begin2, ForwardIterator2 end2, BinaryPredicate pred, __gnu_parallel::sequential_tag)
862 return _GLIBCXX_STD_P::search(begin1, end1, begin2, end2, pred);
865 // Parallel algorithm for random access iterator.
866 template<typename RandomAccessIterator1, typename RandomAccessIterator2,
867 typename BinaryPredicate>
868 RandomAccessIterator1
869 search_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1,
870 RandomAccessIterator2 begin2, RandomAccessIterator2 end2, BinaryPredicate pred, random_access_iterator_tag, random_access_iterator_tag)
872 if (_GLIBCXX_PARALLEL_CONDITION(true))
873 return __gnu_parallel::search_template(begin1, end1, begin2, end2, pred);
874 else
875 return search(begin1, end1, begin2, end2, pred, __gnu_parallel::sequential_tag());
878 // Sequential fallback for input iterator case
879 template<typename ForwardIterator1, typename ForwardIterator2,
880 typename BinaryPredicate, typename IteratorTag1, typename IteratorTag2>
881 inline ForwardIterator1
882 search_switch(ForwardIterator1 begin1, ForwardIterator1 end1,
883 ForwardIterator2 begin2, ForwardIterator2 end2, BinaryPredicate pred, IteratorTag1, IteratorTag2)
885 return search(begin1, end1, begin2, end2, pred, __gnu_parallel::sequential_tag());
888 // Public interface
889 template<typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate>
890 inline ForwardIterator1
891 search(ForwardIterator1 begin1, ForwardIterator1 end1, ForwardIterator2 begin2, ForwardIterator2 end2, BinaryPredicate pred)
893 typedef std::iterator_traits<ForwardIterator1> iterator1_traits;
894 typedef typename iterator1_traits::iterator_category iterator1_category;
895 typedef std::iterator_traits<ForwardIterator2> iterator2_traits;
896 typedef typename iterator2_traits::iterator_category iterator2_category;
897 return search_switch(begin1, end1, begin2, end2, pred, iterator1_category(), iterator2_category());
900 // Sequential fallback
901 template<typename ForwardIterator, typename Integer, typename T>
902 inline ForwardIterator
903 search_n(ForwardIterator begin, ForwardIterator end, Integer count, const T& val, __gnu_parallel::sequential_tag)
904 { return _GLIBCXX_STD_P::search_n(begin, end, count, val); }
906 // Sequential fallback
907 template<typename ForwardIterator, typename Integer, typename T, typename BinaryPredicate>
908 inline ForwardIterator
909 search_n(ForwardIterator begin, ForwardIterator end, Integer count, const T& val, BinaryPredicate binary_pred, __gnu_parallel::sequential_tag)
911 return _GLIBCXX_STD_P::search_n(begin, end, count, val, binary_pred);
914 // Public interface.
915 template<typename ForwardIterator, typename Integer, typename T>
916 inline ForwardIterator
917 search_n(ForwardIterator begin, ForwardIterator end, Integer count, const T& val)
919 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
920 return search_n(begin, end, count, val, __gnu_parallel::equal_to<value_type, T>());
923 // Parallel algorithm for random access iterators.
924 template<typename RandomAccessIterator, typename Integer, typename T, typename BinaryPredicate>
925 RandomAccessIterator
926 search_n_switch(RandomAccessIterator begin, RandomAccessIterator end, Integer count, const T& val, BinaryPredicate binary_pred, random_access_iterator_tag)
928 if (_GLIBCXX_PARALLEL_CONDITION(true))
930 __gnu_parallel::pseudo_sequence<T, Integer> ps(val, count);
931 return __gnu_parallel::search_template(begin, end, ps.begin(), ps.end(), binary_pred);
933 else
934 return std::__search_n(begin, end, count, val, binary_pred, random_access_iterator_tag());
937 // Sequential fallback for input iterator case.
938 template<typename ForwardIterator, typename Integer, typename T, typename BinaryPredicate, typename IteratorTag>
939 inline ForwardIterator
940 search_n_switch(ForwardIterator begin, ForwardIterator end, Integer count, const T& val, BinaryPredicate binary_pred, IteratorTag)
942 return __search_n(begin, end, count, val, binary_pred, IteratorTag());
945 // Public interface.
946 template<typename ForwardIterator, typename Integer, typename T, typename BinaryPredicate>
947 inline ForwardIterator
948 search_n(ForwardIterator begin, ForwardIterator end, Integer count, const T& val, BinaryPredicate binary_pred)
950 return search_n_switch(begin, end, count, val, binary_pred, typename std::iterator_traits<ForwardIterator>::iterator_category());
953 // Sequential fallback.
954 template<typename InputIterator, typename OutputIterator, typename UnaryOperation>
955 inline OutputIterator
956 transform(InputIterator begin, InputIterator end, OutputIterator result, UnaryOperation unary_op, __gnu_parallel::sequential_tag)
958 return _GLIBCXX_STD_P::transform(begin, end, result, unary_op);
961 // Sequential fallback
962 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryOperation>
963 inline OutputIterator
964 transform(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, OutputIterator result, BinaryOperation binary_op, __gnu_parallel::sequential_tag)
966 return _GLIBCXX_STD_P::transform(begin1, end1, begin2, result, binary_op);
969 // Parallel unary transform for random access iterators.
970 template<typename RandomAccessIterator1, typename RandomAccessIterator3, typename UnaryOperation>
971 RandomAccessIterator3
972 transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end, RandomAccessIterator3 result, UnaryOperation unary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
974 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::transform_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
976 bool dummy = true;
977 typedef __gnu_parallel::iterator_pair<RandomAccessIterator1, RandomAccessIterator3, random_access_iterator_tag> ip;
978 ip begin_pair(begin, result), end_pair(end, result + (end - begin));
979 __gnu_parallel::transform1_selector<ip> functionality;
980 __gnu_parallel::for_each_template_random_access(begin_pair, end_pair, unary_op, functionality, __gnu_parallel::dummy_reduct(), dummy, dummy, -1, parallelism_tag);
981 return functionality.finish_iterator;
983 else
984 return transform(begin, end, result, unary_op, __gnu_parallel::sequential_tag());
987 // Sequential fallback for input iterator case.
988 template<typename RandomAccessIterator1, typename RandomAccessIterator3, typename UnaryOperation, typename IteratorTag1, typename IteratorTag2>
989 inline RandomAccessIterator3
990 transform1_switch(RandomAccessIterator1 begin, RandomAccessIterator1 end, RandomAccessIterator3 result, UnaryOperation unary_op, IteratorTag1, IteratorTag2, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
992 return _GLIBCXX_STD_P::transform(begin, end, result, unary_op);
996 // Parallel binary transform for random access iterators.
997 template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename RandomAccessIterator3, typename BinaryOperation>
998 RandomAccessIterator3
999 transform2_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator3 result, BinaryOperation binary_op, random_access_iterator_tag, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1001 if (_GLIBCXX_PARALLEL_CONDITION((end1 - begin1) >= __gnu_parallel::Settings::transform_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
1003 bool dummy = true;
1004 typedef __gnu_parallel::iterator_triple<RandomAccessIterator1, RandomAccessIterator2, RandomAccessIterator3, random_access_iterator_tag> ip;
1005 ip begin_triple(begin1, begin2, result), end_triple(end1, begin2 + (end1 - begin1), result + (end1 - begin1));
1006 __gnu_parallel::transform2_selector<ip> functionality;
1007 __gnu_parallel::for_each_template_random_access(begin_triple, end_triple, binary_op, functionality, __gnu_parallel::dummy_reduct(), dummy, dummy, -1, parallelism_tag);
1008 return functionality.finish_iterator;
1010 else
1011 return transform(begin1, end1, begin2, result, binary_op, __gnu_parallel::sequential_tag());
1014 // Sequential fallback for input iterator case.
1015 template<typename RandomAccessIterator1, typename RandomAccessIterator2, typename RandomAccessIterator3, typename BinaryOperation, typename tag1, typename tag2, typename tag3>
1016 inline RandomAccessIterator3
1017 transform2_switch(RandomAccessIterator1 begin1, RandomAccessIterator1 end1, RandomAccessIterator2 begin2, RandomAccessIterator3 result, BinaryOperation binary_op, tag1, tag2, tag3, __gnu_parallel::parallelism)
1019 return _GLIBCXX_STD_P::transform(begin1, end1, begin2, result, binary_op);
1022 // Public interface.
1023 template<typename InputIterator, typename OutputIterator, typename UnaryOperation>
1024 inline OutputIterator
1025 transform(InputIterator begin, InputIterator end, OutputIterator result,
1026 UnaryOperation unary_op, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1028 typedef std::iterator_traits<InputIterator> iteratori_traits;
1029 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1030 typedef typename iteratori_traits::iterator_category iteratori_category;
1031 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1033 return transform1_switch(begin, end, result, unary_op,
1034 iteratori_category(), iteratoro_category(), parallelism_tag);
1037 // Public interface.
1038 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryOperation>
1039 inline OutputIterator
1040 transform(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, OutputIterator result, BinaryOperation binary_op, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1042 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
1043 typedef typename iteratori1_traits::iterator_category iteratori1_category;
1044 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
1045 typedef typename iteratori2_traits::iterator_category iteratori2_category;
1046 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1047 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1050 return transform2_switch(begin1, end1, begin2, result, binary_op,
1051 iteratori1_category(), iteratori2_category(), iteratoro_category(), parallelism_tag);
1054 // Sequential fallback
1055 template<typename ForwardIterator, typename T>
1056 inline void
1057 replace(ForwardIterator begin, ForwardIterator end, const T& old_value, const T& new_value, __gnu_parallel::sequential_tag)
1058 { _GLIBCXX_STD_P::replace(begin, end, old_value, new_value); }
1060 // Sequential fallback for input iterator case
1061 template<typename ForwardIterator, typename T, typename IteratorTag>
1062 void
1063 replace_switch(ForwardIterator begin, ForwardIterator end, const T& old_value, const T& new_value, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
1064 { replace(begin, end, old_value, new_value, __gnu_parallel::sequential_tag()); }
1066 // Parallel replace for random access iterators
1067 template<typename RandomAccessIterator, typename T>
1068 void
1069 replace_switch(RandomAccessIterator begin, RandomAccessIterator end, const T& old_value, const T& new_value, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
1070 { replace(begin, end, old_value, new_value, __gnu_parallel::sequential_tag()); }
1072 // Public interface
1073 template<typename ForwardIterator, typename T>
1074 inline void
1075 replace(ForwardIterator begin, ForwardIterator end, const T& old_value, const T& new_value, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1077 replace_switch(begin, end, old_value, new_value, typename std::iterator_traits<ForwardIterator>::iterator_category(), parallelism_tag);
1081 // Sequential fallback
1082 template<typename ForwardIterator, typename Predicate, typename T>
1083 inline void
1084 replace_if(ForwardIterator begin, ForwardIterator end, Predicate pred, const T& new_value, __gnu_parallel::sequential_tag)
1085 { _GLIBCXX_STD_P::replace_if(begin, end, pred, new_value); }
1087 // Sequential fallback for input iterator case
1088 template<typename ForwardIterator, typename Predicate, typename T, typename IteratorTag>
1089 void
1090 replace_if_switch(ForwardIterator begin, ForwardIterator end, Predicate pred, const T& new_value, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
1091 { replace_if(begin, end, pred, new_value, __gnu_parallel::sequential_tag()); }
1093 // Parallel algorithm for random access iterators.
1094 template<typename RandomAccessIterator, typename Predicate, typename T>
1095 void
1096 replace_if_switch(RandomAccessIterator begin, RandomAccessIterator end, Predicate pred, const T& new_value, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
1098 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::replace_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
1100 bool dummy;
1101 __gnu_parallel::replace_if_selector<RandomAccessIterator, Predicate, T> functionality(new_value);
1102 __gnu_parallel::for_each_template_random_access(begin, end, pred, functionality, __gnu_parallel::dummy_reduct(), true, dummy, -1, parallelism_tag);
1104 else
1105 replace_if(begin, end, pred, new_value, __gnu_parallel::sequential_tag());
1108 // Public interface.
1109 template<typename ForwardIterator, typename Predicate, typename T>
1110 inline void
1111 replace_if(ForwardIterator begin, ForwardIterator end,
1112 Predicate pred, const T& new_value, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1114 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1115 typedef typename iterator_traits::iterator_category iterator_category;
1117 replace_if_switch(begin, end, pred, new_value, iterator_category(), parallelism_tag);
1120 // Sequential fallback
1121 template<typename ForwardIterator, typename Generator>
1122 inline void
1123 generate(ForwardIterator begin, ForwardIterator end, Generator gen, __gnu_parallel::sequential_tag)
1124 { _GLIBCXX_STD_P::generate<ForwardIterator, Generator>(begin, end, gen); }
1126 // Sequential fallback for input iterator case.
1127 template<typename ForwardIterator, typename Generator, typename IteratorTag>
1128 void
1129 generate_switch(ForwardIterator begin, ForwardIterator end, Generator gen, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
1130 { generate(begin, end, gen, __gnu_parallel::sequential_tag()); }
1132 // Parallel algorithm for random access iterators.
1133 template<typename RandomAccessIterator, typename Generator>
1134 void
1135 generate_switch(RandomAccessIterator begin, RandomAccessIterator end,
1136 Generator gen, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
1138 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::generate_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
1140 bool dummy;
1141 __gnu_parallel::generate_selector<RandomAccessIterator> functionality;
1142 __gnu_parallel::for_each_template_random_access(begin, end, gen, functionality, __gnu_parallel::dummy_reduct(), true, dummy, -1, parallelism_tag);
1144 else
1145 generate(begin, end, gen, __gnu_parallel::sequential_tag());
1148 // Public interface.
1149 template<typename ForwardIterator, typename Generator>
1150 inline void
1151 generate(ForwardIterator begin, ForwardIterator end,
1152 Generator gen, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1154 typedef std::iterator_traits<ForwardIterator> iterator_traits;
1155 typedef typename iterator_traits::iterator_category iterator_category;
1156 generate_switch(begin, end, gen, iterator_category(), parallelism_tag);
1160 // Sequential fallback.
1161 template<typename OutputIterator, typename Size, typename Generator>
1162 inline OutputIterator
1163 generate_n(OutputIterator begin, Size n, Generator gen, __gnu_parallel::sequential_tag)
1164 { return _GLIBCXX_STD_P::generate_n(begin, n, gen); }
1166 // Sequential fallback for input iterator case.
1167 template<typename OutputIterator, typename Size, typename Generator, typename IteratorTag>
1168 OutputIterator
1169 generate_n_switch(OutputIterator begin, Size n, Generator gen, IteratorTag, __gnu_parallel::parallelism)
1170 { return generate_n(begin, n, gen, __gnu_parallel::sequential_tag()); }
1172 // Parallel algorithm for random access iterators.
1173 template<typename RandomAccessIterator, typename Size, typename Generator>
1174 RandomAccessIterator
1175 generate_n_switch(RandomAccessIterator begin, Size n, Generator gen, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
1176 { return generate_n(begin, n, gen, __gnu_parallel::sequential_tag()); }
1178 // Public interface.
1179 template<typename OutputIterator, typename Size, typename Generator>
1180 inline OutputIterator
1181 generate_n(OutputIterator begin, Size n, Generator gen, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1183 typedef std::iterator_traits<OutputIterator> iterator_traits;
1184 typedef typename iterator_traits::iterator_category iterator_category;
1185 return generate_n_switch(begin, n, gen, iterator_category(), parallelism_tag);
1189 // Sequential fallback.
1190 template<typename RandomAccessIterator>
1191 inline void
1192 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, __gnu_parallel::sequential_tag)
1193 { _GLIBCXX_STD_P::random_shuffle(begin, end); }
1195 // Sequential fallback.
1196 template<typename RandomAccessIterator, typename RandomNumberGenerator>
1197 inline void
1198 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, RandomNumberGenerator& rand, __gnu_parallel::sequential_tag)
1199 { _GLIBCXX_STD_P::random_shuffle(begin, end, rand); }
1202 /** @brief Functor wrapper for std::rand(). */
1203 template<typename must_be_int = int>
1204 struct c_rand_number
1206 inline int operator()(int limit)
1207 { return rand() % limit; }
1210 // Fill in random number generator.
1211 template<typename RandomAccessIterator>
1212 inline void
1213 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end)
1215 c_rand_number<> r;
1216 // Parallelization still possible.
1217 random_shuffle(begin, end, r);
1220 // Parallel algorithm for random access iterators.
1221 template<typename RandomAccessIterator, typename RandomNumberGenerator>
1222 void
1223 random_shuffle(RandomAccessIterator begin, RandomAccessIterator end, RandomNumberGenerator& rand)
1225 if (begin == end)
1226 return;
1227 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::random_shuffle_minimal_n))
1228 __gnu_parallel::parallel_random_shuffle(begin, end, rand);
1229 else
1230 __gnu_parallel::sequential_random_shuffle(begin, end, rand);
1233 // Sequential fallback.
1234 template<typename ForwardIterator, typename Predicate>
1235 inline ForwardIterator
1236 partition(ForwardIterator begin, ForwardIterator end, Predicate pred, __gnu_parallel::sequential_tag)
1237 { return _GLIBCXX_STD_P::partition(begin, end, pred); }
1239 // Sequential fallback for input iterator case.
1240 template<typename ForwardIterator, typename Predicate, typename IteratorTag>
1241 inline ForwardIterator
1242 partition_switch(ForwardIterator begin, ForwardIterator end, Predicate pred, IteratorTag)
1243 { return partition(begin, end, pred, __gnu_parallel::sequential_tag()); }
1245 // Parallel algorithm for random access iterators.
1246 template<typename RandomAccessIterator, typename Predicate>
1247 RandomAccessIterator
1248 partition_switch(RandomAccessIterator begin, RandomAccessIterator end, Predicate pred, random_access_iterator_tag)
1250 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::partition_minimal_n))
1252 typedef typename std::iterator_traits<RandomAccessIterator>::difference_type difference_type;
1253 difference_type middle = __gnu_parallel::parallel_partition(begin, end, pred, __gnu_parallel::get_max_threads());
1254 return begin + middle;
1256 else
1257 return partition(begin, end, pred, __gnu_parallel::sequential_tag());
1260 // Public interface.
1261 template<typename ForwardIterator, typename Predicate>
1262 inline ForwardIterator
1263 partition(ForwardIterator begin, ForwardIterator end, Predicate pred)
1265 return partition_switch(begin, end, pred, typename std::iterator_traits<ForwardIterator>::iterator_category());
1268 // Sequential fallback
1269 template<typename RandomAccessIterator>
1270 inline void
1271 sort(RandomAccessIterator begin, RandomAccessIterator end, __gnu_parallel::sequential_tag)
1272 { _GLIBCXX_STD_P::sort<RandomAccessIterator>(begin, end); }
1274 // Sequential fallback
1275 template<typename RandomAccessIterator, typename Comparator>
1276 inline void
1277 sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp, __gnu_parallel::sequential_tag)
1278 { _GLIBCXX_STD_P::sort<RandomAccessIterator, Comparator>(begin, end, comp); }
1280 // Public interface, insert default comparator
1281 template<typename RandomAccessIterator>
1282 inline void
1283 sort(RandomAccessIterator begin, RandomAccessIterator end)
1285 typedef iterator_traits<RandomAccessIterator> traits_type;
1286 typedef typename traits_type::value_type value_type;
1287 sort(begin, end, std::less<value_type>());
1290 template<typename RandomAccessIterator, typename Comparator>
1291 void
1292 sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp)
1294 typedef iterator_traits<RandomAccessIterator> traits_type;
1295 typedef typename traits_type::value_type value_type;
1297 if (begin != end)
1299 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::sort_minimal_n))
1300 __gnu_parallel::parallel_sort(begin, end, comp, false);
1301 else
1302 sort<RandomAccessIterator, Comparator>(begin, end, comp, __gnu_parallel::sequential_tag());
1306 // Sequential fallback.
1307 template<typename RandomAccessIterator>
1308 inline void
1309 stable_sort(RandomAccessIterator begin, RandomAccessIterator end, __gnu_parallel::sequential_tag)
1311 return _GLIBCXX_STD_P::stable_sort<RandomAccessIterator>(begin, end);
1314 // Sequential fallback.
1315 template<typename RandomAccessIterator, typename Comparator>
1316 inline void
1317 stable_sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp, __gnu_parallel::sequential_tag)
1319 return _GLIBCXX_STD_P::stable_sort<RandomAccessIterator, Comparator>(begin, end, comp);
1322 template<typename RandomAccessIterator>
1323 void
1324 stable_sort(RandomAccessIterator begin, RandomAccessIterator end)
1326 typedef iterator_traits<RandomAccessIterator> traits_type;
1327 typedef typename traits_type::value_type value_type;
1329 stable_sort(begin, end, std::less<value_type>());
1332 // Parallel algorithm for random access iterators
1333 template<typename RandomAccessIterator, typename Comparator>
1334 void
1335 stable_sort(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp)
1337 if (begin != end)
1339 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::sort_minimal_n))
1340 __gnu_parallel::parallel_sort(begin, end, comp, true);
1341 else
1342 stable_sort<RandomAccessIterator, Comparator>(begin, end, comp, __gnu_parallel::sequential_tag());
1346 // Sequential fallback
1347 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
1348 inline OutputIterator
1349 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator result,
1350 __gnu_parallel::sequential_tag)
1352 return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result);
1355 // Sequential fallback
1356 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Comparator>
1357 inline OutputIterator
1358 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator result, Comparator comp,
1359 __gnu_parallel::sequential_tag)
1361 return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result, comp);
1364 // Sequential fallback for input iterator case
1365 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Comparator, typename IteratorTag1, typename IteratorTag2, typename IteratorTag3>
1366 inline OutputIterator
1367 merge_switch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator result, Comparator comp, IteratorTag1, IteratorTag2, IteratorTag3)
1369 return _GLIBCXX_STD_P::merge(begin1, end1, begin2, end2, result, comp);
1372 // Parallel algorithm for random access iterators
1373 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Comparator>
1374 OutputIterator
1375 merge_switch(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator result, Comparator comp, random_access_iterator_tag, random_access_iterator_tag, random_access_iterator_tag)
1377 if (_GLIBCXX_PARALLEL_CONDITION((static_cast<__gnu_parallel::sequence_index_t>(end1 - begin1) >= __gnu_parallel::Settings::merge_minimal_n || static_cast<__gnu_parallel::sequence_index_t>(end2 - begin2) >= __gnu_parallel::Settings::merge_minimal_n)))
1378 return __gnu_parallel::parallel_merge_advance(begin1, end1, begin2, end2, result, (end1 - begin1) + (end2 - begin2), comp);
1379 else
1380 return __gnu_parallel::merge_advance(begin1, end1, begin2, end2, result, (end1 - begin1) + (end2 - begin2), comp);
1383 // Public interface
1384 template<typename InputIterator1, typename InputIterator2, typename OutputIterator, typename Comparator>
1385 inline OutputIterator
1386 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator result, Comparator comp)
1388 typedef typename iterator_traits<InputIterator1>::value_type value_type;
1390 typedef std::iterator_traits<InputIterator1> iteratori1_traits;
1391 typedef std::iterator_traits<InputIterator2> iteratori2_traits;
1392 typedef std::iterator_traits<OutputIterator> iteratoro_traits;
1393 typedef typename iteratori1_traits::iterator_category iteratori1_category;
1394 typedef typename iteratori2_traits::iterator_category iteratori2_category;
1395 typedef typename iteratoro_traits::iterator_category iteratoro_category;
1397 return merge_switch(begin1, end1, begin2, end2, result, comp, iteratori1_category(), iteratori2_category(), iteratoro_category());
1401 // Public interface, insert default comparator
1402 template<typename InputIterator1, typename InputIterator2, typename OutputIterator>
1403 inline OutputIterator
1404 merge(InputIterator1 begin1, InputIterator1 end1, InputIterator2 begin2, InputIterator2 end2, OutputIterator result)
1406 typedef std::iterator_traits<InputIterator1> iterator1_traits;
1407 typedef std::iterator_traits<InputIterator2> iterator2_traits;
1408 typedef typename iterator1_traits::value_type value1_type;
1409 typedef typename iterator2_traits::value_type value2_type;
1411 return merge(begin1, end1, begin2, end2, result, __gnu_parallel::less<value1_type, value2_type>());
1414 // Sequential fallback
1415 template<typename RandomAccessIterator>
1416 inline void
1417 nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, __gnu_parallel::sequential_tag)
1418 { return _GLIBCXX_STD_P::nth_element(begin, nth, end); }
1420 // Sequential fallback
1421 template<typename RandomAccessIterator, typename Comparator>
1422 void
1423 nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, Comparator comp, __gnu_parallel::sequential_tag)
1424 { return _GLIBCXX_STD_P::nth_element(begin, nth, end, comp); }
1426 // Public interface
1427 template<typename RandomAccessIterator, typename Comparator>
1428 inline void
1429 nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end, Comparator comp)
1431 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::nth_element_minimal_n))
1432 __gnu_parallel::parallel_nth_element(begin, nth, end, comp);
1433 else
1434 nth_element(begin, nth, end, comp, __gnu_parallel::sequential_tag());
1437 // Public interface, insert default comparator
1438 template<typename RandomAccessIterator>
1439 void
1440 nth_element(RandomAccessIterator begin, RandomAccessIterator nth, RandomAccessIterator end)
1442 typedef typename iterator_traits<RandomAccessIterator>::value_type value_type;
1443 nth_element(begin, nth, end, std::less<value_type>());
1446 // Sequential fallback
1447 template<typename _RandomAccessIterator, typename _Compare>
1448 void
1449 partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end, _Compare comp, __gnu_parallel::sequential_tag)
1450 { _GLIBCXX_STD_P::partial_sort(begin, middle, end, comp); }
1452 // Sequential fallback
1453 template<typename _RandomAccessIterator>
1454 void
1455 partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end, __gnu_parallel::sequential_tag)
1456 { _GLIBCXX_STD_P::partial_sort(begin, middle, end); }
1458 // Public interface, parallel algorithm for random access iterators
1459 template<typename _RandomAccessIterator, typename _Compare>
1460 void
1461 partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end, _Compare comp)
1463 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::partial_sort_minimal_n))
1464 __gnu_parallel::parallel_partial_sort(begin, middle, end, comp);
1465 else
1466 partial_sort(begin, middle, end, comp, __gnu_parallel::sequential_tag());
1469 // Public interface, insert default comparator
1470 template<typename _RandomAccessIterator>
1471 void
1472 partial_sort(_RandomAccessIterator begin, _RandomAccessIterator middle, _RandomAccessIterator end)
1474 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
1475 partial_sort(begin, middle, end, std::less<value_type>());
1478 // Sequential fallback
1479 template<typename ForwardIterator>
1480 inline ForwardIterator
1481 max_element(ForwardIterator begin, ForwardIterator end, __gnu_parallel::sequential_tag)
1482 { return _GLIBCXX_STD_P::max_element(begin, end); }
1484 // Sequential fallback
1485 template<typename ForwardIterator, typename Comparator>
1486 inline ForwardIterator
1487 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp, __gnu_parallel::sequential_tag)
1488 { return _GLIBCXX_STD_P::max_element(begin, end, comp); }
1490 // Sequential fallback for input iterator case
1491 template<typename ForwardIterator, typename Comparator, typename IteratorTag>
1492 ForwardIterator
1493 max_element_switch(ForwardIterator begin, ForwardIterator end, Comparator comp, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
1494 { return max_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
1496 // Public interface, insert default comparator
1497 template<typename ForwardIterator>
1498 inline ForwardIterator
1499 max_element(ForwardIterator begin, ForwardIterator end, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1501 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
1502 return max_element(begin, end, std::less<value_type>(), parallelism_tag);
1505 template<typename RandomAccessIterator, typename Comparator>
1506 RandomAccessIterator
1507 max_element_switch(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
1509 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::max_element_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
1511 RandomAccessIterator res(begin);
1512 __gnu_parallel::identity_selector<RandomAccessIterator> functionality;
1513 __gnu_parallel::for_each_template_random_access(begin, end, __gnu_parallel::nothing(), functionality, __gnu_parallel::max_element_reduct<Comparator, RandomAccessIterator>(comp), res, res, -1, parallelism_tag);
1514 return res;
1516 else
1517 return max_element(begin, end, __gnu_parallel::sequential_tag());
1520 // Public interface
1521 template<typename ForwardIterator, typename Comparator>
1522 inline ForwardIterator
1523 max_element(ForwardIterator begin, ForwardIterator end, Comparator comp, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1525 return max_element_switch(begin, end, comp, typename std::iterator_traits<ForwardIterator>::iterator_category(), parallelism_tag);
1528 // Sequential fallback
1529 template<typename ForwardIterator>
1530 inline
1531 ForwardIterator
1532 min_element(ForwardIterator begin, ForwardIterator end, __gnu_parallel::sequential_tag)
1533 { return _GLIBCXX_STD_P::min_element(begin, end); }
1535 // Sequential fallback
1536 template<typename ForwardIterator, typename Comparator>
1537 inline ForwardIterator
1538 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp, __gnu_parallel::sequential_tag)
1539 { return _GLIBCXX_STD_P::min_element(begin, end, comp); }
1541 // Public interface
1542 template<typename ForwardIterator>
1543 inline ForwardIterator
1544 min_element(ForwardIterator begin, ForwardIterator end, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1546 typedef typename iterator_traits<ForwardIterator>::value_type value_type;
1547 return min_element(begin, end, std::less<value_type>(), parallelism_tag);
1550 // Sequential fallback for input iterator case
1551 template<typename ForwardIterator, typename Comparator, typename IteratorTag>
1552 ForwardIterator
1553 min_element_switch(ForwardIterator begin, ForwardIterator end, Comparator comp, IteratorTag, __gnu_parallel::parallelism parallelism_tag)
1554 { return min_element(begin, end, comp, __gnu_parallel::sequential_tag()); }
1556 // Parallel algorithm for random access iterators
1557 template<typename RandomAccessIterator, typename Comparator>
1558 RandomAccessIterator
1559 min_element_switch(RandomAccessIterator begin, RandomAccessIterator end, Comparator comp, random_access_iterator_tag, __gnu_parallel::parallelism parallelism_tag)
1561 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t>(end - begin) >= __gnu_parallel::Settings::min_element_minimal_n && __gnu_parallel::is_parallel(parallelism_tag)))
1563 RandomAccessIterator res(begin);
1564 __gnu_parallel::identity_selector<RandomAccessIterator> functionality;
1565 __gnu_parallel::for_each_template_random_access(begin, end, __gnu_parallel::nothing(), functionality, __gnu_parallel::min_element_reduct<Comparator, RandomAccessIterator>(comp), res, res, -1, parallelism_tag);
1566 return res;
1568 else
1569 return min_element(begin, end, __gnu_parallel::sequential_tag());
1572 // Public interface
1573 template<typename ForwardIterator, typename Comparator>
1574 inline ForwardIterator
1575 min_element(ForwardIterator begin, ForwardIterator end, Comparator comp, __gnu_parallel::parallelism parallelism_tag = __gnu_parallel::parallel_balanced)
1577 typedef iterator_traits<ForwardIterator> traits_type;
1578 typedef typename traits_type::iterator_category iterator_category;
1579 return min_element_switch(begin, end, comp, iterator_category(), parallelism_tag);
1581 } // end namespace
1582 } // end namespace
1584 #endif /* _GLIBCXX_ALGORITHM_H */