libstdc++
algo.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 
3 // Copyright (C) 2007-2021 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  // Sequential fallback for input iterator case
73  template<typename _IIter, typename _Function, typename _IteratorTag>
74  inline _Function
75  __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
76  _IteratorTag)
77  { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }
78 
79  // Parallel algorithm for random access iterators
80  template<typename _RAIter, typename _Function>
81  _Function
82  __for_each_switch(_RAIter __begin, _RAIter __end,
83  _Function __f, random_access_iterator_tag,
84  __gnu_parallel::_Parallelism __parallelism_tag)
85  {
87  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
88  >= __gnu_parallel::_Settings::get().for_each_minimal_n
89  && __gnu_parallel::__is_parallel(__parallelism_tag)))
90  {
91  bool __dummy;
93 
94  return __gnu_parallel::
96  __begin, __end, __f, __functionality,
97  __gnu_parallel::_DummyReduct(), true, __dummy, -1,
98  __parallelism_tag);
99  }
100  else
101  return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
102  }
103 
104  // Public interface
105  template<typename _Iterator, typename _Function>
106  inline _Function
107  for_each(_Iterator __begin, _Iterator __end, _Function __f,
108  __gnu_parallel::_Parallelism __parallelism_tag)
109  {
110  return __for_each_switch(__begin, __end, __f,
111  std::__iterator_category(__begin),
112  __parallelism_tag);
113  }
114 
115  template<typename _Iterator, typename _Function>
116  inline _Function
117  for_each(_Iterator __begin, _Iterator __end, _Function __f)
118  {
119  return __for_each_switch(__begin, __end, __f,
120  std::__iterator_category(__begin));
121  }
122 
123  // Sequential fallback
124  template<typename _IIter, typename _Tp>
125  inline _IIter
126  find(_IIter __begin, _IIter __end, const _Tp& __val,
128  { return _GLIBCXX_STD_A::find(__begin, __end, __val); }
129 
130  // Sequential fallback for input iterator case
131  template<typename _IIter, typename _Tp, typename _IteratorTag>
132  inline _IIter
133  __find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
134  _IteratorTag)
135  { return _GLIBCXX_STD_A::find(__begin, __end, __val); }
136 
137  // Parallel find for random access iterators
138  template<typename _RAIter, typename _Tp>
139  _RAIter
140  __find_switch(_RAIter __begin, _RAIter __end,
141  const _Tp& __val, random_access_iterator_tag)
142  {
143  typedef iterator_traits<_RAIter> _TraitsType;
144  typedef typename _TraitsType::value_type _ValueType;
145 
146  if (_GLIBCXX_PARALLEL_CONDITION(true))
147  {
149  const _Tp&>,
150  _ValueType, const _Tp&, bool>
153  __begin, __end, __begin, __comp,
155  }
156  else
157  return _GLIBCXX_STD_A::find(__begin, __end, __val);
158  }
159 
160  // Public interface
161  template<typename _IIter, typename _Tp>
162  inline _IIter
163  find(_IIter __begin, _IIter __end, const _Tp& __val)
164  {
165  return __find_switch(__begin, __end, __val,
166  std::__iterator_category(__begin));
167  }
168 
169  // Sequential fallback
170  template<typename _IIter, typename _Predicate>
171  inline _IIter
172  find_if(_IIter __begin, _IIter __end, _Predicate __pred,
174  { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
175 
176  // Sequential fallback for input iterator case
177  template<typename _IIter, typename _Predicate, typename _IteratorTag>
178  inline _IIter
179  __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
180  _IteratorTag)
181  { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
182 
183  // Parallel find_if for random access iterators
184  template<typename _RAIter, typename _Predicate>
185  _RAIter
186  __find_if_switch(_RAIter __begin, _RAIter __end,
187  _Predicate __pred, random_access_iterator_tag)
188  {
189  if (_GLIBCXX_PARALLEL_CONDITION(true))
190  return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
192  __find_if_selector()).first;
193  else
194  return _GLIBCXX_STD_A::find_if(__begin, __end, __pred);
195  }
196 
197  // Public interface
198  template<typename _IIter, typename _Predicate>
199  inline _IIter
200  find_if(_IIter __begin, _IIter __end, _Predicate __pred)
201  {
202  return __find_if_switch(__begin, __end, __pred,
203  std::__iterator_category(__begin));
204  }
205 
206  // Sequential fallback
207  template<typename _IIter, typename _FIterator>
208  inline _IIter
209  find_first_of(_IIter __begin1, _IIter __end1,
210  _FIterator __begin2, _FIterator __end2,
212  {
213  return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2);
214  }
215 
216  // Sequential fallback
217  template<typename _IIter, typename _FIterator,
218  typename _BinaryPredicate>
219  inline _IIter
220  find_first_of(_IIter __begin1, _IIter __end1,
221  _FIterator __begin2, _FIterator __end2,
222  _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
223  { return _GLIBCXX_STD_A::find_first_of(
224  __begin1, __end1, __begin2, __end2, __comp); }
225 
226  // Sequential fallback for input iterator type
227  template<typename _IIter, typename _FIterator,
228  typename _IteratorTag1, typename _IteratorTag2>
229  inline _IIter
230  __find_first_of_switch(_IIter __begin1, _IIter __end1,
231  _FIterator __begin2, _FIterator __end2,
232  _IteratorTag1, _IteratorTag2)
233  { return find_first_of(__begin1, __end1, __begin2, __end2,
235 
236  // Parallel algorithm for random access iterators
237  template<typename _RAIter, typename _FIterator,
238  typename _BinaryPredicate, typename _IteratorTag>
239  inline _RAIter
240  __find_first_of_switch(_RAIter __begin1,
241  _RAIter __end1,
242  _FIterator __begin2, _FIterator __end2,
243  _BinaryPredicate __comp, random_access_iterator_tag,
244  _IteratorTag)
245  {
246  return __gnu_parallel::
247  __find_template(__begin1, __end1, __begin1, __comp,
249  <_FIterator>(__begin2, __end2)).first;
250  }
251 
252  // Sequential fallback for input iterator type
253  template<typename _IIter, typename _FIterator,
254  typename _BinaryPredicate, typename _IteratorTag1,
255  typename _IteratorTag2>
256  inline _IIter
257  __find_first_of_switch(_IIter __begin1, _IIter __end1,
258  _FIterator __begin2, _FIterator __end2,
259  _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
260  { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
262 
263  // Public interface
264  template<typename _IIter, typename _FIterator,
265  typename _BinaryPredicate>
266  inline _IIter
267  find_first_of(_IIter __begin1, _IIter __end1,
268  _FIterator __begin2, _FIterator __end2,
269  _BinaryPredicate __comp)
270  {
271  return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
272  std::__iterator_category(__begin1),
273  std::__iterator_category(__begin2));
274  }
275 
276  // Public interface, insert default comparator
277  template<typename _IIter, typename _FIterator>
278  inline _IIter
279  find_first_of(_IIter __begin1, _IIter __end1,
280  _FIterator __begin2, _FIterator __end2)
281  {
282  typedef typename std::iterator_traits<_IIter>::value_type _IValueType;
283  typedef typename std::iterator_traits<_FIterator>::value_type _FValueType;
284 
285  return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2,
287  }
288 
289  // Sequential fallback
290  template<typename _IIter, typename _OutputIterator>
291  inline _OutputIterator
292  unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
294  { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); }
295 
296  // Sequential fallback
297  template<typename _IIter, typename _OutputIterator,
298  typename _Predicate>
299  inline _OutputIterator
300  unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
301  _Predicate __pred, __gnu_parallel::sequential_tag)
302  { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); }
303 
304  // Sequential fallback for input iterator case
305  template<typename _IIter, typename _OutputIterator,
306  typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
307  inline _OutputIterator
308  __unique_copy_switch(_IIter __begin, _IIter __last,
309  _OutputIterator __out, _Predicate __pred,
310  _IteratorTag1, _IteratorTag2)
311  { return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); }
312 
313  // Parallel unique_copy for random access iterators
314  template<typename _RAIter, typename _RandomAccessOutputIterator,
315  typename _Predicate>
316  _RandomAccessOutputIterator
317  __unique_copy_switch(_RAIter __begin, _RAIter __last,
318  _RandomAccessOutputIterator __out, _Predicate __pred,
320  {
322  static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
323  > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
325  __begin, __last, __out, __pred);
326  else
327  return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred);
328  }
329 
330  // Public interface
331  template<typename _IIter, typename _OutputIterator>
332  inline _OutputIterator
333  unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
334  {
335  typedef typename std::iterator_traits<_IIter>::value_type _ValueType;
336 
337  return __unique_copy_switch(
338  __begin1, __end1, __out, equal_to<_ValueType>(),
339  std::__iterator_category(__begin1),
340  std::__iterator_category(__out));
341  }
342 
343  // Public interface
344  template<typename _IIter, typename _OutputIterator, typename _Predicate>
345  inline _OutputIterator
346  unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
347  _Predicate __pred)
348  {
349  return __unique_copy_switch(
350  __begin1, __end1, __out, __pred,
351  std::__iterator_category(__begin1),
352  std::__iterator_category(__out));
353  }
354 
355  // Sequential fallback
356  template<typename _IIter1, typename _IIter2,
357  typename _OutputIterator>
358  inline _OutputIterator
359  set_union(_IIter1 __begin1, _IIter1 __end1,
360  _IIter2 __begin2, _IIter2 __end2,
361  _OutputIterator __out, __gnu_parallel::sequential_tag)
362  { return _GLIBCXX_STD_A::set_union(
363  __begin1, __end1, __begin2, __end2, __out); }
364 
365  // Sequential fallback
366  template<typename _IIter1, typename _IIter2,
367  typename _OutputIterator, typename _Predicate>
368  inline _OutputIterator
369  set_union(_IIter1 __begin1, _IIter1 __end1,
370  _IIter2 __begin2, _IIter2 __end2,
371  _OutputIterator __out, _Predicate __pred,
373  { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
374  __begin2, __end2, __out, __pred); }
375 
376  // Sequential fallback for input iterator case
377  template<typename _IIter1, typename _IIter2, typename _Predicate,
378  typename _OutputIterator, typename _IteratorTag1,
379  typename _IteratorTag2, typename _IteratorTag3>
380  inline _OutputIterator
381  __set_union_switch(
382  _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
383  _OutputIterator __result, _Predicate __pred,
384  _IteratorTag1, _IteratorTag2, _IteratorTag3)
385  { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
386  __begin2, __end2, __result, __pred); }
387 
388  // Parallel set_union for random access iterators
389  template<typename _RAIter1, typename _RAIter2,
390  typename _Output_RAIter, typename _Predicate>
391  _Output_RAIter
392  __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
393  _RAIter2 __begin2, _RAIter2 __end2,
394  _Output_RAIter __result, _Predicate __pred,
397  {
399  static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
400  >= __gnu_parallel::_Settings::get().set_union_minimal_n
401  || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
402  >= __gnu_parallel::_Settings::get().set_union_minimal_n))
403  return __gnu_parallel::__parallel_set_union(
404  __begin1, __end1, __begin2, __end2, __result, __pred);
405  else
406  return _GLIBCXX_STD_A::set_union(__begin1, __end1,
407  __begin2, __end2, __result, __pred);
408  }
409 
410  // Public interface
411  template<typename _IIter1, typename _IIter2,
412  typename _OutputIterator>
413  inline _OutputIterator
414  set_union(_IIter1 __begin1, _IIter1 __end1,
415  _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
416  {
417  typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
418  typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
419 
420  return __set_union_switch(
421  __begin1, __end1, __begin2, __end2, __out,
423  std::__iterator_category(__begin1),
424  std::__iterator_category(__begin2),
425  std::__iterator_category(__out));
426  }
427 
428  // Public interface
429  template<typename _IIter1, typename _IIter2,
430  typename _OutputIterator, typename _Predicate>
431  inline _OutputIterator
432  set_union(_IIter1 __begin1, _IIter1 __end1,
433  _IIter2 __begin2, _IIter2 __end2,
434  _OutputIterator __out, _Predicate __pred)
435  {
436  return __set_union_switch(
437  __begin1, __end1, __begin2, __end2, __out, __pred,
438  std::__iterator_category(__begin1),
439  std::__iterator_category(__begin2),
440  std::__iterator_category(__out));
441  }
442 
443  // Sequential fallback.
444  template<typename _IIter1, typename _IIter2,
445  typename _OutputIterator>
446  inline _OutputIterator
447  set_intersection(_IIter1 __begin1, _IIter1 __end1,
448  _IIter2 __begin2, _IIter2 __end2,
449  _OutputIterator __out, __gnu_parallel::sequential_tag)
450  { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1,
451  __begin2, __end2, __out); }
452 
453  // Sequential fallback.
454  template<typename _IIter1, typename _IIter2,
455  typename _OutputIterator, typename _Predicate>
456  inline _OutputIterator
457  set_intersection(_IIter1 __begin1, _IIter1 __end1,
458  _IIter2 __begin2, _IIter2 __end2,
459  _OutputIterator __out, _Predicate __pred,
461  { return _GLIBCXX_STD_A::set_intersection(
462  __begin1, __end1, __begin2, __end2, __out, __pred); }
463 
464  // Sequential fallback for input iterator case
465  template<typename _IIter1, typename _IIter2,
466  typename _Predicate, typename _OutputIterator,
467  typename _IteratorTag1, typename _IteratorTag2,
468  typename _IteratorTag3>
469  inline _OutputIterator
470  __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
471  _IIter2 __begin2, _IIter2 __end2,
472  _OutputIterator __result, _Predicate __pred,
473  _IteratorTag1, _IteratorTag2, _IteratorTag3)
474  { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2,
475  __end2, __result, __pred); }
476 
477  // Parallel set_intersection for random access iterators
478  template<typename _RAIter1, typename _RAIter2,
479  typename _Output_RAIter, typename _Predicate>
480  _Output_RAIter
481  __set_intersection_switch(_RAIter1 __begin1,
482  _RAIter1 __end1,
483  _RAIter2 __begin2,
484  _RAIter2 __end2,
485  _Output_RAIter __result,
486  _Predicate __pred,
490  {
492  static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
493  >= __gnu_parallel::_Settings::get().set_union_minimal_n
494  || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
495  >= __gnu_parallel::_Settings::get().set_union_minimal_n))
496  return __gnu_parallel::__parallel_set_intersection(
497  __begin1, __end1, __begin2, __end2, __result, __pred);
498  else
499  return _GLIBCXX_STD_A::set_intersection(
500  __begin1, __end1, __begin2, __end2, __result, __pred);
501  }
502 
503  // Public interface
504  template<typename _IIter1, typename _IIter2,
505  typename _OutputIterator>
506  inline _OutputIterator
507  set_intersection(_IIter1 __begin1, _IIter1 __end1,
508  _IIter2 __begin2, _IIter2 __end2,
509  _OutputIterator __out)
510  {
511  typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
512  typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
513 
514  return __set_intersection_switch(
515  __begin1, __end1, __begin2, __end2, __out,
517  std::__iterator_category(__begin1),
518  std::__iterator_category(__begin2),
519  std::__iterator_category(__out));
520  }
521 
522  template<typename _IIter1, typename _IIter2,
523  typename _OutputIterator, typename _Predicate>
524  inline _OutputIterator
525  set_intersection(_IIter1 __begin1, _IIter1 __end1,
526  _IIter2 __begin2, _IIter2 __end2,
527  _OutputIterator __out, _Predicate __pred)
528  {
529  return __set_intersection_switch(
530  __begin1, __end1, __begin2, __end2, __out, __pred,
531  std::__iterator_category(__begin1),
532  std::__iterator_category(__begin2),
533  std::__iterator_category(__out));
534  }
535 
536  // Sequential fallback
537  template<typename _IIter1, typename _IIter2,
538  typename _OutputIterator>
539  inline _OutputIterator
540  set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
541  _IIter2 __begin2, _IIter2 __end2,
542  _OutputIterator __out,
544  { return _GLIBCXX_STD_A::set_symmetric_difference(
545  __begin1, __end1, __begin2, __end2, __out); }
546 
547  // Sequential fallback
548  template<typename _IIter1, typename _IIter2,
549  typename _OutputIterator, typename _Predicate>
550  inline _OutputIterator
551  set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
552  _IIter2 __begin2, _IIter2 __end2,
553  _OutputIterator __out, _Predicate __pred,
555  { return _GLIBCXX_STD_A::set_symmetric_difference(
556  __begin1, __end1, __begin2, __end2, __out, __pred); }
557 
558  // Sequential fallback for input iterator case
559  template<typename _IIter1, typename _IIter2,
560  typename _Predicate, typename _OutputIterator,
561  typename _IteratorTag1, typename _IteratorTag2,
562  typename _IteratorTag3>
563  inline _OutputIterator
564  __set_symmetric_difference_switch(
565  _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
566  _OutputIterator __result, _Predicate __pred,
567  _IteratorTag1, _IteratorTag2, _IteratorTag3)
568  { return _GLIBCXX_STD_A::set_symmetric_difference(
569  __begin1, __end1, __begin2, __end2, __result, __pred); }
570 
571  // Parallel set_symmetric_difference for random access iterators
572  template<typename _RAIter1, typename _RAIter2,
573  typename _Output_RAIter, typename _Predicate>
574  _Output_RAIter
575  __set_symmetric_difference_switch(_RAIter1 __begin1,
576  _RAIter1 __end1,
577  _RAIter2 __begin2,
578  _RAIter2 __end2,
579  _Output_RAIter __result,
580  _Predicate __pred,
584  {
586  static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
587  >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
588  || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
589  >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
590  return __gnu_parallel::__parallel_set_symmetric_difference(
591  __begin1, __end1, __begin2, __end2, __result, __pred);
592  else
593  return _GLIBCXX_STD_A::set_symmetric_difference(
594  __begin1, __end1, __begin2, __end2, __result, __pred);
595  }
596 
597  // Public interface.
598  template<typename _IIter1, typename _IIter2,
599  typename _OutputIterator>
600  inline _OutputIterator
601  set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
602  _IIter2 __begin2, _IIter2 __end2,
603  _OutputIterator __out)
604  {
605  typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
606  typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
607 
608  return __set_symmetric_difference_switch(
609  __begin1, __end1, __begin2, __end2, __out,
611  std::__iterator_category(__begin1),
612  std::__iterator_category(__begin2),
613  std::__iterator_category(__out));
614  }
615 
616  // Public interface.
617  template<typename _IIter1, typename _IIter2,
618  typename _OutputIterator, typename _Predicate>
619  inline _OutputIterator
620  set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
621  _IIter2 __begin2, _IIter2 __end2,
622  _OutputIterator __out, _Predicate __pred)
623  {
624  return __set_symmetric_difference_switch(
625  __begin1, __end1, __begin2, __end2, __out, __pred,
626  std::__iterator_category(__begin1),
627  std::__iterator_category(__begin2),
628  std::__iterator_category(__out));
629  }
630 
631  // Sequential fallback.
632  template<typename _IIter1, typename _IIter2,
633  typename _OutputIterator>
634  inline _OutputIterator
635  set_difference(_IIter1 __begin1, _IIter1 __end1,
636  _IIter2 __begin2, _IIter2 __end2,
637  _OutputIterator __out, __gnu_parallel::sequential_tag)
638  { return _GLIBCXX_STD_A::set_difference(
639  __begin1,__end1, __begin2, __end2, __out); }
640 
641  // Sequential fallback.
642  template<typename _IIter1, typename _IIter2,
643  typename _OutputIterator, typename _Predicate>
644  inline _OutputIterator
645  set_difference(_IIter1 __begin1, _IIter1 __end1,
646  _IIter2 __begin2, _IIter2 __end2,
647  _OutputIterator __out, _Predicate __pred,
649  { return _GLIBCXX_STD_A::set_difference(__begin1, __end1,
650  __begin2, __end2, __out, __pred); }
651 
652  // Sequential fallback for input iterator case.
653  template<typename _IIter1, typename _IIter2, typename _Predicate,
654  typename _OutputIterator, typename _IteratorTag1,
655  typename _IteratorTag2, typename _IteratorTag3>
656  inline _OutputIterator
657  __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
658  _IIter2 __begin2, _IIter2 __end2,
659  _OutputIterator __result, _Predicate __pred,
660  _IteratorTag1, _IteratorTag2, _IteratorTag3)
661  { return _GLIBCXX_STD_A::set_difference(
662  __begin1, __end1, __begin2, __end2, __result, __pred); }
663 
664  // Parallel set_difference for random access iterators
665  template<typename _RAIter1, typename _RAIter2,
666  typename _Output_RAIter, typename _Predicate>
667  _Output_RAIter
668  __set_difference_switch(_RAIter1 __begin1,
669  _RAIter1 __end1,
670  _RAIter2 __begin2,
671  _RAIter2 __end2,
672  _Output_RAIter __result, _Predicate __pred,
676  {
678  static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
679  >= __gnu_parallel::_Settings::get().set_difference_minimal_n
680  || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
681  >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
682  return __gnu_parallel::__parallel_set_difference(
683  __begin1, __end1, __begin2, __end2, __result, __pred);
684  else
685  return _GLIBCXX_STD_A::set_difference(
686  __begin1, __end1, __begin2, __end2, __result, __pred);
687  }
688 
689  // Public interface
690  template<typename _IIter1, typename _IIter2,
691  typename _OutputIterator>
692  inline _OutputIterator
693  set_difference(_IIter1 __begin1, _IIter1 __end1,
694  _IIter2 __begin2, _IIter2 __end2,
695  _OutputIterator __out)
696  {
697  typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
698  typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
699 
700  return __set_difference_switch(
701  __begin1, __end1, __begin2, __end2, __out,
703  std::__iterator_category(__begin1),
704  std::__iterator_category(__begin2),
705  std::__iterator_category(__out));
706  }
707 
708  // Public interface
709  template<typename _IIter1, typename _IIter2,
710  typename _OutputIterator, typename _Predicate>
711  inline _OutputIterator
712  set_difference(_IIter1 __begin1, _IIter1 __end1,
713  _IIter2 __begin2, _IIter2 __end2,
714  _OutputIterator __out, _Predicate __pred)
715  {
716  return __set_difference_switch(
717  __begin1, __end1, __begin2, __end2, __out, __pred,
718  std::__iterator_category(__begin1),
719  std::__iterator_category(__begin2),
720  std::__iterator_category(__out));
721  }
722 
723  // Sequential fallback
724  template<typename _FIterator>
725  inline _FIterator
726  adjacent_find(_FIterator __begin, _FIterator __end,
728  { return _GLIBCXX_STD_A::adjacent_find(__begin, __end); }
729 
730  // Sequential fallback
731  template<typename _FIterator, typename _BinaryPredicate>
732  inline _FIterator
733  adjacent_find(_FIterator __begin, _FIterator __end,
734  _BinaryPredicate __binary_pred,
736  { return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); }
737 
738  // Parallel algorithm for random access iterators
739  template<typename _RAIter>
740  _RAIter
741  __adjacent_find_switch(_RAIter __begin, _RAIter __end,
743  {
744  typedef iterator_traits<_RAIter> _TraitsType;
745  typedef typename _TraitsType::value_type _ValueType;
746 
747  if (_GLIBCXX_PARALLEL_CONDITION(true))
748  {
749  _RAIter __spot = __gnu_parallel::
751  __begin, __end - 1, __begin, equal_to<_ValueType>(),
753  .first;
754  if (__spot == (__end - 1))
755  return __end;
756  else
757  return __spot;
758  }
759  else
760  return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
761  }
762 
763  // Sequential fallback for input iterator case
764  template<typename _FIterator, typename _IteratorTag>
765  inline _FIterator
766  __adjacent_find_switch(_FIterator __begin, _FIterator __end,
767  _IteratorTag)
768  { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }
769 
770  // Public interface
771  template<typename _FIterator>
772  inline _FIterator
773  adjacent_find(_FIterator __begin, _FIterator __end)
774  {
775  return __adjacent_find_switch(__begin, __end,
776  std::__iterator_category(__begin));
777  }
778 
779  // Sequential fallback for input iterator case
780  template<typename _FIterator, typename _BinaryPredicate,
781  typename _IteratorTag>
782  inline _FIterator
783  __adjacent_find_switch(_FIterator __begin, _FIterator __end,
784  _BinaryPredicate __pred, _IteratorTag)
785  { return adjacent_find(__begin, __end, __pred,
787 
788  // Parallel algorithm for random access iterators
789  template<typename _RAIter, typename _BinaryPredicate>
790  _RAIter
791  __adjacent_find_switch(_RAIter __begin, _RAIter __end,
792  _BinaryPredicate __pred, random_access_iterator_tag)
793  {
794  if (_GLIBCXX_PARALLEL_CONDITION(true))
795  return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
797  __adjacent_find_selector()).first;
798  else
799  return adjacent_find(__begin, __end, __pred,
801  }
802 
803  // Public interface
804  template<typename _FIterator, typename _BinaryPredicate>
805  inline _FIterator
806  adjacent_find(_FIterator __begin, _FIterator __end,
807  _BinaryPredicate __pred)
808  {
809  return __adjacent_find_switch(__begin, __end, __pred,
810  std::__iterator_category(__begin));
811  }
812 
813  // Sequential fallback
814  template<typename _IIter, typename _Tp>
816  count(_IIter __begin, _IIter __end, const _Tp& __value,
818  { return _GLIBCXX_STD_A::count(__begin, __end, __value); }
819 
820  // Parallel code for random access iterators
821  template<typename _RAIter, typename _Tp>
823  __count_switch(_RAIter __begin, _RAIter __end,
824  const _Tp& __value, random_access_iterator_tag,
825  __gnu_parallel::_Parallelism __parallelism_tag)
826  {
827  typedef iterator_traits<_RAIter> _TraitsType;
828  typedef typename _TraitsType::value_type _ValueType;
829  typedef typename _TraitsType::difference_type _DifferenceType;
831 
833  static_cast<_SequenceIndex>(__end - __begin)
834  >= __gnu_parallel::_Settings::get().count_minimal_n
835  && __gnu_parallel::__is_parallel(__parallelism_tag)))
836  {
838  __functionality;
839  _DifferenceType __res = 0;
842  __begin, __end, __value, __functionality,
843  std::plus<_SequenceIndex>(), __res, __res, -1,
844  __parallelism_tag);
845  return __res;
846  }
847  else
848  return count(__begin, __end, __value,
850  }
851 
852  // Sequential fallback for input iterator case.
853  template<typename _IIter, typename _Tp, typename _IteratorTag>
855  __count_switch(_IIter __begin, _IIter __end, const _Tp& __value,
856  _IteratorTag)
857  { return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
858  }
859 
860  // Public interface.
861  template<typename _IIter, typename _Tp>
863  count(_IIter __begin, _IIter __end, const _Tp& __value,
864  __gnu_parallel::_Parallelism __parallelism_tag)
865  {
866  return __count_switch(__begin, __end, __value,
867  std::__iterator_category(__begin),
868  __parallelism_tag);
869  }
870 
871  template<typename _IIter, typename _Tp>
873  count(_IIter __begin, _IIter __end, const _Tp& __value)
874  {
875  return __count_switch(__begin, __end, __value,
876  std::__iterator_category(__begin));
877  }
878 
879 
880  // Sequential fallback.
881  template<typename _IIter, typename _Predicate>
883  count_if(_IIter __begin, _IIter __end, _Predicate __pred,
885  { return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); }
886 
887  // Parallel count_if for random access iterators
888  template<typename _RAIter, typename _Predicate>
890  __count_if_switch(_RAIter __begin, _RAIter __end,
891  _Predicate __pred, random_access_iterator_tag,
892  __gnu_parallel::_Parallelism __parallelism_tag)
893  {
894  typedef iterator_traits<_RAIter> _TraitsType;
895  typedef typename _TraitsType::value_type _ValueType;
896  typedef typename _TraitsType::difference_type _DifferenceType;
898 
900  static_cast<_SequenceIndex>(__end - __begin)
901  >= __gnu_parallel::_Settings::get().count_minimal_n
902  && __gnu_parallel::__is_parallel(__parallelism_tag)))
903  {
904  _DifferenceType __res = 0;
905  __gnu_parallel::
906  __count_if_selector<_RAIter, _DifferenceType>
907  __functionality;
910  __begin, __end, __pred, __functionality,
911  std::plus<_SequenceIndex>(), __res, __res, -1,
912  __parallelism_tag);
913  return __res;
914  }
915  else
916  return count_if(__begin, __end, __pred,
918  }
919 
920  // Sequential fallback for input iterator case.
921  template<typename _IIter, typename _Predicate, typename _IteratorTag>
923  __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
924  _IteratorTag)
925  { return count_if(__begin, __end, __pred,
927 
928  // Public interface.
929  template<typename _IIter, typename _Predicate>
931  count_if(_IIter __begin, _IIter __end, _Predicate __pred,
932  __gnu_parallel::_Parallelism __parallelism_tag)
933  {
934  return __count_if_switch(__begin, __end, __pred,
935  std::__iterator_category(__begin),
936  __parallelism_tag);
937  }
938 
939  template<typename _IIter, typename _Predicate>
941  count_if(_IIter __begin, _IIter __end, _Predicate __pred)
942  {
943  return __count_if_switch(__begin, __end, __pred,
944  std::__iterator_category(__begin));
945  }
946 
947 
948  // Sequential fallback.
949  template<typename _FIterator1, typename _FIterator2>
950  inline _FIterator1
951  search(_FIterator1 __begin1, _FIterator1 __end1,
952  _FIterator2 __begin2, _FIterator2 __end2,
954  { return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); }
955 
956  // Parallel algorithm for random access iterator
957  template<typename _RAIter1, typename _RAIter2>
958  _RAIter1
959  __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
960  _RAIter2 __begin2, _RAIter2 __end2,
962  {
963  typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1;
964  typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2;
965 
967  static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
968  >= __gnu_parallel::_Settings::get().search_minimal_n))
969  return __gnu_parallel::
971  __begin1, __end1, __begin2, __end2,
973  else
974  return search(__begin1, __end1, __begin2, __end2,
976  }
977 
978  // Sequential fallback for input iterator case
979  template<typename _FIterator1, typename _FIterator2,
980  typename _IteratorTag1, typename _IteratorTag2>
981  inline _FIterator1
982  __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
983  _FIterator2 __begin2, _FIterator2 __end2,
984  _IteratorTag1, _IteratorTag2)
985  { return search(__begin1, __end1, __begin2, __end2,
987 
988  // Public interface.
989  template<typename _FIterator1, typename _FIterator2>
990  inline _FIterator1
991  search(_FIterator1 __begin1, _FIterator1 __end1,
992  _FIterator2 __begin2, _FIterator2 __end2)
993  {
994  return __search_switch(__begin1, __end1, __begin2, __end2,
995  std::__iterator_category(__begin1),
996  std::__iterator_category(__begin2));
997  }
998 
999  // Public interface.
1000  template<typename _FIterator1, typename _FIterator2,
1001  typename _BinaryPredicate>
1002  inline _FIterator1
1003  search(_FIterator1 __begin1, _FIterator1 __end1,
1004  _FIterator2 __begin2, _FIterator2 __end2,
1005  _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
1006  { return _GLIBCXX_STD_A::search(
1007  __begin1, __end1, __begin2, __end2, __pred); }
1008 
1009  // Parallel algorithm for random access iterator.
1010  template<typename _RAIter1, typename _RAIter2,
1011  typename _BinaryPredicate>
1012  _RAIter1
1013  __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
1014  _RAIter2 __begin2, _RAIter2 __end2,
1015  _BinaryPredicate __pred,
1017  {
1019  static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
1020  >= __gnu_parallel::_Settings::get().search_minimal_n))
1021  return __gnu_parallel::__search_template(__begin1, __end1,
1022  __begin2, __end2, __pred);
1023  else
1024  return search(__begin1, __end1, __begin2, __end2, __pred,
1026  }
1027 
1028  // Sequential fallback for input iterator case
1029  template<typename _FIterator1, typename _FIterator2,
1030  typename _BinaryPredicate, typename _IteratorTag1,
1031  typename _IteratorTag2>
1032  inline _FIterator1
1033  __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
1034  _FIterator2 __begin2, _FIterator2 __end2,
1035  _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
1036  { return search(__begin1, __end1, __begin2, __end2, __pred,
1038 
1039  // Public interface
1040  template<typename _FIterator1, typename _FIterator2,
1041  typename _BinaryPredicate>
1042  inline _FIterator1
1043  search(_FIterator1 __begin1, _FIterator1 __end1,
1044  _FIterator2 __begin2, _FIterator2 __end2,
1045  _BinaryPredicate __pred)
1046  {
1047  return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
1048  std::__iterator_category(__begin1),
1049  std::__iterator_category(__begin2));
1050  }
1051 
1052 #if __cplusplus >= 201703L
1053  /** @brief Search a sequence using a Searcher object.
1054  *
1055  * @param __first A forward iterator.
1056  * @param __last A forward iterator.
1057  * @param __searcher A callable object.
1058  * @return @p __searcher(__first,__last).first
1059  */
1060  template<typename _ForwardIterator, typename _Searcher>
1061  inline _ForwardIterator
1062  search(_ForwardIterator __first, _ForwardIterator __last,
1063  const _Searcher& __searcher)
1064  { return __searcher(__first, __last).first; }
1065 #endif
1066 
1067  // Sequential fallback
1068  template<typename _FIterator, typename _Integer, typename _Tp>
1069  inline _FIterator
1070  search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1071  const _Tp& __val, __gnu_parallel::sequential_tag)
1072  { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); }
1073 
1074  // Sequential fallback
1075  template<typename _FIterator, typename _Integer, typename _Tp,
1076  typename _BinaryPredicate>
1077  inline _FIterator
1078  search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1079  const _Tp& __val, _BinaryPredicate __binary_pred,
1081  { return _GLIBCXX_STD_A::search_n(
1082  __begin, __end, __count, __val, __binary_pred); }
1083 
1084  // Public interface.
1085  template<typename _FIterator, typename _Integer, typename _Tp>
1086  inline _FIterator
1087  search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1088  const _Tp& __val)
1089  {
1090  typedef typename iterator_traits<_FIterator>::value_type _ValueType;
1091  return __gnu_parallel::search_n(__begin, __end, __count, __val,
1093  }
1094 
1095  // Parallel algorithm for random access iterators.
1096  template<typename _RAIter, typename _Integer,
1097  typename _Tp, typename _BinaryPredicate>
1098  _RAIter
1099  __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count,
1100  const _Tp& __val, _BinaryPredicate __binary_pred,
1101  random_access_iterator_tag)
1102  {
1104  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1105  >= __gnu_parallel::_Settings::get().search_minimal_n))
1106  {
1109  __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
1110  }
1111  else
1112  return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
1113  __binary_pred);
1114  }
1115 
1116  // Sequential fallback for input iterator case.
1117  template<typename _FIterator, typename _Integer, typename _Tp,
1118  typename _BinaryPredicate, typename _IteratorTag>
1119  inline _FIterator
1120  __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count,
1121  const _Tp& __val, _BinaryPredicate __binary_pred,
1122  _IteratorTag)
1123  { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
1124  __binary_pred); }
1125 
1126  // Public interface.
1127  template<typename _FIterator, typename _Integer, typename _Tp,
1128  typename _BinaryPredicate>
1129  inline _FIterator
1130  search_n(_FIterator __begin, _FIterator __end, _Integer __count,
1131  const _Tp& __val, _BinaryPredicate __binary_pred)
1132  {
1133  return __search_n_switch(__begin, __end, __count, __val, __binary_pred,
1134  std::__iterator_category(__begin));
1135  }
1136 
1137 
1138  // Sequential fallback.
1139  template<typename _IIter, typename _OutputIterator,
1140  typename _UnaryOperation>
1141  inline _OutputIterator
1142  transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1143  _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
1144  { return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); }
1145 
1146  // Parallel unary transform for random access iterators.
1147  template<typename _RAIter1, typename _RAIter2,
1148  typename _UnaryOperation>
1149  _RAIter2
1150  __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
1151  _RAIter2 __result, _UnaryOperation __unary_op,
1152  random_access_iterator_tag, random_access_iterator_tag,
1153  __gnu_parallel::_Parallelism __parallelism_tag)
1154  {
1156  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1157  >= __gnu_parallel::_Settings::get().transform_minimal_n
1158  && __gnu_parallel::__is_parallel(__parallelism_tag)))
1159  {
1160  bool __dummy = true;
1161  typedef __gnu_parallel::_IteratorPair<_RAIter1,
1162  _RAIter2, random_access_iterator_tag> _ItTrip;
1163  _ItTrip __begin_pair(__begin, __result),
1164  __end_pair(__end, __result + (__end - __begin));
1168  __begin_pair, __end_pair, __unary_op, __functionality,
1170  __dummy, __dummy, -1, __parallelism_tag);
1171  return __functionality._M_finish_iterator;
1172  }
1173  else
1174  return transform(__begin, __end, __result, __unary_op,
1176  }
1177 
1178  // Sequential fallback for input iterator case.
1179  template<typename _RAIter1, typename _RAIter2,
1180  typename _UnaryOperation, typename _IteratorTag1,
1181  typename _IteratorTag2>
1182  inline _RAIter2
1183  __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
1184  _RAIter2 __result, _UnaryOperation __unary_op,
1185  _IteratorTag1, _IteratorTag2)
1186  { return transform(__begin, __end, __result, __unary_op,
1188 
1189  // Public interface.
1190  template<typename _IIter, typename _OutputIterator,
1191  typename _UnaryOperation>
1192  inline _OutputIterator
1193  transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1194  _UnaryOperation __unary_op,
1195  __gnu_parallel::_Parallelism __parallelism_tag)
1196  {
1197  return __transform1_switch(__begin, __end, __result, __unary_op,
1198  std::__iterator_category(__begin),
1199  std::__iterator_category(__result),
1200  __parallelism_tag);
1201  }
1202 
1203  template<typename _IIter, typename _OutputIterator,
1204  typename _UnaryOperation>
1205  inline _OutputIterator
1206  transform(_IIter __begin, _IIter __end, _OutputIterator __result,
1207  _UnaryOperation __unary_op)
1208  {
1209  return __transform1_switch(__begin, __end, __result, __unary_op,
1210  std::__iterator_category(__begin),
1211  std::__iterator_category(__result));
1212  }
1213 
1214 
1215  // Sequential fallback
1216  template<typename _IIter1, typename _IIter2,
1217  typename _OutputIterator, typename _BinaryOperation>
1218  inline _OutputIterator
1219  transform(_IIter1 __begin1, _IIter1 __end1,
1220  _IIter2 __begin2, _OutputIterator __result,
1221  _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
1222  { return _GLIBCXX_STD_A::transform(__begin1, __end1,
1223  __begin2, __result, __binary_op); }
1224 
1225  // Parallel binary transform for random access iterators.
1226  template<typename _RAIter1, typename _RAIter2,
1227  typename _RAIter3, typename _BinaryOperation>
1228  _RAIter3
1229  __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
1230  _RAIter2 __begin2,
1231  _RAIter3 __result, _BinaryOperation __binary_op,
1232  random_access_iterator_tag, random_access_iterator_tag,
1233  random_access_iterator_tag,
1234  __gnu_parallel::_Parallelism __parallelism_tag)
1235  {
1237  (__end1 - __begin1) >=
1238  __gnu_parallel::_Settings::get().transform_minimal_n
1239  && __gnu_parallel::__is_parallel(__parallelism_tag)))
1240  {
1241  bool __dummy = true;
1242  typedef __gnu_parallel::_IteratorTriple<_RAIter1,
1243  _RAIter2, _RAIter3,
1244  random_access_iterator_tag> _ItTrip;
1245  _ItTrip __begin_triple(__begin1, __begin2, __result),
1246  __end_triple(__end1, __begin2 + (__end1 - __begin1),
1247  __result + (__end1 - __begin1));
1250  __for_each_template_random_access(__begin_triple, __end_triple,
1251  __binary_op, __functionality,
1253  __dummy, __dummy, -1,
1254  __parallelism_tag);
1255  return __functionality._M_finish_iterator;
1256  }
1257  else
1258  return transform(__begin1, __end1, __begin2, __result, __binary_op,
1260  }
1261 
1262  // Sequential fallback for input iterator case.
1263  template<typename _IIter1, typename _IIter2,
1264  typename _OutputIterator, typename _BinaryOperation,
1265  typename _Tag1, typename _Tag2, typename _Tag3>
1266  inline _OutputIterator
1267  __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
1268  _IIter2 __begin2, _OutputIterator __result,
1269  _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
1270  { return transform(__begin1, __end1, __begin2, __result, __binary_op,
1272 
1273  // Public interface.
1274  template<typename _IIter1, typename _IIter2,
1275  typename _OutputIterator, typename _BinaryOperation>
1276  inline _OutputIterator
1277  transform(_IIter1 __begin1, _IIter1 __end1,
1278  _IIter2 __begin2, _OutputIterator __result,
1279  _BinaryOperation __binary_op,
1280  __gnu_parallel::_Parallelism __parallelism_tag)
1281  {
1282  return __transform2_switch(
1283  __begin1, __end1, __begin2, __result, __binary_op,
1284  std::__iterator_category(__begin1),
1285  std::__iterator_category(__begin2),
1286  std::__iterator_category(__result),
1287  __parallelism_tag);
1288  }
1289 
1290  template<typename _IIter1, typename _IIter2,
1291  typename _OutputIterator, typename _BinaryOperation>
1292  inline _OutputIterator
1293  transform(_IIter1 __begin1, _IIter1 __end1,
1294  _IIter2 __begin2, _OutputIterator __result,
1295  _BinaryOperation __binary_op)
1296  {
1297  return __transform2_switch(
1298  __begin1, __end1, __begin2, __result, __binary_op,
1299  std::__iterator_category(__begin1),
1300  std::__iterator_category(__begin2),
1301  std::__iterator_category(__result));
1302  }
1303 
1304  // Sequential fallback
1305  template<typename _FIterator, typename _Tp>
1306  inline void
1307  replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1308  const _Tp& __new_value, __gnu_parallel::sequential_tag)
1309  { _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); }
1310 
1311  // Sequential fallback for input iterator case
1312  template<typename _FIterator, typename _Tp, typename _IteratorTag>
1313  inline void
1314  __replace_switch(_FIterator __begin, _FIterator __end,
1315  const _Tp& __old_value, const _Tp& __new_value,
1316  _IteratorTag)
1317  { replace(__begin, __end, __old_value, __new_value,
1319 
1320  // Parallel replace for random access iterators
1321  template<typename _RAIter, typename _Tp>
1322  inline void
1323  __replace_switch(_RAIter __begin, _RAIter __end,
1324  const _Tp& __old_value, const _Tp& __new_value,
1325  random_access_iterator_tag,
1326  __gnu_parallel::_Parallelism __parallelism_tag)
1327  {
1328  // XXX parallel version is where?
1329  replace(__begin, __end, __old_value, __new_value,
1331  }
1332 
1333  // Public interface
1334  template<typename _FIterator, typename _Tp>
1335  inline void
1336  replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1337  const _Tp& __new_value,
1338  __gnu_parallel::_Parallelism __parallelism_tag)
1339  {
1340  __replace_switch(__begin, __end, __old_value, __new_value,
1341  std::__iterator_category(__begin),
1342  __parallelism_tag);
1343  }
1344 
1345  template<typename _FIterator, typename _Tp>
1346  inline void
1347  replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
1348  const _Tp& __new_value)
1349  {
1350  __replace_switch(__begin, __end, __old_value, __new_value,
1351  std::__iterator_category(__begin));
1352  }
1353 
1354 
1355  // Sequential fallback
1356  template<typename _FIterator, typename _Predicate, typename _Tp>
1357  inline void
1358  replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
1359  const _Tp& __new_value, __gnu_parallel::sequential_tag)
1360  { _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); }
1361 
1362  // Sequential fallback for input iterator case
1363  template<typename _FIterator, typename _Predicate, typename _Tp,
1364  typename _IteratorTag>
1365  inline void
1366  __replace_if_switch(_FIterator __begin, _FIterator __end,
1367  _Predicate __pred, const _Tp& __new_value, _IteratorTag)
1368  { replace_if(__begin, __end, __pred, __new_value,
1370 
1371  // Parallel algorithm for random access iterators.
1372  template<typename _RAIter, typename _Predicate, typename _Tp>
1373  void
1374  __replace_if_switch(_RAIter __begin, _RAIter __end,
1375  _Predicate __pred, const _Tp& __new_value,
1376  random_access_iterator_tag,
1377  __gnu_parallel::_Parallelism __parallelism_tag)
1378  {
1380  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1381  >= __gnu_parallel::_Settings::get().replace_minimal_n
1382  && __gnu_parallel::__is_parallel(__parallelism_tag)))
1383  {
1384  bool __dummy;
1385  __gnu_parallel::
1386  __replace_if_selector<_RAIter, _Predicate, _Tp>
1387  __functionality(__new_value);
1390  __begin, __end, __pred, __functionality,
1392  true, __dummy, -1, __parallelism_tag);
1393  }
1394  else
1395  replace_if(__begin, __end, __pred, __new_value,
1397  }
1398 
1399  // Public interface.
1400  template<typename _FIterator, typename _Predicate, typename _Tp>
1401  inline void
1402  replace_if(_FIterator __begin, _FIterator __end,
1403  _Predicate __pred, const _Tp& __new_value,
1404  __gnu_parallel::_Parallelism __parallelism_tag)
1405  {
1406  __replace_if_switch(__begin, __end, __pred, __new_value,
1407  std::__iterator_category(__begin),
1408  __parallelism_tag);
1409  }
1410 
1411  template<typename _FIterator, typename _Predicate, typename _Tp>
1412  inline void
1413  replace_if(_FIterator __begin, _FIterator __end,
1414  _Predicate __pred, const _Tp& __new_value)
1415  {
1416  __replace_if_switch(__begin, __end, __pred, __new_value,
1417  std::__iterator_category(__begin));
1418  }
1419 
1420  // Sequential fallback
1421  template<typename _FIterator, typename _Generator>
1422  inline void
1423  generate(_FIterator __begin, _FIterator __end, _Generator __gen,
1425  { _GLIBCXX_STD_A::generate(__begin, __end, __gen); }
1426 
1427  // Sequential fallback for input iterator case.
1428  template<typename _FIterator, typename _Generator, typename _IteratorTag>
1429  inline void
1430  __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen,
1431  _IteratorTag)
1432  { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }
1433 
1434  // Parallel algorithm for random access iterators.
1435  template<typename _RAIter, typename _Generator>
1436  void
1437  __generate_switch(_RAIter __begin, _RAIter __end,
1438  _Generator __gen, random_access_iterator_tag,
1439  __gnu_parallel::_Parallelism __parallelism_tag)
1440  {
1442  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1443  >= __gnu_parallel::_Settings::get().generate_minimal_n
1444  && __gnu_parallel::__is_parallel(__parallelism_tag)))
1445  {
1446  bool __dummy;
1448  __functionality;
1451  __begin, __end, __gen, __functionality,
1453  true, __dummy, -1, __parallelism_tag);
1454  }
1455  else
1456  generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
1457  }
1458 
1459  // Public interface.
1460  template<typename _FIterator, typename _Generator>
1461  inline void
1462  generate(_FIterator __begin, _FIterator __end,
1463  _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
1464  {
1465  __generate_switch(__begin, __end, __gen,
1466  std::__iterator_category(__begin),
1467  __parallelism_tag);
1468  }
1469 
1470  template<typename _FIterator, typename _Generator>
1471  inline void
1472  generate(_FIterator __begin, _FIterator __end, _Generator __gen)
1473  {
1474  __generate_switch(__begin, __end, __gen,
1475  std::__iterator_category(__begin));
1476  }
1477 
1478 
1479  // Sequential fallback.
1480  template<typename _OutputIterator, typename _Size, typename _Generator>
1481  inline _OutputIterator
1482  generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
1484  { return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); }
1485 
1486  // Sequential fallback for input iterator case.
1487  template<typename _OutputIterator, typename _Size, typename _Generator,
1488  typename _IteratorTag>
1489  inline _OutputIterator
1490  __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen,
1491  _IteratorTag)
1492  { return generate_n(__begin, __n, __gen,
1494 
1495  // Parallel algorithm for random access iterators.
1496  template<typename _RAIter, typename _Size, typename _Generator>
1497  inline _RAIter
1498  __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen,
1499  random_access_iterator_tag,
1500  __gnu_parallel::_Parallelism __parallelism_tag)
1501  {
1502  // XXX parallel version is where?
1503  return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
1504  }
1505 
1506  // Public interface.
1507  template<typename _OutputIterator, typename _Size, typename _Generator>
1508  inline _OutputIterator
1509  generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
1510  __gnu_parallel::_Parallelism __parallelism_tag)
1511  {
1512  return __generate_n_switch(__begin, __n, __gen,
1513  std::__iterator_category(__begin),
1514  __parallelism_tag);
1515  }
1516 
1517  template<typename _OutputIterator, typename _Size, typename _Generator>
1518  inline _OutputIterator
1519  generate_n(_OutputIterator __begin, _Size __n, _Generator __gen)
1520  {
1521  return __generate_n_switch(__begin, __n, __gen,
1522  std::__iterator_category(__begin));
1523  }
1524 
1525 
1526  // Sequential fallback.
1527  template<typename _RAIter>
1528  inline void
1529  random_shuffle(_RAIter __begin, _RAIter __end,
1531  { _GLIBCXX_STD_A::random_shuffle(__begin, __end); }
1532 
1533  // Sequential fallback.
1534  template<typename _RAIter, typename _RandomNumberGenerator>
1535  inline void
1536  random_shuffle(_RAIter __begin, _RAIter __end,
1537  _RandomNumberGenerator& __rand,
1539  { _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); }
1540 
1541 
1542  /** @brief Functor wrapper for std::rand(). */
1543  template<typename _MustBeInt = int>
1545  {
1546  int
1547  operator()(int __limit)
1548  { return rand() % __limit; }
1549  };
1550 
1551  // Fill in random number generator.
1552  template<typename _RAIter>
1553  inline void
1554  random_shuffle(_RAIter __begin, _RAIter __end)
1555  {
1556  _CRandNumber<> __r;
1557  // Parallelization still possible.
1558  __gnu_parallel::random_shuffle(__begin, __end, __r);
1559  }
1560 
1561  // Parallel algorithm for random access iterators.
1562  template<typename _RAIter, typename _RandomNumberGenerator>
1563  void
1564  random_shuffle(_RAIter __begin, _RAIter __end,
1565 #if __cplusplus >= 201103L
1566  _RandomNumberGenerator&& __rand)
1567 #else
1568  _RandomNumberGenerator& __rand)
1569 #endif
1570  {
1571  if (__begin == __end)
1572  return;
1574  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1575  >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
1576  __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
1577  else
1578  __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
1579  }
1580 
1581  // Sequential fallback.
1582  template<typename _FIterator, typename _Predicate>
1583  inline _FIterator
1584  partition(_FIterator __begin, _FIterator __end,
1585  _Predicate __pred, __gnu_parallel::sequential_tag)
1586  { return _GLIBCXX_STD_A::partition(__begin, __end, __pred); }
1587 
1588  // Sequential fallback for input iterator case.
1589  template<typename _FIterator, typename _Predicate, typename _IteratorTag>
1590  inline _FIterator
1591  __partition_switch(_FIterator __begin, _FIterator __end,
1592  _Predicate __pred, _IteratorTag)
1593  { return partition(__begin, __end, __pred,
1595 
1596  // Parallel algorithm for random access iterators.
1597  template<typename _RAIter, typename _Predicate>
1598  _RAIter
1599  __partition_switch(_RAIter __begin, _RAIter __end,
1600  _Predicate __pred, random_access_iterator_tag)
1601  {
1603  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1604  >= __gnu_parallel::_Settings::get().partition_minimal_n))
1605  {
1606  typedef typename std::iterator_traits<_RAIter>::
1607  difference_type _DifferenceType;
1608  _DifferenceType __middle = __gnu_parallel::
1609  __parallel_partition(__begin, __end, __pred,
1610  __gnu_parallel::__get_max_threads());
1611  return __begin + __middle;
1612  }
1613  else
1614  return partition(__begin, __end, __pred,
1616  }
1617 
1618  // Public interface.
1619  template<typename _FIterator, typename _Predicate>
1620  inline _FIterator
1621  partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
1622  {
1623  return __partition_switch(__begin, __end, __pred,
1624  std::__iterator_category(__begin));
1625  }
1626 
1627  // sort interface
1628 
1629  // Sequential fallback
1630  template<typename _RAIter>
1631  inline void
1632  sort(_RAIter __begin, _RAIter __end,
1634  { _GLIBCXX_STD_A::sort(__begin, __end); }
1635 
1636  // Sequential fallback
1637  template<typename _RAIter, typename _Compare>
1638  inline void
1639  sort(_RAIter __begin, _RAIter __end, _Compare __comp,
1641  { _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end,
1642  __comp); }
1643 
1644  // Public interface
1645  template<typename _RAIter, typename _Compare,
1646  typename _Parallelism>
1647  void
1648  sort(_RAIter __begin, _RAIter __end, _Compare __comp,
1649  _Parallelism __parallelism)
1650  {
1651  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1652 
1653  if (__begin != __end)
1654  {
1656  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
1657  __gnu_parallel::_Settings::get().sort_minimal_n))
1658  __gnu_parallel::__parallel_sort<false>(
1659  __begin, __end, __comp, __parallelism);
1660  else
1661  sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
1662  }
1663  }
1664 
1665  // Public interface, insert default comparator
1666  template<typename _RAIter>
1667  inline void
1668  sort(_RAIter __begin, _RAIter __end)
1669  {
1670  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1671  sort(__begin, __end, std::less<_ValueType>(),
1673  }
1674 
1675  // Public interface, insert default comparator
1676  template<typename _RAIter>
1677  inline void
1678  sort(_RAIter __begin, _RAIter __end,
1680  {
1681  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1682  sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1683  }
1684 
1685  // Public interface, insert default comparator
1686  template<typename _RAIter>
1687  inline void
1688  sort(_RAIter __begin, _RAIter __end,
1689  __gnu_parallel::parallel_tag __parallelism)
1690  {
1691  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1692  sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1693  }
1694 
1695  // Public interface, insert default comparator
1696  template<typename _RAIter>
1697  inline void
1698  sort(_RAIter __begin, _RAIter __end,
1700  {
1701  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1702  sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1703  }
1704 
1705  // Public interface, insert default comparator
1706  template<typename _RAIter>
1707  inline void
1708  sort(_RAIter __begin, _RAIter __end,
1710  {
1711  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1712  sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1713  }
1714 
1715  // Public interface, insert default comparator
1716  template<typename _RAIter>
1717  inline void
1718  sort(_RAIter __begin, _RAIter __end,
1720  {
1721  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1722  sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1723  }
1724 
1725  // Public interface, insert default comparator
1726  template<typename _RAIter>
1727  inline void
1728  sort(_RAIter __begin, _RAIter __end,
1729  __gnu_parallel::quicksort_tag __parallelism)
1730  {
1731  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1732  sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1733  }
1734 
1735  // Public interface, insert default comparator
1736  template<typename _RAIter>
1737  inline void
1738  sort(_RAIter __begin, _RAIter __end,
1740  {
1741  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1742  sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1743  }
1744 
1745  // Public interface
1746  template<typename _RAIter, typename _Compare>
1747  void
1748  sort(_RAIter __begin, _RAIter __end, _Compare __comp)
1749  {
1750  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1751  sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
1752  }
1753 
1754  // stable_sort interface
1755 
1756 
1757  // Sequential fallback
1758  template<typename _RAIter>
1759  inline void
1760  stable_sort(_RAIter __begin, _RAIter __end,
1762  { _GLIBCXX_STD_A::stable_sort(__begin, __end); }
1763 
1764  // Sequential fallback
1765  template<typename _RAIter, typename _Compare>
1766  inline void
1767  stable_sort(_RAIter __begin, _RAIter __end,
1768  _Compare __comp, __gnu_parallel::sequential_tag)
1769  { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(__begin, __end, __comp); }
1770 
1771  // Public interface
1772  template<typename _RAIter, typename _Compare,
1773  typename _Parallelism>
1774  void
1775  stable_sort(_RAIter __begin, _RAIter __end,
1776  _Compare __comp, _Parallelism __parallelism)
1777  {
1778  typedef iterator_traits<_RAIter> _TraitsType;
1779  typedef typename _TraitsType::value_type _ValueType;
1780 
1781  if (__begin != __end)
1782  {
1784  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
1785  __gnu_parallel::_Settings::get().sort_minimal_n))
1786  __gnu_parallel::__parallel_sort<true>(__begin, __end,
1787  __comp, __parallelism);
1788  else
1789  stable_sort(__begin, __end, __comp,
1791  }
1792  }
1793 
1794  // Public interface, insert default comparator
1795  template<typename _RAIter>
1796  inline void
1797  stable_sort(_RAIter __begin, _RAIter __end)
1798  {
1799  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1800  stable_sort(__begin, __end, std::less<_ValueType>(),
1802  }
1803 
1804  // Public interface, insert default comparator
1805  template<typename _RAIter>
1806  inline void
1807  stable_sort(_RAIter __begin, _RAIter __end,
1809  {
1810  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1811  stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1812  }
1813 
1814  // Public interface, insert default comparator
1815  template<typename _RAIter>
1816  inline void
1817  stable_sort(_RAIter __begin, _RAIter __end,
1818  __gnu_parallel::parallel_tag __parallelism)
1819  {
1820  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1821  stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1822  }
1823 
1824  // Public interface, insert default comparator
1825  template<typename _RAIter>
1826  inline void
1827  stable_sort(_RAIter __begin, _RAIter __end,
1829  {
1830  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1831  stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1832  }
1833 
1834  // Public interface, insert default comparator
1835  template<typename _RAIter>
1836  inline void
1837  stable_sort(_RAIter __begin, _RAIter __end,
1838  __gnu_parallel::quicksort_tag __parallelism)
1839  {
1840  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1841  stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1842  }
1843 
1844  // Public interface, insert default comparator
1845  template<typename _RAIter>
1846  inline void
1847  stable_sort(_RAIter __begin, _RAIter __end,
1849  {
1850  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1851  stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
1852  }
1853 
1854  // Public interface
1855  template<typename _RAIter, typename _Compare>
1856  void
1857  stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp)
1858  {
1859  stable_sort(
1860  __begin, __end, __comp, __gnu_parallel::default_parallel_tag());
1861  }
1862 
1863  // Sequential fallback
1864  template<typename _IIter1, typename _IIter2,
1865  typename _OutputIterator>
1866  inline _OutputIterator
1867  merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
1868  _IIter2 __end2, _OutputIterator __result,
1870  { return _GLIBCXX_STD_A::merge(
1871  __begin1, __end1, __begin2, __end2, __result); }
1872 
1873  // Sequential fallback
1874  template<typename _IIter1, typename _IIter2,
1875  typename _OutputIterator, typename _Compare>
1876  inline _OutputIterator
1877  merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
1878  _IIter2 __end2, _OutputIterator __result, _Compare __comp,
1880  { return _GLIBCXX_STD_A::merge(
1881  __begin1, __end1, __begin2, __end2, __result, __comp); }
1882 
1883  // Sequential fallback for input iterator case
1884  template<typename _IIter1, typename _IIter2, typename _OutputIterator,
1885  typename _Compare, typename _IteratorTag1,
1886  typename _IteratorTag2, typename _IteratorTag3>
1887  inline _OutputIterator
1888  __merge_switch(_IIter1 __begin1, _IIter1 __end1,
1889  _IIter2 __begin2, _IIter2 __end2,
1890  _OutputIterator __result, _Compare __comp,
1891  _IteratorTag1, _IteratorTag2, _IteratorTag3)
1892  { return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2,
1893  __result, __comp); }
1894 
1895  // Parallel algorithm for random access iterators
1896  template<typename _IIter1, typename _IIter2,
1897  typename _OutputIterator, typename _Compare>
1898  _OutputIterator
1899  __merge_switch(_IIter1 __begin1, _IIter1 __end1,
1900  _IIter2 __begin2, _IIter2 __end2,
1901  _OutputIterator __result, _Compare __comp,
1902  random_access_iterator_tag, random_access_iterator_tag,
1903  random_access_iterator_tag)
1904  {
1906  (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
1907  >= __gnu_parallel::_Settings::get().merge_minimal_n
1908  || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
1909  >= __gnu_parallel::_Settings::get().merge_minimal_n)))
1911  __begin1, __end1, __begin2, __end2, __result,
1912  (__end1 - __begin1) + (__end2 - __begin2), __comp);
1913  else
1915  __begin1, __end1, __begin2, __end2, __result,
1916  (__end1 - __begin1) + (__end2 - __begin2), __comp);
1917  }
1918 
1919  // Public interface
1920  template<typename _IIter1, typename _IIter2,
1921  typename _OutputIterator, typename _Compare>
1922  inline _OutputIterator
1923  merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
1924  _IIter2 __end2, _OutputIterator __result, _Compare __comp)
1925  {
1926  return __merge_switch(
1927  __begin1, __end1, __begin2, __end2, __result, __comp,
1928  std::__iterator_category(__begin1),
1929  std::__iterator_category(__begin2),
1930  std::__iterator_category(__result));
1931  }
1932 
1933  // Public interface, insert default comparator
1934  template<typename _IIter1, typename _IIter2,
1935  typename _OutputIterator>
1936  inline _OutputIterator
1937  merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
1938  _IIter2 __end2, _OutputIterator __result)
1939  {
1940  typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
1941  typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
1942 
1943  return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2,
1945  }
1946 
1947  // Sequential fallback
1948  template<typename _RAIter>
1949  inline void
1950  nth_element(_RAIter __begin, _RAIter __nth,
1951  _RAIter __end, __gnu_parallel::sequential_tag)
1952  { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); }
1953 
1954  // Sequential fallback
1955  template<typename _RAIter, typename _Compare>
1956  inline void
1957  nth_element(_RAIter __begin, _RAIter __nth,
1958  _RAIter __end, _Compare __comp,
1960  { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); }
1961 
1962  // Public interface
1963  template<typename _RAIter, typename _Compare>
1964  inline void
1965  nth_element(_RAIter __begin, _RAIter __nth,
1966  _RAIter __end, _Compare __comp)
1967  {
1969  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
1970  >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
1971  __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
1972  else
1973  nth_element(__begin, __nth, __end, __comp,
1975  }
1976 
1977  // Public interface, insert default comparator
1978  template<typename _RAIter>
1979  inline void
1980  nth_element(_RAIter __begin, _RAIter __nth,
1981  _RAIter __end)
1982  {
1983  typedef typename iterator_traits<_RAIter>::value_type _ValueType;
1984  __gnu_parallel::nth_element(__begin, __nth, __end,
1986  }
1987 
1988  // Sequential fallback
1989  template<typename _RAIter, typename _Compare>
1990  inline void
1991  partial_sort(_RAIter __begin, _RAIter __middle,
1992  _RAIter __end, _Compare __comp,
1994  { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); }
1995 
1996  // Sequential fallback
1997  template<typename _RAIter>
1998  inline void
1999  partial_sort(_RAIter __begin, _RAIter __middle,
2000  _RAIter __end, __gnu_parallel::sequential_tag)
2001  { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); }
2002 
2003  // Public interface, parallel algorithm for random access iterators
2004  template<typename _RAIter, typename _Compare>
2005  void
2006  partial_sort(_RAIter __begin, _RAIter __middle,
2007  _RAIter __end, _Compare __comp)
2008  {
2010  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2011  >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
2013  __parallel_partial_sort(__begin, __middle, __end, __comp);
2014  else
2015  partial_sort(__begin, __middle, __end, __comp,
2017  }
2018 
2019  // Public interface, insert default comparator
2020  template<typename _RAIter>
2021  inline void
2022  partial_sort(_RAIter __begin, _RAIter __middle,
2023  _RAIter __end)
2024  {
2025  typedef iterator_traits<_RAIter> _TraitsType;
2026  typedef typename _TraitsType::value_type _ValueType;
2027  __gnu_parallel::partial_sort(__begin, __middle, __end,
2029  }
2030 
2031  // Sequential fallback
2032  template<typename _FIterator>
2033  inline _FIterator
2034  max_element(_FIterator __begin, _FIterator __end,
2036  { return _GLIBCXX_STD_A::max_element(__begin, __end); }
2037 
2038  // Sequential fallback
2039  template<typename _FIterator, typename _Compare>
2040  inline _FIterator
2041  max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2043  { return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); }
2044 
2045  // Sequential fallback for input iterator case
2046  template<typename _FIterator, typename _Compare, typename _IteratorTag>
2047  inline _FIterator
2048  __max_element_switch(_FIterator __begin, _FIterator __end,
2049  _Compare __comp, _IteratorTag)
2050  { return max_element(__begin, __end, __comp,
2052 
2053  // Parallel algorithm for random access iterators
2054  template<typename _RAIter, typename _Compare>
2055  _RAIter
2056  __max_element_switch(_RAIter __begin, _RAIter __end,
2057  _Compare __comp, random_access_iterator_tag,
2058  __gnu_parallel::_Parallelism __parallelism_tag)
2059  {
2061  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2062  >= __gnu_parallel::_Settings::get().max_element_minimal_n
2063  && __gnu_parallel::__is_parallel(__parallelism_tag)))
2064  {
2065  _RAIter __res(__begin);
2067  __functionality;
2070  __begin, __end, __gnu_parallel::_Nothing(), __functionality,
2072  __res, __res, -1, __parallelism_tag);
2073  return __res;
2074  }
2075  else
2076  return max_element(__begin, __end, __comp,
2078  }
2079 
2080  // Public interface, insert default comparator
2081  template<typename _FIterator>
2082  inline _FIterator
2083  max_element(_FIterator __begin, _FIterator __end,
2084  __gnu_parallel::_Parallelism __parallelism_tag)
2085  {
2086  typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2087  return max_element(__begin, __end, std::less<_ValueType>(),
2088  __parallelism_tag);
2089  }
2090 
2091  template<typename _FIterator>
2092  inline _FIterator
2093  max_element(_FIterator __begin, _FIterator __end)
2094  {
2095  typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2096  return __gnu_parallel::max_element(__begin, __end,
2098  }
2099 
2100  // Public interface
2101  template<typename _FIterator, typename _Compare>
2102  inline _FIterator
2103  max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2104  __gnu_parallel::_Parallelism __parallelism_tag)
2105  {
2106  return __max_element_switch(__begin, __end, __comp,
2107  std::__iterator_category(__begin),
2108  __parallelism_tag);
2109  }
2110 
2111  template<typename _FIterator, typename _Compare>
2112  inline _FIterator
2113  max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
2114  {
2115  return __max_element_switch(__begin, __end, __comp,
2116  std::__iterator_category(__begin));
2117  }
2118 
2119 
2120  // Sequential fallback
2121  template<typename _FIterator>
2122  inline _FIterator
2123  min_element(_FIterator __begin, _FIterator __end,
2125  { return _GLIBCXX_STD_A::min_element(__begin, __end); }
2126 
2127  // Sequential fallback
2128  template<typename _FIterator, typename _Compare>
2129  inline _FIterator
2130  min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2132  { return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); }
2133 
2134  // Sequential fallback for input iterator case
2135  template<typename _FIterator, typename _Compare, typename _IteratorTag>
2136  inline _FIterator
2137  __min_element_switch(_FIterator __begin, _FIterator __end,
2138  _Compare __comp, _IteratorTag)
2139  { return min_element(__begin, __end, __comp,
2141 
2142  // Parallel algorithm for random access iterators
2143  template<typename _RAIter, typename _Compare>
2144  _RAIter
2145  __min_element_switch(_RAIter __begin, _RAIter __end,
2146  _Compare __comp, random_access_iterator_tag,
2147  __gnu_parallel::_Parallelism __parallelism_tag)
2148  {
2150  static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
2151  >= __gnu_parallel::_Settings::get().min_element_minimal_n
2152  && __gnu_parallel::__is_parallel(__parallelism_tag)))
2153  {
2154  _RAIter __res(__begin);
2156  __functionality;
2159  __begin, __end, __gnu_parallel::_Nothing(), __functionality,
2161  __res, __res, -1, __parallelism_tag);
2162  return __res;
2163  }
2164  else
2165  return min_element(__begin, __end, __comp,
2167  }
2168 
2169  // Public interface, insert default comparator
2170  template<typename _FIterator>
2171  inline _FIterator
2172  min_element(_FIterator __begin, _FIterator __end,
2173  __gnu_parallel::_Parallelism __parallelism_tag)
2174  {
2175  typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2176  return min_element(__begin, __end, std::less<_ValueType>(),
2177  __parallelism_tag);
2178  }
2179 
2180  template<typename _FIterator>
2181  inline _FIterator
2182  min_element(_FIterator __begin, _FIterator __end)
2183  {
2184  typedef typename iterator_traits<_FIterator>::value_type _ValueType;
2185  return __gnu_parallel::min_element(__begin, __end,
2187  }
2188 
2189  // Public interface
2190  template<typename _FIterator, typename _Compare>
2191  inline _FIterator
2192  min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
2193  __gnu_parallel::_Parallelism __parallelism_tag)
2194  {
2195  return __min_element_switch(__begin, __end, __comp,
2196  std::__iterator_category(__begin),
2197  __parallelism_tag);
2198  }
2199 
2200  template<typename _FIterator, typename _Compare>
2201  inline _FIterator
2202  min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
2203  {
2204  return __min_element_switch(__begin, __end, __comp,
2205  std::__iterator_category(__begin));
2206  }
2207 
2208 #if __cplusplus >= 201703L
2210  using _GLIBCXX_STD_A::sample;
2211 #endif
2212 } // end namespace
2213 } // end namespace
2214 
2215 #endif /* _GLIBCXX_PARALLEL_ALGO_H */
Parallel implementation of std::random_shuffle(). This file is a GNU parallel extension to the Standa...
Recommends parallel execution at compile time, optionally using a user-specified number of threads...
Definition: tags.h:46
Test predicate on a single element, used for std::find() and std::find_if ().
void __parallel_partial_sort(_RAIter __begin, _RAIter __middle, _RAIter __end, _Compare __comp)
Parallel implementation of std::partial_sort().
Definition: partition.h:422
Parallel implementation of std::partition(), std::nth_element(), and std::partial_sort(). This file is a GNU parallel extension to the Standard C++ Library.
_RAIter3 __parallel_merge_advance(_RAIter1 &__begin1, _RAIter1 __end1, _RAIter2 &__begin2, _RAIter2 __end2, _RAIter3 __target, typename std::iterator_traits< _RAIter1 >::difference_type __max_length, _Compare __comp)
Merge routine fallback to sequential in case the iterators of the two input sequences are of differen...
Definition: merge.h:195
Parallel implementation base for std::search() and std::search_n(). This file is a GNU parallel exten...
_Function objects representing different tasks to be plugged into the parallel find algorithm...
void __parallel_nth_element(_RAIter __begin, _RAIter __nth, _RAIter __end, _Compare __comp)
Parallel implementation of std::nth_element().
Definition: partition.h:332
#define _GLIBCXX_PARALLEL_CONDITION(__c)
Determine at compile(?)-time if the parallel variant of an algorithm should be called.
Definition: settings.h:94
Similar to std::binder2nd, but giving the argument types explicitly.
Definition: base.h:220
Parallel implementations of set operations for random-access iterators. This file is a GNU parallel e...
Forces parallel sorting using multiway mergesort with splitting by sampling at compile time...
Definition: tags.h:146
Traits class for iterators.
constexpr iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
Main interface for embarrassingly parallel functions.
_UserOp __for_each_template_random_access(_IIter __begin, _IIter __end, _UserOp __user_op, _Functionality &__functionality, _Red __reduction, _Result __reduction_start, _Result &__output, typename std::iterator_traits< _IIter >::difference_type __bound, _Parallelism __parallelism_tag)
Chose the desired algorithm by evaluating __parallelism_tag.
Definition: for_each.h:61
Sequential helper functions. This file is a GNU parallel extension to the Standard C++ Library...
Reduction function doing nothing.
Functors representing different tasks to be plugged into the generic parallelization methods for emba...
Selector that just returns the passed iterator.
Similar to std::less, but allows two different types.
Definition: base.h:252
Forces parallel sorting using balanced quicksort at compile time.
Definition: tags.h:164
One of the math functors.
Definition: stl_function.h:160
Forces sequential execution at compile time.
Definition: tags.h:42
A triple of iterators. The usual iterator operations are applied to all three child iterators...
Definition: iterator.h:120
Reduction for finding the maximum element, using a comparator.
Functor doing nothing.
constexpr _InputIterator for_each_n(_InputIterator __first, _Size __n, _Function __f)
Apply a function to every element of a sequence.
Definition: stl_algo.h:3840
static const _Settings & get()
Get the global settings.
Recommends parallel execution using the default parallel algorithm.
Definition: tags.h:79
Test predicate on two adjacent elements.
A pair of iterators. The usual iterator operations are applied to both child iterators.
Definition: iterator.h:45
Sequence that conceptually consists of multiple copies of the same element. The copies are not stored...
Definition: base.h:359
_ForwardIterator search(_ForwardIterator __first, _ForwardIterator __last, const _Searcher &__searcher)
Search a sequence using a Searcher object.
Definition: algo.h:1062
_It _M_finish_iterator
_Iterator on last element processed; needed for some algorithms (e. g. std::transform()).
void __sequential_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator &__rng)
Sequential cache-efficient random shuffle.
Random-access iterators support a superset of bidirectional iterator operations.
Functor wrapper for std::rand().
Definition: algo.h:1544
Forces parallel sorting using multiway mergesort at compile time.
Definition: tags.h:128
Parallelization of embarrassingly parallel execution by means of equal splitting. This file is a GNU ...
std::transform() __selector, two input sequences variant.
__RAIter1 __search_template(__RAIter1 __begin1, __RAIter1 __end1, __RAIter2 __begin2, __RAIter2 __end2, _Pred __pred)
Parallel std::search.
Definition: search.h:81
Test predicate on several elements.
One of the comparison functors.
Definition: stl_function.h:354
One of the comparison functors.
Definition: stl_function.h:345
std::transform() __selector, one input sequence variant.
std::iterator_traits< _RAIter >::difference_type __parallel_partition(_RAIter __begin, _RAIter __end, _Predicate __pred, _ThreadIndex __num_threads)
Parallel implementation of std::partition.
Definition: partition.h:56
_OutputIterator __merge_advance(_RAIter1 &__begin1, _RAIter1 __end1, _RAIter2 &__begin2, _RAIter2 __end2, _OutputIterator __target, _DifferenceTp __max_length, _Compare __comp)
Merge routine being able to merge only the __max_length smallest elements.
Definition: merge.h:171
Forces parallel sorting using multiway mergesort with exact splitting at compile time.
Definition: tags.h:137
Parallel implementations of std::unique_copy(). This file is a GNU parallel extension to the Standard...
void __parallel_random_shuffle(_RAIter __begin, _RAIter __end, _RandomNumberGenerator __rng=_RandomNumber())
Parallel random public call.
Parallel implementation of std::merge(). This file is a GNU parallel extension to the Standard C++ Li...
Parallelization of embarrassingly parallel execution by means of work-stealing.
Parallelization of embarrassingly parallel execution by means of an OpenMP for loop. This file is a GNU parallel extension to the Standard C++ Library.
Similar to std::equal_to, but allows two different types.
Definition: base.h:244
_OutputIterator __parallel_unique_copy(_IIter __first, _IIter __last, _OutputIterator __result, _BinaryPredicate __binary_pred)
Parallel std::unique_copy(), w/__o explicit equality predicate.
Definition: unique_copy.h:50
GNU parallel code for public use.
Forces parallel sorting using unbalanced quicksort at compile time.
Definition: tags.h:155
Helper iterator classes for the std::transform() functions. This file is a GNU parallel extension to ...
_SampleIterator sample(_PopulationIterator __first, _PopulationIterator __last, _SampleIterator __out, _Distance __n, _UniformRandomBitGenerator &&__g)
Take a random sample from a population.
Definition: stl_algo.h:5845
Parallelization of embarrassingly parallel execution by means of an OpenMP for loop with static sched...
Parallel implementation base for std::find(), std::equal() and related functions. This file is a GNU ...
std::pair< _RAIter1, _RAIter2 > __find_template(_RAIter1 __begin1, _RAIter1 __end1, _RAIter2 __begin2, _Pred __pred, _Selector __selector)
Parallel std::find, switch for different algorithms.
Definition: find.h:60
Reduction for finding the maximum element, using a comparator.
ISO C++ entities toplevel namespace is std.
uint64_t _SequenceIndex
Unsigned integer to index __elements. The total number of elements for each algorithm must fit into t...
Definition: types.h:117
_Parallelism
Run-time equivalents for the compile-time tags.
Definition: types.h:44
Parallel sorting algorithm switch. This file is a GNU parallel extension to the Standard C++ Library...