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