3 // Copyright (C) 2007-2023 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file parallel/algo.h
26 * @brief Parallel STL function calls corresponding to the stl_algo.h header.
28 * The functions defined here mainly do case switches and
29 * call the actual parallelized versions in other files.
30 * Inlining policy: Functions that basically only contain one function call,
31 * are declared inline.
32 * This file is a GNU parallel extension to the Standard C++ Library.
35 // Written by Johannes Singler and Felix Putze.
37 #ifndef _GLIBCXX_PARALLEL_ALGO_H
38 #define _GLIBCXX_PARALLEL_ALGO_H 1
40 #include <parallel/algorithmfwd.h>
41 #include <bits/stl_algobase.h>
42 #include <bits/stl_algo.h>
43 #include <parallel/iterator.h>
44 #include <parallel/base.h>
45 #include <parallel/sort.h>
46 #include <parallel/workstealing.h>
47 #include <parallel/par_loop.h>
48 #include <parallel/omp_loop.h>
49 #include <parallel/omp_loop_static.h>
50 #include <parallel/for_each_selectors.h>
51 #include <parallel/for_each.h>
52 #include <parallel/find.h>
53 #include <parallel/find_selectors.h>
54 #include <parallel/search.h>
55 #include <parallel/random_shuffle.h>
56 #include <parallel/partition.h>
57 #include <parallel/merge.h>
58 #include <parallel/unique_copy.h>
59 #include <parallel/set_operations.h>
61 namespace std
_GLIBCXX_VISIBILITY(default)
65 // Sequential fallback
66 template<typename _IIter
, typename _Function
>
68 for_each(_IIter __begin
, _IIter __end
, _Function __f
,
69 __gnu_parallel::sequential_tag
)
70 { return _GLIBCXX_STD_A::for_each(__begin
, __end
, __f
); }
72 // Sequential fallback for input iterator case
73 template<typename _IIter
, typename _Function
, typename _IteratorTag
>
75 __for_each_switch(_IIter __begin
, _IIter __end
, _Function __f
,
77 { return for_each(__begin
, __end
, __f
, __gnu_parallel::sequential_tag()); }
79 // Parallel algorithm for random access iterators
80 template<typename _RAIter
, typename _Function
>
82 __for_each_switch(_RAIter __begin
, _RAIter __end
,
83 _Function __f
, random_access_iterator_tag
,
84 __gnu_parallel::_Parallelism __parallelism_tag
)
86 if (_GLIBCXX_PARALLEL_CONDITION(
87 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
88 >= __gnu_parallel::_Settings::get().for_each_minimal_n
89 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
92 __gnu_parallel::__for_each_selector
<_RAIter
> __functionality
;
94 return __gnu_parallel::
95 __for_each_template_random_access(
96 __begin
, __end
, __f
, __functionality
,
97 __gnu_parallel::_DummyReduct(), true, __dummy
, -1,
101 return for_each(__begin
, __end
, __f
, __gnu_parallel::sequential_tag());
105 template<typename _Iterator
, typename _Function
>
107 for_each(_Iterator __begin
, _Iterator __end
, _Function __f
,
108 __gnu_parallel::_Parallelism __parallelism_tag
)
110 return __for_each_switch(__begin
, __end
, __f
,
111 std::__iterator_category(__begin
),
115 template<typename _Iterator
, typename _Function
>
117 for_each(_Iterator __begin
, _Iterator __end
, _Function __f
)
119 return __for_each_switch(__begin
, __end
, __f
,
120 std::__iterator_category(__begin
));
123 // Sequential fallback
124 template<typename _IIter
, typename _Tp
>
126 find(_IIter __begin
, _IIter __end
, const _Tp
& __val
,
127 __gnu_parallel::sequential_tag
)
128 { return _GLIBCXX_STD_A::find(__begin
, __end
, __val
); }
130 // Sequential fallback for input iterator case
131 template<typename _IIter
, typename _Tp
, typename _IteratorTag
>
133 __find_switch(_IIter __begin
, _IIter __end
, const _Tp
& __val
,
135 { return _GLIBCXX_STD_A::find(__begin
, __end
, __val
); }
137 // Parallel find for random access iterators
138 template<typename _RAIter
, typename _Tp
>
140 __find_switch(_RAIter __begin
, _RAIter __end
,
141 const _Tp
& __val
, random_access_iterator_tag
)
143 typedef iterator_traits
<_RAIter
> _TraitsType
;
144 typedef typename
_TraitsType::value_type _ValueType
;
146 if (_GLIBCXX_PARALLEL_CONDITION(true))
148 __gnu_parallel::__binder2nd
<__gnu_parallel::_EqualTo
<_ValueType
,
150 _ValueType
, const _Tp
&, bool>
151 __comp(__gnu_parallel::_EqualTo
<_ValueType
, const _Tp
&>(), __val
);
152 return __gnu_parallel::__find_template(
153 __begin
, __end
, __begin
, __comp
,
154 __gnu_parallel::__find_if_selector()).first
;
157 return _GLIBCXX_STD_A::find(__begin
, __end
, __val
);
161 template<typename _IIter
, typename _Tp
>
163 find(_IIter __begin
, _IIter __end
, const _Tp
& __val
)
165 return __find_switch(__begin
, __end
, __val
,
166 std::__iterator_category(__begin
));
169 // Sequential fallback
170 template<typename _IIter
, typename _Predicate
>
172 find_if(_IIter __begin
, _IIter __end
, _Predicate __pred
,
173 __gnu_parallel::sequential_tag
)
174 { return _GLIBCXX_STD_A::find_if(__begin
, __end
, __pred
); }
176 // Sequential fallback for input iterator case
177 template<typename _IIter
, typename _Predicate
, typename _IteratorTag
>
179 __find_if_switch(_IIter __begin
, _IIter __end
, _Predicate __pred
,
181 { return _GLIBCXX_STD_A::find_if(__begin
, __end
, __pred
); }
183 // Parallel find_if for random access iterators
184 template<typename _RAIter
, typename _Predicate
>
186 __find_if_switch(_RAIter __begin
, _RAIter __end
,
187 _Predicate __pred
, random_access_iterator_tag
)
189 if (_GLIBCXX_PARALLEL_CONDITION(true))
190 return __gnu_parallel::__find_template(__begin
, __end
, __begin
, __pred
,
192 __find_if_selector()).first
;
194 return _GLIBCXX_STD_A::find_if(__begin
, __end
, __pred
);
198 template<typename _IIter
, typename _Predicate
>
200 find_if(_IIter __begin
, _IIter __end
, _Predicate __pred
)
202 return __find_if_switch(__begin
, __end
, __pred
,
203 std::__iterator_category(__begin
));
206 // Sequential fallback
207 template<typename _IIter
, typename _FIterator
>
209 find_first_of(_IIter __begin1
, _IIter __end1
,
210 _FIterator __begin2
, _FIterator __end2
,
211 __gnu_parallel::sequential_tag
)
213 return _GLIBCXX_STD_A::find_first_of(__begin1
, __end1
, __begin2
, __end2
);
216 // Sequential fallback
217 template<typename _IIter
, typename _FIterator
,
218 typename _BinaryPredicate
>
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
); }
226 // Sequential fallback for input iterator type
227 template<typename _IIter
, typename _FIterator
,
228 typename _IteratorTag1
, typename _IteratorTag2
>
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
,
234 __gnu_parallel::sequential_tag()); }
236 // Parallel algorithm for random access iterators
237 template<typename _RAIter
, typename _FIterator
,
238 typename _BinaryPredicate
, typename _IteratorTag
>
240 __find_first_of_switch(_RAIter __begin1
,
242 _FIterator __begin2
, _FIterator __end2
,
243 _BinaryPredicate __comp
, random_access_iterator_tag
,
246 return __gnu_parallel::
247 __find_template(__begin1
, __end1
, __begin1
, __comp
,
248 __gnu_parallel::__find_first_of_selector
249 <_FIterator
>(__begin2
, __end2
)).first
;
252 // Sequential fallback for input iterator type
253 template<typename _IIter
, typename _FIterator
,
254 typename _BinaryPredicate
, typename _IteratorTag1
,
255 typename _IteratorTag2
>
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
,
261 __gnu_parallel::sequential_tag()); }
264 template<typename _IIter
, typename _FIterator
,
265 typename _BinaryPredicate
>
267 find_first_of(_IIter __begin1
, _IIter __end1
,
268 _FIterator __begin2
, _FIterator __end2
,
269 _BinaryPredicate __comp
)
271 return __find_first_of_switch(__begin1
, __end1
, __begin2
, __end2
, __comp
,
272 std::__iterator_category(__begin1
),
273 std::__iterator_category(__begin2
));
276 // Public interface, insert default comparator
277 template<typename _IIter
, typename _FIterator
>
279 find_first_of(_IIter __begin1
, _IIter __end1
,
280 _FIterator __begin2
, _FIterator __end2
)
282 typedef typename
std::iterator_traits
<_IIter
>::value_type _IValueType
;
283 typedef typename
std::iterator_traits
<_FIterator
>::value_type _FValueType
;
285 return __gnu_parallel::find_first_of(__begin1
, __end1
, __begin2
, __end2
,
286 __gnu_parallel::_EqualTo
<_IValueType
, _FValueType
>());
289 // Sequential fallback
290 template<typename _IIter
, typename _OutputIterator
>
291 inline _OutputIterator
292 unique_copy(_IIter __begin1
, _IIter __end1
, _OutputIterator __out
,
293 __gnu_parallel::sequential_tag
)
294 { return _GLIBCXX_STD_A::unique_copy(__begin1
, __end1
, __out
); }
296 // Sequential fallback
297 template<typename _IIter
, typename _OutputIterator
,
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
); }
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
); }
313 // Parallel unique_copy for random access iterators
314 template<typename _RAIter
, typename _RandomAccessOutputIterator
,
316 _RandomAccessOutputIterator
317 __unique_copy_switch(_RAIter __begin
, _RAIter __last
,
318 _RandomAccessOutputIterator __out
, _Predicate __pred
,
319 random_access_iterator_tag
, random_access_iterator_tag
)
321 if (_GLIBCXX_PARALLEL_CONDITION(
322 static_cast<__gnu_parallel::_SequenceIndex
>(__last
- __begin
)
323 > __gnu_parallel::_Settings::get().unique_copy_minimal_n
))
324 return __gnu_parallel::__parallel_unique_copy(
325 __begin
, __last
, __out
, __pred
);
327 return _GLIBCXX_STD_A::unique_copy(__begin
, __last
, __out
, __pred
);
331 template<typename _IIter
, typename _OutputIterator
>
332 inline _OutputIterator
333 unique_copy(_IIter __begin1
, _IIter __end1
, _OutputIterator __out
)
335 typedef typename
std::iterator_traits
<_IIter
>::value_type _ValueType
;
337 return __unique_copy_switch(
338 __begin1
, __end1
, __out
, equal_to
<_ValueType
>(),
339 std::__iterator_category(__begin1
),
340 std::__iterator_category(__out
));
344 template<typename _IIter
, typename _OutputIterator
, typename _Predicate
>
345 inline _OutputIterator
346 unique_copy(_IIter __begin1
, _IIter __end1
, _OutputIterator __out
,
349 return __unique_copy_switch(
350 __begin1
, __end1
, __out
, __pred
,
351 std::__iterator_category(__begin1
),
352 std::__iterator_category(__out
));
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
); }
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
,
372 __gnu_parallel::sequential_tag
)
373 { return _GLIBCXX_STD_A::set_union(__begin1
, __end1
,
374 __begin2
, __end2
, __out
, __pred
); }
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
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
); }
388 // Parallel set_union for random access iterators
389 template<typename _RAIter1
, typename _RAIter2
,
390 typename _Output_RAIter
, typename _Predicate
>
392 __set_union_switch(_RAIter1 __begin1
, _RAIter1 __end1
,
393 _RAIter2 __begin2
, _RAIter2 __end2
,
394 _Output_RAIter __result
, _Predicate __pred
,
395 random_access_iterator_tag
, random_access_iterator_tag
,
396 random_access_iterator_tag
)
398 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
406 return _GLIBCXX_STD_A::set_union(__begin1
, __end1
,
407 __begin2
, __end2
, __result
, __pred
);
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
)
417 typedef typename
std::iterator_traits
<_IIter1
>::value_type _ValueType1
;
418 typedef typename
std::iterator_traits
<_IIter2
>::value_type _ValueType2
;
420 return __set_union_switch(
421 __begin1
, __end1
, __begin2
, __end2
, __out
,
422 __gnu_parallel::_Less
<_ValueType1
, _ValueType2
>(),
423 std::__iterator_category(__begin1
),
424 std::__iterator_category(__begin2
),
425 std::__iterator_category(__out
));
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
)
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
));
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
); }
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
,
460 __gnu_parallel::sequential_tag
)
461 { return _GLIBCXX_STD_A::set_intersection(
462 __begin1
, __end1
, __begin2
, __end2
, __out
, __pred
); }
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
); }
477 // Parallel set_intersection for random access iterators
478 template<typename _RAIter1
, typename _RAIter2
,
479 typename _Output_RAIter
, typename _Predicate
>
481 __set_intersection_switch(_RAIter1 __begin1
,
485 _Output_RAIter __result
,
487 random_access_iterator_tag
,
488 random_access_iterator_tag
,
489 random_access_iterator_tag
)
491 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
499 return _GLIBCXX_STD_A::set_intersection(
500 __begin1
, __end1
, __begin2
, __end2
, __result
, __pred
);
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
)
511 typedef typename
std::iterator_traits
<_IIter1
>::value_type _ValueType1
;
512 typedef typename
std::iterator_traits
<_IIter2
>::value_type _ValueType2
;
514 return __set_intersection_switch(
515 __begin1
, __end1
, __begin2
, __end2
, __out
,
516 __gnu_parallel::_Less
<_ValueType1
, _ValueType2
>(),
517 std::__iterator_category(__begin1
),
518 std::__iterator_category(__begin2
),
519 std::__iterator_category(__out
));
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
)
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
));
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
,
543 __gnu_parallel::sequential_tag
)
544 { return _GLIBCXX_STD_A::set_symmetric_difference(
545 __begin1
, __end1
, __begin2
, __end2
, __out
); }
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
,
554 __gnu_parallel::sequential_tag
)
555 { return _GLIBCXX_STD_A::set_symmetric_difference(
556 __begin1
, __end1
, __begin2
, __end2
, __out
, __pred
); }
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
); }
571 // Parallel set_symmetric_difference for random access iterators
572 template<typename _RAIter1
, typename _RAIter2
,
573 typename _Output_RAIter
, typename _Predicate
>
575 __set_symmetric_difference_switch(_RAIter1 __begin1
,
579 _Output_RAIter __result
,
581 random_access_iterator_tag
,
582 random_access_iterator_tag
,
583 random_access_iterator_tag
)
585 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
593 return _GLIBCXX_STD_A::set_symmetric_difference(
594 __begin1
, __end1
, __begin2
, __end2
, __result
, __pred
);
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
)
605 typedef typename
std::iterator_traits
<_IIter1
>::value_type _ValueType1
;
606 typedef typename
std::iterator_traits
<_IIter2
>::value_type _ValueType2
;
608 return __set_symmetric_difference_switch(
609 __begin1
, __end1
, __begin2
, __end2
, __out
,
610 __gnu_parallel::_Less
<_ValueType1
, _ValueType2
>(),
611 std::__iterator_category(__begin1
),
612 std::__iterator_category(__begin2
),
613 std::__iterator_category(__out
));
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
)
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
));
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
); }
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
,
648 __gnu_parallel::sequential_tag
)
649 { return _GLIBCXX_STD_A::set_difference(__begin1
, __end1
,
650 __begin2
, __end2
, __out
, __pred
); }
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
); }
664 // Parallel set_difference for random access iterators
665 template<typename _RAIter1
, typename _RAIter2
,
666 typename _Output_RAIter
, typename _Predicate
>
668 __set_difference_switch(_RAIter1 __begin1
,
672 _Output_RAIter __result
, _Predicate __pred
,
673 random_access_iterator_tag
,
674 random_access_iterator_tag
,
675 random_access_iterator_tag
)
677 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
685 return _GLIBCXX_STD_A::set_difference(
686 __begin1
, __end1
, __begin2
, __end2
, __result
, __pred
);
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
)
697 typedef typename
std::iterator_traits
<_IIter1
>::value_type _ValueType1
;
698 typedef typename
std::iterator_traits
<_IIter2
>::value_type _ValueType2
;
700 return __set_difference_switch(
701 __begin1
, __end1
, __begin2
, __end2
, __out
,
702 __gnu_parallel::_Less
<_ValueType1
, _ValueType2
>(),
703 std::__iterator_category(__begin1
),
704 std::__iterator_category(__begin2
),
705 std::__iterator_category(__out
));
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
)
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
));
723 // Sequential fallback
724 template<typename _FIterator
>
726 adjacent_find(_FIterator __begin
, _FIterator __end
,
727 __gnu_parallel::sequential_tag
)
728 { return _GLIBCXX_STD_A::adjacent_find(__begin
, __end
); }
730 // Sequential fallback
731 template<typename _FIterator
, typename _BinaryPredicate
>
733 adjacent_find(_FIterator __begin
, _FIterator __end
,
734 _BinaryPredicate __binary_pred
,
735 __gnu_parallel::sequential_tag
)
736 { return _GLIBCXX_STD_A::adjacent_find(__begin
, __end
, __binary_pred
); }
738 // Parallel algorithm for random access iterators
739 template<typename _RAIter
>
741 __adjacent_find_switch(_RAIter __begin
, _RAIter __end
,
742 random_access_iterator_tag
)
744 typedef iterator_traits
<_RAIter
> _TraitsType
;
745 typedef typename
_TraitsType::value_type _ValueType
;
747 if (_GLIBCXX_PARALLEL_CONDITION(true))
749 _RAIter __spot
= __gnu_parallel::
751 __begin
, __end
- 1, __begin
, equal_to
<_ValueType
>(),
752 __gnu_parallel::__adjacent_find_selector())
754 if (__spot
== (__end
- 1))
760 return adjacent_find(__begin
, __end
, __gnu_parallel::sequential_tag());
763 // Sequential fallback for input iterator case
764 template<typename _FIterator
, typename _IteratorTag
>
766 __adjacent_find_switch(_FIterator __begin
, _FIterator __end
,
768 { return adjacent_find(__begin
, __end
, __gnu_parallel::sequential_tag()); }
771 template<typename _FIterator
>
773 adjacent_find(_FIterator __begin
, _FIterator __end
)
775 return __adjacent_find_switch(__begin
, __end
,
776 std::__iterator_category(__begin
));
779 // Sequential fallback for input iterator case
780 template<typename _FIterator
, typename _BinaryPredicate
,
781 typename _IteratorTag
>
783 __adjacent_find_switch(_FIterator __begin
, _FIterator __end
,
784 _BinaryPredicate __pred
, _IteratorTag
)
785 { return adjacent_find(__begin
, __end
, __pred
,
786 __gnu_parallel::sequential_tag()); }
788 // Parallel algorithm for random access iterators
789 template<typename _RAIter
, typename _BinaryPredicate
>
791 __adjacent_find_switch(_RAIter __begin
, _RAIter __end
,
792 _BinaryPredicate __pred
, random_access_iterator_tag
)
794 if (_GLIBCXX_PARALLEL_CONDITION(true))
795 return __gnu_parallel::__find_template(__begin
, __end
, __begin
, __pred
,
797 __adjacent_find_selector()).first
;
799 return adjacent_find(__begin
, __end
, __pred
,
800 __gnu_parallel::sequential_tag());
804 template<typename _FIterator
, typename _BinaryPredicate
>
806 adjacent_find(_FIterator __begin
, _FIterator __end
,
807 _BinaryPredicate __pred
)
809 return __adjacent_find_switch(__begin
, __end
, __pred
,
810 std::__iterator_category(__begin
));
813 // Sequential fallback
814 template<typename _IIter
, typename _Tp
>
815 inline typename iterator_traits
<_IIter
>::difference_type
816 count(_IIter __begin
, _IIter __end
, const _Tp
& __value
,
817 __gnu_parallel::sequential_tag
)
818 { return _GLIBCXX_STD_A::count(__begin
, __end
, __value
); }
820 // Parallel code for random access iterators
821 template<typename _RAIter
, typename _Tp
>
822 typename iterator_traits
<_RAIter
>::difference_type
823 __count_switch(_RAIter __begin
, _RAIter __end
,
824 const _Tp
& __value
, random_access_iterator_tag
,
825 __gnu_parallel::_Parallelism __parallelism_tag
)
827 typedef iterator_traits
<_RAIter
> _TraitsType
;
828 typedef typename
_TraitsType::value_type _ValueType
;
829 typedef typename
_TraitsType::difference_type _DifferenceType
;
830 typedef __gnu_parallel::_SequenceIndex _SequenceIndex
;
832 if (_GLIBCXX_PARALLEL_CONDITION(
833 static_cast<_SequenceIndex
>(__end
- __begin
)
834 >= __gnu_parallel::_Settings::get().count_minimal_n
835 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
837 __gnu_parallel::__count_selector
<_RAIter
, _DifferenceType
>
839 _DifferenceType __res
= 0;
841 __for_each_template_random_access(
842 __begin
, __end
, __value
, __functionality
,
843 std::plus
<_SequenceIndex
>(), __res
, __res
, -1,
848 return count(__begin
, __end
, __value
,
849 __gnu_parallel::sequential_tag());
852 // Sequential fallback for input iterator case.
853 template<typename _IIter
, typename _Tp
, typename _IteratorTag
>
854 inline typename iterator_traits
<_IIter
>::difference_type
855 __count_switch(_IIter __begin
, _IIter __end
, const _Tp
& __value
,
857 { return count(__begin
, __end
, __value
, __gnu_parallel::sequential_tag());
861 template<typename _IIter
, typename _Tp
>
862 inline typename iterator_traits
<_IIter
>::difference_type
863 count(_IIter __begin
, _IIter __end
, const _Tp
& __value
,
864 __gnu_parallel::_Parallelism __parallelism_tag
)
866 return __count_switch(__begin
, __end
, __value
,
867 std::__iterator_category(__begin
),
871 template<typename _IIter
, typename _Tp
>
872 inline typename iterator_traits
<_IIter
>::difference_type
873 count(_IIter __begin
, _IIter __end
, const _Tp
& __value
)
875 return __count_switch(__begin
, __end
, __value
,
876 std::__iterator_category(__begin
));
880 // Sequential fallback.
881 template<typename _IIter
, typename _Predicate
>
882 inline typename iterator_traits
<_IIter
>::difference_type
883 count_if(_IIter __begin
, _IIter __end
, _Predicate __pred
,
884 __gnu_parallel::sequential_tag
)
885 { return _GLIBCXX_STD_A::count_if(__begin
, __end
, __pred
); }
887 // Parallel count_if for random access iterators
888 template<typename _RAIter
, typename _Predicate
>
889 typename iterator_traits
<_RAIter
>::difference_type
890 __count_if_switch(_RAIter __begin
, _RAIter __end
,
891 _Predicate __pred
, random_access_iterator_tag
,
892 __gnu_parallel::_Parallelism __parallelism_tag
)
894 typedef iterator_traits
<_RAIter
> _TraitsType
;
895 typedef typename
_TraitsType::value_type _ValueType
;
896 typedef typename
_TraitsType::difference_type _DifferenceType
;
897 typedef __gnu_parallel::_SequenceIndex _SequenceIndex
;
899 if (_GLIBCXX_PARALLEL_CONDITION(
900 static_cast<_SequenceIndex
>(__end
- __begin
)
901 >= __gnu_parallel::_Settings::get().count_minimal_n
902 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
904 _DifferenceType __res
= 0;
906 __count_if_selector
<_RAIter
, _DifferenceType
>
909 __for_each_template_random_access(
910 __begin
, __end
, __pred
, __functionality
,
911 std::plus
<_SequenceIndex
>(), __res
, __res
, -1,
916 return count_if(__begin
, __end
, __pred
,
917 __gnu_parallel::sequential_tag());
920 // Sequential fallback for input iterator case.
921 template<typename _IIter
, typename _Predicate
, typename _IteratorTag
>
922 inline typename iterator_traits
<_IIter
>::difference_type
923 __count_if_switch(_IIter __begin
, _IIter __end
, _Predicate __pred
,
925 { return count_if(__begin
, __end
, __pred
,
926 __gnu_parallel::sequential_tag()); }
929 template<typename _IIter
, typename _Predicate
>
930 inline typename iterator_traits
<_IIter
>::difference_type
931 count_if(_IIter __begin
, _IIter __end
, _Predicate __pred
,
932 __gnu_parallel::_Parallelism __parallelism_tag
)
934 return __count_if_switch(__begin
, __end
, __pred
,
935 std::__iterator_category(__begin
),
939 template<typename _IIter
, typename _Predicate
>
940 inline typename iterator_traits
<_IIter
>::difference_type
941 count_if(_IIter __begin
, _IIter __end
, _Predicate __pred
)
943 return __count_if_switch(__begin
, __end
, __pred
,
944 std::__iterator_category(__begin
));
948 // Sequential fallback.
949 template<typename _FIterator1
, typename _FIterator2
>
951 search(_FIterator1 __begin1
, _FIterator1 __end1
,
952 _FIterator2 __begin2
, _FIterator2 __end2
,
953 __gnu_parallel::sequential_tag
)
954 { return _GLIBCXX_STD_A::search(__begin1
, __end1
, __begin2
, __end2
); }
956 // Parallel algorithm for random access iterator
957 template<typename _RAIter1
, typename _RAIter2
>
959 __search_switch(_RAIter1 __begin1
, _RAIter1 __end1
,
960 _RAIter2 __begin2
, _RAIter2 __end2
,
961 random_access_iterator_tag
, random_access_iterator_tag
)
963 typedef typename
std::iterator_traits
<_RAIter1
>::value_type _ValueType1
;
964 typedef typename
std::iterator_traits
<_RAIter2
>::value_type _ValueType2
;
966 if (_GLIBCXX_PARALLEL_CONDITION(
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
,
972 __gnu_parallel::_EqualTo
<_ValueType1
, _ValueType2
>());
974 return search(__begin1
, __end1
, __begin2
, __end2
,
975 __gnu_parallel::sequential_tag());
978 // Sequential fallback for input iterator case
979 template<typename _FIterator1
, typename _FIterator2
,
980 typename _IteratorTag1
, typename _IteratorTag2
>
982 __search_switch(_FIterator1 __begin1
, _FIterator1 __end1
,
983 _FIterator2 __begin2
, _FIterator2 __end2
,
984 _IteratorTag1
, _IteratorTag2
)
985 { return search(__begin1
, __end1
, __begin2
, __end2
,
986 __gnu_parallel::sequential_tag()); }
989 template<typename _FIterator1
, typename _FIterator2
>
991 search(_FIterator1 __begin1
, _FIterator1 __end1
,
992 _FIterator2 __begin2
, _FIterator2 __end2
)
994 return __search_switch(__begin1
, __end1
, __begin2
, __end2
,
995 std::__iterator_category(__begin1
),
996 std::__iterator_category(__begin2
));
1000 template<typename _FIterator1
, typename _FIterator2
,
1001 typename _BinaryPredicate
>
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
); }
1009 // Parallel algorithm for random access iterator.
1010 template<typename _RAIter1
, typename _RAIter2
,
1011 typename _BinaryPredicate
>
1013 __search_switch(_RAIter1 __begin1
, _RAIter1 __end1
,
1014 _RAIter2 __begin2
, _RAIter2 __end2
,
1015 _BinaryPredicate __pred
,
1016 random_access_iterator_tag
, random_access_iterator_tag
)
1018 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
1024 return search(__begin1
, __end1
, __begin2
, __end2
, __pred
,
1025 __gnu_parallel::sequential_tag());
1028 // Sequential fallback for input iterator case
1029 template<typename _FIterator1
, typename _FIterator2
,
1030 typename _BinaryPredicate
, typename _IteratorTag1
,
1031 typename _IteratorTag2
>
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
,
1037 __gnu_parallel::sequential_tag()); }
1040 template<typename _FIterator1
, typename _FIterator2
,
1041 typename _BinaryPredicate
>
1043 search(_FIterator1 __begin1
, _FIterator1 __end1
,
1044 _FIterator2 __begin2
, _FIterator2 __end2
,
1045 _BinaryPredicate __pred
)
1047 return __search_switch(__begin1
, __end1
, __begin2
, __end2
, __pred
,
1048 std::__iterator_category(__begin1
),
1049 std::__iterator_category(__begin2
));
1052 #if __cplusplus >= 201703L
1053 /** @brief Search a sequence using a Searcher object.
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
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
; }
1067 // Sequential fallback
1068 template<typename _FIterator
, typename _Integer
, typename _Tp
>
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
); }
1074 // Sequential fallback
1075 template<typename _FIterator
, typename _Integer
, typename _Tp
,
1076 typename _BinaryPredicate
>
1078 search_n(_FIterator __begin
, _FIterator __end
, _Integer __count
,
1079 const _Tp
& __val
, _BinaryPredicate __binary_pred
,
1080 __gnu_parallel::sequential_tag
)
1081 { return _GLIBCXX_STD_A::search_n(
1082 __begin
, __end
, __count
, __val
, __binary_pred
); }
1084 // Public interface.
1085 template<typename _FIterator
, typename _Integer
, typename _Tp
>
1087 search_n(_FIterator __begin
, _FIterator __end
, _Integer __count
,
1090 typedef typename iterator_traits
<_FIterator
>::value_type _ValueType
;
1091 return __gnu_parallel::search_n(__begin
, __end
, __count
, __val
,
1092 __gnu_parallel::_EqualTo
<_ValueType
, _Tp
>());
1095 // Parallel algorithm for random access iterators.
1096 template<typename _RAIter
, typename _Integer
,
1097 typename _Tp
, typename _BinaryPredicate
>
1099 __search_n_switch(_RAIter __begin
, _RAIter __end
, _Integer __count
,
1100 const _Tp
& __val
, _BinaryPredicate __binary_pred
,
1101 random_access_iterator_tag
)
1103 if (_GLIBCXX_PARALLEL_CONDITION(
1104 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
1105 >= __gnu_parallel::_Settings::get().search_minimal_n
))
1107 __gnu_parallel::_PseudoSequence
<_Tp
, _Integer
> __ps(__val
, __count
);
1108 return __gnu_parallel::__search_template(
1109 __begin
, __end
, __ps
.begin(), __ps
.end(), __binary_pred
);
1112 return _GLIBCXX_STD_A::search_n(__begin
, __end
, __count
, __val
,
1116 // Sequential fallback for input iterator case.
1117 template<typename _FIterator
, typename _Integer
, typename _Tp
,
1118 typename _BinaryPredicate
, typename _IteratorTag
>
1120 __search_n_switch(_FIterator __begin
, _FIterator __end
, _Integer __count
,
1121 const _Tp
& __val
, _BinaryPredicate __binary_pred
,
1123 { return _GLIBCXX_STD_A::search_n(__begin
, __end
, __count
, __val
,
1126 // Public interface.
1127 template<typename _FIterator
, typename _Integer
, typename _Tp
,
1128 typename _BinaryPredicate
>
1130 search_n(_FIterator __begin
, _FIterator __end
, _Integer __count
,
1131 const _Tp
& __val
, _BinaryPredicate __binary_pred
)
1133 return __search_n_switch(__begin
, __end
, __count
, __val
, __binary_pred
,
1134 std::__iterator_category(__begin
));
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
); }
1146 // Parallel unary transform for random access iterators.
1147 template<typename _RAIter1
, typename _RAIter2
,
1148 typename _UnaryOperation
>
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
)
1155 if (_GLIBCXX_PARALLEL_CONDITION(
1156 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
1157 >= __gnu_parallel::_Settings::get().transform_minimal_n
1158 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
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
));
1165 __gnu_parallel::__transform1_selector
<_ItTrip
> __functionality
;
1167 __for_each_template_random_access(
1168 __begin_pair
, __end_pair
, __unary_op
, __functionality
,
1169 __gnu_parallel::_DummyReduct(),
1170 __dummy
, __dummy
, -1, __parallelism_tag
);
1171 return __functionality
._M_finish_iterator
;
1174 return transform(__begin
, __end
, __result
, __unary_op
,
1175 __gnu_parallel::sequential_tag());
1178 // Sequential fallback for input iterator case.
1179 template<typename _RAIter1
, typename _RAIter2
,
1180 typename _UnaryOperation
, typename _IteratorTag1
,
1181 typename _IteratorTag2
>
1183 __transform1_switch(_RAIter1 __begin
, _RAIter1 __end
,
1184 _RAIter2 __result
, _UnaryOperation __unary_op
,
1185 _IteratorTag1
, _IteratorTag2
)
1186 { return transform(__begin
, __end
, __result
, __unary_op
,
1187 __gnu_parallel::sequential_tag()); }
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
)
1197 return __transform1_switch(__begin
, __end
, __result
, __unary_op
,
1198 std::__iterator_category(__begin
),
1199 std::__iterator_category(__result
),
1203 template<typename _IIter
, typename _OutputIterator
,
1204 typename _UnaryOperation
>
1205 inline _OutputIterator
1206 transform(_IIter __begin
, _IIter __end
, _OutputIterator __result
,
1207 _UnaryOperation __unary_op
)
1209 return __transform1_switch(__begin
, __end
, __result
, __unary_op
,
1210 std::__iterator_category(__begin
),
1211 std::__iterator_category(__result
));
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
); }
1225 // Parallel binary transform for random access iterators.
1226 template<typename _RAIter1
, typename _RAIter2
,
1227 typename _RAIter3
, typename _BinaryOperation
>
1229 __transform2_switch(_RAIter1 __begin1
, _RAIter1 __end1
,
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
)
1236 if (_GLIBCXX_PARALLEL_CONDITION(
1237 (__end1
- __begin1
) >=
1238 __gnu_parallel::_Settings::get().transform_minimal_n
1239 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
1241 bool __dummy
= true;
1242 typedef __gnu_parallel::_IteratorTriple
<_RAIter1
,
1244 random_access_iterator_tag
> _ItTrip
;
1245 _ItTrip
__begin_triple(__begin1
, __begin2
, __result
),
1246 __end_triple(__end1
, __begin2
+ (__end1
- __begin1
),
1247 __result
+ (__end1
- __begin1
));
1248 __gnu_parallel::__transform2_selector
<_ItTrip
> __functionality
;
1250 __for_each_template_random_access(__begin_triple
, __end_triple
,
1251 __binary_op
, __functionality
,
1252 __gnu_parallel::_DummyReduct(),
1253 __dummy
, __dummy
, -1,
1255 return __functionality
._M_finish_iterator
;
1258 return transform(__begin1
, __end1
, __begin2
, __result
, __binary_op
,
1259 __gnu_parallel::sequential_tag());
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
,
1271 __gnu_parallel::sequential_tag()); }
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
)
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
),
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
)
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
));
1304 // Sequential fallback
1305 template<typename _FIterator
, typename _Tp
>
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
); }
1311 // Sequential fallback for input iterator case
1312 template<typename _FIterator
, typename _Tp
, typename _IteratorTag
>
1314 __replace_switch(_FIterator __begin
, _FIterator __end
,
1315 const _Tp
& __old_value
, const _Tp
& __new_value
,
1317 { replace(__begin
, __end
, __old_value
, __new_value
,
1318 __gnu_parallel::sequential_tag()); }
1320 // Parallel replace for random access iterators
1321 template<typename _RAIter
, typename _Tp
>
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
)
1328 // XXX parallel version is where?
1329 replace(__begin
, __end
, __old_value
, __new_value
,
1330 __gnu_parallel::sequential_tag());
1334 template<typename _FIterator
, typename _Tp
>
1336 replace(_FIterator __begin
, _FIterator __end
, const _Tp
& __old_value
,
1337 const _Tp
& __new_value
,
1338 __gnu_parallel::_Parallelism __parallelism_tag
)
1340 __replace_switch(__begin
, __end
, __old_value
, __new_value
,
1341 std::__iterator_category(__begin
),
1345 template<typename _FIterator
, typename _Tp
>
1347 replace(_FIterator __begin
, _FIterator __end
, const _Tp
& __old_value
,
1348 const _Tp
& __new_value
)
1350 __replace_switch(__begin
, __end
, __old_value
, __new_value
,
1351 std::__iterator_category(__begin
));
1355 // Sequential fallback
1356 template<typename _FIterator
, typename _Predicate
, typename _Tp
>
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
); }
1362 // Sequential fallback for input iterator case
1363 template<typename _FIterator
, typename _Predicate
, typename _Tp
,
1364 typename _IteratorTag
>
1366 __replace_if_switch(_FIterator __begin
, _FIterator __end
,
1367 _Predicate __pred
, const _Tp
& __new_value
, _IteratorTag
)
1368 { replace_if(__begin
, __end
, __pred
, __new_value
,
1369 __gnu_parallel::sequential_tag()); }
1371 // Parallel algorithm for random access iterators.
1372 template<typename _RAIter
, typename _Predicate
, typename _Tp
>
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
)
1379 if (_GLIBCXX_PARALLEL_CONDITION(
1380 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
1381 >= __gnu_parallel::_Settings::get().replace_minimal_n
1382 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
1386 __replace_if_selector
<_RAIter
, _Predicate
, _Tp
>
1387 __functionality(__new_value
);
1389 __for_each_template_random_access(
1390 __begin
, __end
, __pred
, __functionality
,
1391 __gnu_parallel::_DummyReduct(),
1392 true, __dummy
, -1, __parallelism_tag
);
1395 replace_if(__begin
, __end
, __pred
, __new_value
,
1396 __gnu_parallel::sequential_tag());
1399 // Public interface.
1400 template<typename _FIterator
, typename _Predicate
, typename _Tp
>
1402 replace_if(_FIterator __begin
, _FIterator __end
,
1403 _Predicate __pred
, const _Tp
& __new_value
,
1404 __gnu_parallel::_Parallelism __parallelism_tag
)
1406 __replace_if_switch(__begin
, __end
, __pred
, __new_value
,
1407 std::__iterator_category(__begin
),
1411 template<typename _FIterator
, typename _Predicate
, typename _Tp
>
1413 replace_if(_FIterator __begin
, _FIterator __end
,
1414 _Predicate __pred
, const _Tp
& __new_value
)
1416 __replace_if_switch(__begin
, __end
, __pred
, __new_value
,
1417 std::__iterator_category(__begin
));
1420 // Sequential fallback
1421 template<typename _FIterator
, typename _Generator
>
1423 generate(_FIterator __begin
, _FIterator __end
, _Generator __gen
,
1424 __gnu_parallel::sequential_tag
)
1425 { _GLIBCXX_STD_A::generate(__begin
, __end
, __gen
); }
1427 // Sequential fallback for input iterator case.
1428 template<typename _FIterator
, typename _Generator
, typename _IteratorTag
>
1430 __generate_switch(_FIterator __begin
, _FIterator __end
, _Generator __gen
,
1432 { generate(__begin
, __end
, __gen
, __gnu_parallel::sequential_tag()); }
1434 // Parallel algorithm for random access iterators.
1435 template<typename _RAIter
, typename _Generator
>
1437 __generate_switch(_RAIter __begin
, _RAIter __end
,
1438 _Generator __gen
, random_access_iterator_tag
,
1439 __gnu_parallel::_Parallelism __parallelism_tag
)
1441 if (_GLIBCXX_PARALLEL_CONDITION(
1442 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
1443 >= __gnu_parallel::_Settings::get().generate_minimal_n
1444 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
1447 __gnu_parallel::__generate_selector
<_RAIter
>
1450 __for_each_template_random_access(
1451 __begin
, __end
, __gen
, __functionality
,
1452 __gnu_parallel::_DummyReduct(),
1453 true, __dummy
, -1, __parallelism_tag
);
1456 generate(__begin
, __end
, __gen
, __gnu_parallel::sequential_tag());
1459 // Public interface.
1460 template<typename _FIterator
, typename _Generator
>
1462 generate(_FIterator __begin
, _FIterator __end
,
1463 _Generator __gen
, __gnu_parallel::_Parallelism __parallelism_tag
)
1465 __generate_switch(__begin
, __end
, __gen
,
1466 std::__iterator_category(__begin
),
1470 template<typename _FIterator
, typename _Generator
>
1472 generate(_FIterator __begin
, _FIterator __end
, _Generator __gen
)
1474 __generate_switch(__begin
, __end
, __gen
,
1475 std::__iterator_category(__begin
));
1479 // Sequential fallback.
1480 template<typename _OutputIterator
, typename _Size
, typename _Generator
>
1481 inline _OutputIterator
1482 generate_n(_OutputIterator __begin
, _Size __n
, _Generator __gen
,
1483 __gnu_parallel::sequential_tag
)
1484 { return _GLIBCXX_STD_A::generate_n(__begin
, __n
, __gen
); }
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
,
1492 { return generate_n(__begin
, __n
, __gen
,
1493 __gnu_parallel::sequential_tag()); }
1495 // Parallel algorithm for random access iterators.
1496 template<typename _RAIter
, typename _Size
, typename _Generator
>
1498 __generate_n_switch(_RAIter __begin
, _Size __n
, _Generator __gen
,
1499 random_access_iterator_tag
,
1500 __gnu_parallel::_Parallelism __parallelism_tag
)
1502 // XXX parallel version is where?
1503 return generate_n(__begin
, __n
, __gen
, __gnu_parallel::sequential_tag());
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
)
1512 return __generate_n_switch(__begin
, __n
, __gen
,
1513 std::__iterator_category(__begin
),
1517 template<typename _OutputIterator
, typename _Size
, typename _Generator
>
1518 inline _OutputIterator
1519 generate_n(_OutputIterator __begin
, _Size __n
, _Generator __gen
)
1521 return __generate_n_switch(__begin
, __n
, __gen
,
1522 std::__iterator_category(__begin
));
1526 // Sequential fallback.
1527 template<typename _RAIter
>
1529 random_shuffle(_RAIter __begin
, _RAIter __end
,
1530 __gnu_parallel::sequential_tag
)
1531 { _GLIBCXX_STD_A::random_shuffle(__begin
, __end
); }
1533 // Sequential fallback.
1534 template<typename _RAIter
, typename _RandomNumberGenerator
>
1536 random_shuffle(_RAIter __begin
, _RAIter __end
,
1537 _RandomNumberGenerator
& __rand
,
1538 __gnu_parallel::sequential_tag
)
1539 { _GLIBCXX_STD_A::random_shuffle(__begin
, __end
, __rand
); }
1542 /** @brief Functor wrapper for std::rand(). */
1543 template<typename _MustBeInt
= int>
1547 operator()(int __limit
)
1548 { return rand() % __limit
; }
1551 // Fill in random number generator.
1552 template<typename _RAIter
>
1554 random_shuffle(_RAIter __begin
, _RAIter __end
)
1557 // Parallelization still possible.
1558 __gnu_parallel::random_shuffle(__begin
, __end
, __r
);
1561 // Parallel algorithm for random access iterators.
1562 template<typename _RAIter
, typename _RandomNumberGenerator
>
1564 random_shuffle(_RAIter __begin
, _RAIter __end
,
1565 #if __cplusplus >= 201103L
1566 _RandomNumberGenerator
&& __rand
)
1568 _RandomNumberGenerator
& __rand
)
1571 if (__begin
== __end
)
1573 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
1578 __gnu_parallel::__sequential_random_shuffle(__begin
, __end
, __rand
);
1581 // Sequential fallback.
1582 template<typename _FIterator
, typename _Predicate
>
1584 partition(_FIterator __begin
, _FIterator __end
,
1585 _Predicate __pred
, __gnu_parallel::sequential_tag
)
1586 { return _GLIBCXX_STD_A::partition(__begin
, __end
, __pred
); }
1588 // Sequential fallback for input iterator case.
1589 template<typename _FIterator
, typename _Predicate
, typename _IteratorTag
>
1591 __partition_switch(_FIterator __begin
, _FIterator __end
,
1592 _Predicate __pred
, _IteratorTag
)
1593 { return partition(__begin
, __end
, __pred
,
1594 __gnu_parallel::sequential_tag()); }
1596 // Parallel algorithm for random access iterators.
1597 template<typename _RAIter
, typename _Predicate
>
1599 __partition_switch(_RAIter __begin
, _RAIter __end
,
1600 _Predicate __pred
, random_access_iterator_tag
)
1602 if (_GLIBCXX_PARALLEL_CONDITION(
1603 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
1604 >= __gnu_parallel::_Settings::get().partition_minimal_n
))
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
;
1614 return partition(__begin
, __end
, __pred
,
1615 __gnu_parallel::sequential_tag());
1618 // Public interface.
1619 template<typename _FIterator
, typename _Predicate
>
1621 partition(_FIterator __begin
, _FIterator __end
, _Predicate __pred
)
1623 return __partition_switch(__begin
, __end
, __pred
,
1624 std::__iterator_category(__begin
));
1629 // Sequential fallback
1630 template<typename _RAIter
>
1632 sort(_RAIter __begin
, _RAIter __end
,
1633 __gnu_parallel::sequential_tag
)
1634 { _GLIBCXX_STD_A::sort(__begin
, __end
); }
1636 // Sequential fallback
1637 template<typename _RAIter
, typename _Compare
>
1639 sort(_RAIter __begin
, _RAIter __end
, _Compare __comp
,
1640 __gnu_parallel::sequential_tag
)
1641 { _GLIBCXX_STD_A::sort
<_RAIter
, _Compare
>(__begin
, __end
,
1645 template<typename _RAIter
, typename _Compare
,
1646 typename _Parallelism
>
1648 sort(_RAIter __begin
, _RAIter __end
, _Compare __comp
,
1649 _Parallelism __parallelism
)
1651 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1653 if (__begin
!= __end
)
1655 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
1661 sort(__begin
, __end
, __comp
, __gnu_parallel::sequential_tag());
1665 // Public interface, insert default comparator
1666 template<typename _RAIter
>
1668 sort(_RAIter __begin
, _RAIter __end
)
1670 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1671 sort(__begin
, __end
, std::less
<_ValueType
>(),
1672 __gnu_parallel::default_parallel_tag());
1675 // Public interface, insert default comparator
1676 template<typename _RAIter
>
1678 sort(_RAIter __begin
, _RAIter __end
,
1679 __gnu_parallel::default_parallel_tag __parallelism
)
1681 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1682 sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1685 // Public interface, insert default comparator
1686 template<typename _RAIter
>
1688 sort(_RAIter __begin
, _RAIter __end
,
1689 __gnu_parallel::parallel_tag __parallelism
)
1691 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1692 sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1695 // Public interface, insert default comparator
1696 template<typename _RAIter
>
1698 sort(_RAIter __begin
, _RAIter __end
,
1699 __gnu_parallel::multiway_mergesort_tag __parallelism
)
1701 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1702 sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1705 // Public interface, insert default comparator
1706 template<typename _RAIter
>
1708 sort(_RAIter __begin
, _RAIter __end
,
1709 __gnu_parallel::multiway_mergesort_sampling_tag __parallelism
)
1711 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1712 sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1715 // Public interface, insert default comparator
1716 template<typename _RAIter
>
1718 sort(_RAIter __begin
, _RAIter __end
,
1719 __gnu_parallel::multiway_mergesort_exact_tag __parallelism
)
1721 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1722 sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1725 // Public interface, insert default comparator
1726 template<typename _RAIter
>
1728 sort(_RAIter __begin
, _RAIter __end
,
1729 __gnu_parallel::quicksort_tag __parallelism
)
1731 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1732 sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1735 // Public interface, insert default comparator
1736 template<typename _RAIter
>
1738 sort(_RAIter __begin
, _RAIter __end
,
1739 __gnu_parallel::balanced_quicksort_tag __parallelism
)
1741 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1742 sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1746 template<typename _RAIter
, typename _Compare
>
1748 sort(_RAIter __begin
, _RAIter __end
, _Compare __comp
)
1750 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1751 sort(__begin
, __end
, __comp
, __gnu_parallel::default_parallel_tag());
1754 // stable_sort interface
1757 // Sequential fallback
1758 template<typename _RAIter
>
1760 stable_sort(_RAIter __begin
, _RAIter __end
,
1761 __gnu_parallel::sequential_tag
)
1762 { _GLIBCXX_STD_A::stable_sort(__begin
, __end
); }
1764 // Sequential fallback
1765 template<typename _RAIter
, typename _Compare
>
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
); }
1772 template<typename _RAIter
, typename _Compare
,
1773 typename _Parallelism
>
1775 stable_sort(_RAIter __begin
, _RAIter __end
,
1776 _Compare __comp
, _Parallelism __parallelism
)
1778 typedef iterator_traits
<_RAIter
> _TraitsType
;
1779 typedef typename
_TraitsType::value_type _ValueType
;
1781 if (__begin
!= __end
)
1783 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
1789 stable_sort(__begin
, __end
, __comp
,
1790 __gnu_parallel::sequential_tag());
1794 // Public interface, insert default comparator
1795 template<typename _RAIter
>
1797 stable_sort(_RAIter __begin
, _RAIter __end
)
1799 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1800 stable_sort(__begin
, __end
, std::less
<_ValueType
>(),
1801 __gnu_parallel::default_parallel_tag());
1804 // Public interface, insert default comparator
1805 template<typename _RAIter
>
1807 stable_sort(_RAIter __begin
, _RAIter __end
,
1808 __gnu_parallel::default_parallel_tag __parallelism
)
1810 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1811 stable_sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1814 // Public interface, insert default comparator
1815 template<typename _RAIter
>
1817 stable_sort(_RAIter __begin
, _RAIter __end
,
1818 __gnu_parallel::parallel_tag __parallelism
)
1820 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1821 stable_sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1824 // Public interface, insert default comparator
1825 template<typename _RAIter
>
1827 stable_sort(_RAIter __begin
, _RAIter __end
,
1828 __gnu_parallel::multiway_mergesort_tag __parallelism
)
1830 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1831 stable_sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1834 // Public interface, insert default comparator
1835 template<typename _RAIter
>
1837 stable_sort(_RAIter __begin
, _RAIter __end
,
1838 __gnu_parallel::quicksort_tag __parallelism
)
1840 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1841 stable_sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1844 // Public interface, insert default comparator
1845 template<typename _RAIter
>
1847 stable_sort(_RAIter __begin
, _RAIter __end
,
1848 __gnu_parallel::balanced_quicksort_tag __parallelism
)
1850 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1851 stable_sort(__begin
, __end
, std::less
<_ValueType
>(), __parallelism
);
1855 template<typename _RAIter
, typename _Compare
>
1857 stable_sort(_RAIter __begin
, _RAIter __end
, _Compare __comp
)
1860 __begin
, __end
, __comp
, __gnu_parallel::default_parallel_tag());
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
,
1869 __gnu_parallel::sequential_tag
)
1870 { return _GLIBCXX_STD_A::merge(
1871 __begin1
, __end1
, __begin2
, __end2
, __result
); }
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
,
1879 __gnu_parallel::sequential_tag
)
1880 { return _GLIBCXX_STD_A::merge(
1881 __begin1
, __end1
, __begin2
, __end2
, __result
, __comp
); }
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
); }
1895 // Parallel algorithm for random access iterators
1896 template<typename _IIter1
, typename _IIter2
,
1897 typename _OutputIterator
, typename _Compare
>
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
)
1905 if (_GLIBCXX_PARALLEL_CONDITION(
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
)))
1910 return __gnu_parallel::__parallel_merge_advance(
1911 __begin1
, __end1
, __begin2
, __end2
, __result
,
1912 (__end1
- __begin1
) + (__end2
- __begin2
), __comp
);
1914 return __gnu_parallel::__merge_advance(
1915 __begin1
, __end1
, __begin2
, __end2
, __result
,
1916 (__end1
- __begin1
) + (__end2
- __begin2
), __comp
);
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
)
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
));
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
)
1940 typedef typename
std::iterator_traits
<_IIter1
>::value_type _ValueType1
;
1941 typedef typename
std::iterator_traits
<_IIter2
>::value_type _ValueType2
;
1943 return __gnu_parallel::merge(__begin1
, __end1
, __begin2
, __end2
,
1944 __result
, __gnu_parallel::_Less
<_ValueType1
, _ValueType2
>());
1947 // Sequential fallback
1948 template<typename _RAIter
>
1950 nth_element(_RAIter __begin
, _RAIter __nth
,
1951 _RAIter __end
, __gnu_parallel::sequential_tag
)
1952 { return _GLIBCXX_STD_A::nth_element(__begin
, __nth
, __end
); }
1954 // Sequential fallback
1955 template<typename _RAIter
, typename _Compare
>
1957 nth_element(_RAIter __begin
, _RAIter __nth
,
1958 _RAIter __end
, _Compare __comp
,
1959 __gnu_parallel::sequential_tag
)
1960 { return _GLIBCXX_STD_A::nth_element(__begin
, __nth
, __end
, __comp
); }
1963 template<typename _RAIter
, typename _Compare
>
1965 nth_element(_RAIter __begin
, _RAIter __nth
,
1966 _RAIter __end
, _Compare __comp
)
1968 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
1973 nth_element(__begin
, __nth
, __end
, __comp
,
1974 __gnu_parallel::sequential_tag());
1977 // Public interface, insert default comparator
1978 template<typename _RAIter
>
1980 nth_element(_RAIter __begin
, _RAIter __nth
,
1983 typedef typename iterator_traits
<_RAIter
>::value_type _ValueType
;
1984 __gnu_parallel::nth_element(__begin
, __nth
, __end
,
1985 std::less
<_ValueType
>());
1988 // Sequential fallback
1989 template<typename _RAIter
, typename _Compare
>
1991 partial_sort(_RAIter __begin
, _RAIter __middle
,
1992 _RAIter __end
, _Compare __comp
,
1993 __gnu_parallel::sequential_tag
)
1994 { _GLIBCXX_STD_A::partial_sort(__begin
, __middle
, __end
, __comp
); }
1996 // Sequential fallback
1997 template<typename _RAIter
>
1999 partial_sort(_RAIter __begin
, _RAIter __middle
,
2000 _RAIter __end
, __gnu_parallel::sequential_tag
)
2001 { _GLIBCXX_STD_A::partial_sort(__begin
, __middle
, __end
); }
2003 // Public interface, parallel algorithm for random access iterators
2004 template<typename _RAIter
, typename _Compare
>
2006 partial_sort(_RAIter __begin
, _RAIter __middle
,
2007 _RAIter __end
, _Compare __comp
)
2009 if (_GLIBCXX_PARALLEL_CONDITION(
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
);
2015 partial_sort(__begin
, __middle
, __end
, __comp
,
2016 __gnu_parallel::sequential_tag());
2019 // Public interface, insert default comparator
2020 template<typename _RAIter
>
2022 partial_sort(_RAIter __begin
, _RAIter __middle
,
2025 typedef iterator_traits
<_RAIter
> _TraitsType
;
2026 typedef typename
_TraitsType::value_type _ValueType
;
2027 __gnu_parallel::partial_sort(__begin
, __middle
, __end
,
2028 std::less
<_ValueType
>());
2031 // Sequential fallback
2032 template<typename _FIterator
>
2034 max_element(_FIterator __begin
, _FIterator __end
,
2035 __gnu_parallel::sequential_tag
)
2036 { return _GLIBCXX_STD_A::max_element(__begin
, __end
); }
2038 // Sequential fallback
2039 template<typename _FIterator
, typename _Compare
>
2041 max_element(_FIterator __begin
, _FIterator __end
, _Compare __comp
,
2042 __gnu_parallel::sequential_tag
)
2043 { return _GLIBCXX_STD_A::max_element(__begin
, __end
, __comp
); }
2045 // Sequential fallback for input iterator case
2046 template<typename _FIterator
, typename _Compare
, typename _IteratorTag
>
2048 __max_element_switch(_FIterator __begin
, _FIterator __end
,
2049 _Compare __comp
, _IteratorTag
)
2050 { return max_element(__begin
, __end
, __comp
,
2051 __gnu_parallel::sequential_tag()); }
2053 // Parallel algorithm for random access iterators
2054 template<typename _RAIter
, typename _Compare
>
2056 __max_element_switch(_RAIter __begin
, _RAIter __end
,
2057 _Compare __comp
, random_access_iterator_tag
,
2058 __gnu_parallel::_Parallelism __parallelism_tag
)
2060 if (_GLIBCXX_PARALLEL_CONDITION(
2061 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
2062 >= __gnu_parallel::_Settings::get().max_element_minimal_n
2063 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
2065 _RAIter
__res(__begin
);
2066 __gnu_parallel::__identity_selector
<_RAIter
>
2069 __for_each_template_random_access(
2070 __begin
, __end
, __gnu_parallel::_Nothing(), __functionality
,
2071 __gnu_parallel::__max_element_reduct
<_Compare
, _RAIter
>(__comp
),
2072 __res
, __res
, -1, __parallelism_tag
);
2076 return max_element(__begin
, __end
, __comp
,
2077 __gnu_parallel::sequential_tag());
2080 // Public interface, insert default comparator
2081 template<typename _FIterator
>
2083 max_element(_FIterator __begin
, _FIterator __end
,
2084 __gnu_parallel::_Parallelism __parallelism_tag
)
2086 typedef typename iterator_traits
<_FIterator
>::value_type _ValueType
;
2087 return max_element(__begin
, __end
, std::less
<_ValueType
>(),
2091 template<typename _FIterator
>
2093 max_element(_FIterator __begin
, _FIterator __end
)
2095 typedef typename iterator_traits
<_FIterator
>::value_type _ValueType
;
2096 return __gnu_parallel::max_element(__begin
, __end
,
2097 std::less
<_ValueType
>());
2101 template<typename _FIterator
, typename _Compare
>
2103 max_element(_FIterator __begin
, _FIterator __end
, _Compare __comp
,
2104 __gnu_parallel::_Parallelism __parallelism_tag
)
2106 return __max_element_switch(__begin
, __end
, __comp
,
2107 std::__iterator_category(__begin
),
2111 template<typename _FIterator
, typename _Compare
>
2113 max_element(_FIterator __begin
, _FIterator __end
, _Compare __comp
)
2115 return __max_element_switch(__begin
, __end
, __comp
,
2116 std::__iterator_category(__begin
));
2120 // Sequential fallback
2121 template<typename _FIterator
>
2123 min_element(_FIterator __begin
, _FIterator __end
,
2124 __gnu_parallel::sequential_tag
)
2125 { return _GLIBCXX_STD_A::min_element(__begin
, __end
); }
2127 // Sequential fallback
2128 template<typename _FIterator
, typename _Compare
>
2130 min_element(_FIterator __begin
, _FIterator __end
, _Compare __comp
,
2131 __gnu_parallel::sequential_tag
)
2132 { return _GLIBCXX_STD_A::min_element(__begin
, __end
, __comp
); }
2134 // Sequential fallback for input iterator case
2135 template<typename _FIterator
, typename _Compare
, typename _IteratorTag
>
2137 __min_element_switch(_FIterator __begin
, _FIterator __end
,
2138 _Compare __comp
, _IteratorTag
)
2139 { return min_element(__begin
, __end
, __comp
,
2140 __gnu_parallel::sequential_tag()); }
2142 // Parallel algorithm for random access iterators
2143 template<typename _RAIter
, typename _Compare
>
2145 __min_element_switch(_RAIter __begin
, _RAIter __end
,
2146 _Compare __comp
, random_access_iterator_tag
,
2147 __gnu_parallel::_Parallelism __parallelism_tag
)
2149 if (_GLIBCXX_PARALLEL_CONDITION(
2150 static_cast<__gnu_parallel::_SequenceIndex
>(__end
- __begin
)
2151 >= __gnu_parallel::_Settings::get().min_element_minimal_n
2152 && __gnu_parallel::__is_parallel(__parallelism_tag
)))
2154 _RAIter
__res(__begin
);
2155 __gnu_parallel::__identity_selector
<_RAIter
>
2158 __for_each_template_random_access(
2159 __begin
, __end
, __gnu_parallel::_Nothing(), __functionality
,
2160 __gnu_parallel::__min_element_reduct
<_Compare
, _RAIter
>(__comp
),
2161 __res
, __res
, -1, __parallelism_tag
);
2165 return min_element(__begin
, __end
, __comp
,
2166 __gnu_parallel::sequential_tag());
2169 // Public interface, insert default comparator
2170 template<typename _FIterator
>
2172 min_element(_FIterator __begin
, _FIterator __end
,
2173 __gnu_parallel::_Parallelism __parallelism_tag
)
2175 typedef typename iterator_traits
<_FIterator
>::value_type _ValueType
;
2176 return min_element(__begin
, __end
, std::less
<_ValueType
>(),
2180 template<typename _FIterator
>
2182 min_element(_FIterator __begin
, _FIterator __end
)
2184 typedef typename iterator_traits
<_FIterator
>::value_type _ValueType
;
2185 return __gnu_parallel::min_element(__begin
, __end
,
2186 std::less
<_ValueType
>());
2190 template<typename _FIterator
, typename _Compare
>
2192 min_element(_FIterator __begin
, _FIterator __end
, _Compare __comp
,
2193 __gnu_parallel::_Parallelism __parallelism_tag
)
2195 return __min_element_switch(__begin
, __end
, __comp
,
2196 std::__iterator_category(__begin
),
2200 template<typename _FIterator
, typename _Compare
>
2202 min_element(_FIterator __begin
, _FIterator __end
, _Compare __comp
)
2204 return __min_element_switch(__begin
, __end
, __comp
,
2205 std::__iterator_category(__begin
));
2208 #if __cplusplus >= 201703L
2209 using _GLIBCXX_STD_A::for_each_n
;
2210 using _GLIBCXX_STD_A::sample
;
2215 #endif /* _GLIBCXX_PARALLEL_ALGO_H */