libstdc++

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