3 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19 // MA 02111-1307, USA.
21 // As a special exception, you may use this file as part of a free
22 // software library without restriction. Specifically, if other files
23 // instantiate templates or use macros or inline functions from this
24 // file, or you compile this file and link it with other files to
25 // produce an executable, this file does not by itself cause the
26 // resulting executable to be covered by the GNU General Public
27 // License. This exception does not however invalidate any other
28 // reasons why the executable file might be covered by the GNU General
31 /** @file parallel/algo.h
32 * @brief Parallel STL function calls corresponding to the stl_algo.h header.
34 * The functions defined here mainly do case switches and
35 * call the actual parallelized versions in other files.
36 * Inlining policy: Functions that basically only contain one function call,
37 * are declared inline.
38 * This file is a GNU parallel extension to the Standard C++ Library.
41 // Written by Johannes Singler and Felix Putze.
43 #ifndef _GLIBCXX_PARALLEL_ALGO_H
44 #define _GLIBCXX_PARALLEL_ALGO_H 1
46 #include <parallel/algorithmfwd.h>
47 #include <bits/stl_algobase.h>
48 #include <bits/stl_algo.h>
49 #include <parallel/iterator.h>
50 #include <parallel/base.h>
51 #include <parallel/sort.h>
52 #include <parallel/workstealing.h>
53 #include <parallel/par_loop.h>
54 #include <parallel/omp_loop.h>
55 #include <parallel/omp_loop_static.h>
56 #include <parallel/for_each_selectors.h>
57 #include <parallel/for_each.h>
58 #include <parallel/find.h>
59 #include <parallel/find_selectors.h>
60 #include <parallel/search.h>
61 #include <parallel/random_shuffle.h>
62 #include <parallel/partition.h>
63 #include <parallel/merge.h>
64 #include <parallel/unique_copy.h>
65 #include <parallel/set_operations.h>
71 // Sequential fallback
72 template<typename InputIterator
, typename Function
>
74 for_each(InputIterator begin
, InputIterator end
, Function f
,
75 __gnu_parallel::sequential_tag
)
76 { return _GLIBCXX_STD_P::for_each(begin
, end
, f
); }
78 // Sequential fallback for input iterator case
79 template<typename InputIterator
, typename Function
, typename IteratorTag
>
81 for_each_switch(InputIterator begin
, InputIterator end
, Function f
,
83 { return for_each(begin
, end
, f
, __gnu_parallel::sequential_tag()); }
85 // Parallel algorithm for random access iterators
86 template<typename RandomAccessIterator
, typename Function
>
88 for_each_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
89 Function f
, random_access_iterator_tag
,
90 __gnu_parallel::parallelism parallelism_tag
91 = __gnu_parallel::parallel_balanced
)
93 if (_GLIBCXX_PARALLEL_CONDITION(
94 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
95 >= __gnu_parallel::Settings::for_each_minimal_n
96 && __gnu_parallel::is_parallel(parallelism_tag
)))
99 __gnu_parallel::for_each_selector
<RandomAccessIterator
>
102 return __gnu_parallel::
103 for_each_template_random_access(begin
, end
, f
, functionality
,
104 __gnu_parallel::dummy_reduct(),
105 true, dummy
, -1, parallelism_tag
);
108 return for_each(begin
, end
, f
, __gnu_parallel::sequential_tag());
112 template<typename Iterator
, typename Function
>
114 for_each(Iterator begin
, Iterator end
, Function f
,
115 __gnu_parallel::parallelism parallelism_tag
)
117 typedef std::iterator_traits
<Iterator
> iterator_traits
;
118 typedef typename
iterator_traits::iterator_category iterator_category
;
119 return for_each_switch(begin
, end
, f
, iterator_category(),
123 template<typename Iterator
, typename Function
>
125 for_each(Iterator begin
, Iterator end
, Function f
)
127 typedef std::iterator_traits
<Iterator
> iterator_traits
;
128 typedef typename
iterator_traits::iterator_category iterator_category
;
129 return for_each_switch(begin
, end
, f
, iterator_category());
133 // Sequential fallback
134 template<typename InputIterator
, typename T
>
136 find(InputIterator begin
, InputIterator end
, const T
& val
,
137 __gnu_parallel::sequential_tag
)
138 { return _GLIBCXX_STD_P::find(begin
, end
, val
); }
140 // Sequential fallback for input iterator case
141 template<typename InputIterator
, typename T
, typename IteratorTag
>
143 find_switch(InputIterator begin
, InputIterator end
, const T
& val
,
145 { return _GLIBCXX_STD_P::find(begin
, end
, val
); }
147 // Parallel find for random access iterators
148 template<typename RandomAccessIterator
, typename T
>
150 find_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
151 const T
& val
, random_access_iterator_tag
)
153 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
154 typedef typename
traits_type::value_type value_type
;
156 if (_GLIBCXX_PARALLEL_CONDITION(true))
158 binder2nd
<__gnu_parallel::equal_to
<value_type
, T
> >
159 comp(__gnu_parallel::equal_to
<value_type
, T
>(), val
);
160 return __gnu_parallel::find_template(begin
, end
, begin
, comp
,
162 find_if_selector()).first
;
165 return _GLIBCXX_STD_P::find(begin
, end
, val
);
169 template<typename InputIterator
, typename T
>
171 find(InputIterator begin
, InputIterator end
, const T
& val
)
173 typedef std::iterator_traits
<InputIterator
> iterator_traits
;
174 typedef typename
iterator_traits::iterator_category iterator_category
;
175 return find_switch(begin
, end
, val
, iterator_category());
178 // Sequential fallback
179 template<typename InputIterator
, typename Predicate
>
181 find_if(InputIterator begin
, InputIterator end
, Predicate pred
,
182 __gnu_parallel::sequential_tag
)
183 { return _GLIBCXX_STD_P::find_if(begin
, end
, pred
); }
185 // Sequential fallback for input iterator case
186 template<typename InputIterator
, typename Predicate
, typename IteratorTag
>
188 find_if_switch(InputIterator begin
, InputIterator end
, Predicate pred
,
190 { return _GLIBCXX_STD_P::find_if(begin
, end
, pred
); }
192 // Parallel find_if for random access iterators
193 template<typename RandomAccessIterator
, typename Predicate
>
195 find_if_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
196 Predicate pred
, random_access_iterator_tag
)
198 if (_GLIBCXX_PARALLEL_CONDITION(true))
199 return __gnu_parallel::find_template(begin
, end
, begin
, pred
,
201 find_if_selector()).first
;
203 return _GLIBCXX_STD_P::find_if(begin
, end
, pred
);
207 template<typename InputIterator
, typename Predicate
>
209 find_if(InputIterator begin
, InputIterator end
, Predicate pred
)
211 typedef std::iterator_traits
<InputIterator
> iterator_traits
;
212 typedef typename
iterator_traits::iterator_category iterator_category
;
213 return find_if_switch(begin
, end
, pred
, iterator_category());
216 // Sequential fallback
217 template<typename InputIterator
, typename ForwardIterator
>
219 find_first_of(InputIterator begin1
, InputIterator end1
,
220 ForwardIterator begin2
, ForwardIterator end2
,
221 __gnu_parallel::sequential_tag
)
222 { return _GLIBCXX_STD_P::find_first_of(begin1
, end1
, begin2
, end2
); }
224 // Sequential fallback
225 template<typename InputIterator
, typename ForwardIterator
,
226 typename BinaryPredicate
>
228 find_first_of(InputIterator begin1
, InputIterator end1
,
229 ForwardIterator begin2
, ForwardIterator end2
,
230 BinaryPredicate comp
, __gnu_parallel::sequential_tag
)
231 { return _GLIBCXX_STD_P::find_first_of(begin1
, end1
, begin2
, end2
, comp
); }
233 // Sequential fallback for input iterator type
234 template<typename InputIterator
, typename ForwardIterator
,
235 typename IteratorTag1
, typename IteratorTag2
>
237 find_first_of_switch(InputIterator begin1
, InputIterator end1
,
238 ForwardIterator begin2
, ForwardIterator end2
,
239 IteratorTag1
, IteratorTag2
)
240 { return find_first_of(begin1
, end1
, begin2
, end2
,
241 __gnu_parallel::sequential_tag()); }
243 // Parallel algorithm for random access iterators
244 template<typename RandomAccessIterator
, typename ForwardIterator
,
245 typename BinaryPredicate
, typename IteratorTag
>
246 inline RandomAccessIterator
247 find_first_of_switch(RandomAccessIterator begin1
,
248 RandomAccessIterator end1
,
249 ForwardIterator begin2
, ForwardIterator end2
,
250 BinaryPredicate comp
, random_access_iterator_tag
,
253 return __gnu_parallel::
254 find_template(begin1
, end1
, begin1
, comp
,
255 __gnu_parallel::find_first_of_selector
256 <ForwardIterator
>(begin2
, end2
)).first
;
259 // Sequential fallback for input iterator type
260 template<typename InputIterator
, typename ForwardIterator
,
261 typename BinaryPredicate
, typename IteratorTag1
,
262 typename IteratorTag2
>
264 find_first_of_switch(InputIterator begin1
, InputIterator end1
,
265 ForwardIterator begin2
, ForwardIterator end2
,
266 BinaryPredicate comp
, IteratorTag1
, IteratorTag2
)
267 { return find_first_of(begin1
, end1
, begin2
, end2
, comp
,
268 __gnu_parallel::sequential_tag()); }
271 template<typename InputIterator
, typename ForwardIterator
,
272 typename BinaryPredicate
>
274 find_first_of(InputIterator begin1
, InputIterator end1
,
275 ForwardIterator begin2
, ForwardIterator end2
,
276 BinaryPredicate comp
)
278 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
279 typedef std::iterator_traits
<ForwardIterator
> iteratorf_traits
;
280 typedef typename
iteratori_traits::iterator_category iteratori_category
;
281 typedef typename
iteratorf_traits::iterator_category iteratorf_category
;
283 return find_first_of_switch(begin1
, end1
, begin2
, end2
, comp
,
284 iteratori_category(), iteratorf_category());
287 // Public interface, insert default comparator
288 template<typename InputIterator
, typename ForwardIterator
>
290 find_first_of(InputIterator begin1
, InputIterator end1
,
291 ForwardIterator begin2
, ForwardIterator end2
)
293 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
294 typedef std::iterator_traits
<ForwardIterator
> iteratorf_traits
;
295 typedef typename
iteratori_traits::value_type valuei_type
;
296 typedef typename
iteratorf_traits::value_type valuef_type
;
298 return find_first_of(begin1
, end1
, begin2
, end2
, __gnu_parallel::
299 equal_to
<valuei_type
, valuef_type
>());
302 // Sequential fallback
303 template<typename InputIterator
, typename OutputIterator
>
304 inline OutputIterator
305 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
,
306 __gnu_parallel::sequential_tag
)
307 { return _GLIBCXX_STD_P::unique_copy(begin1
, end1
, out
); }
309 // Sequential fallback
310 template<typename InputIterator
, typename OutputIterator
,
312 inline OutputIterator
313 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
,
314 Predicate pred
, __gnu_parallel::sequential_tag
)
315 { return _GLIBCXX_STD_P::unique_copy(begin1
, end1
, out
, pred
); }
317 // Sequential fallback for input iterator case
318 template<typename InputIterator
, typename OutputIterator
,
319 typename Predicate
, typename IteratorTag1
, typename IteratorTag2
>
320 inline OutputIterator
321 unique_copy_switch(InputIterator begin
, InputIterator last
,
322 OutputIterator out
, Predicate pred
,
323 IteratorTag1
, IteratorTag2
)
324 { return _GLIBCXX_STD_P::unique_copy(begin
, last
, out
, pred
); }
326 // Parallel unique_copy for random access iterators
327 template<typename RandomAccessIterator
, typename RandomAccessOutputIterator
,
329 RandomAccessOutputIterator
330 unique_copy_switch(RandomAccessIterator begin
, RandomAccessIterator last
,
331 RandomAccessOutputIterator out
, Predicate pred
,
332 random_access_iterator_tag
, random_access_iterator_tag
)
334 if (_GLIBCXX_PARALLEL_CONDITION(
335 static_cast<__gnu_parallel::sequence_index_t
>(last
- begin
)
336 > __gnu_parallel::Settings::unique_copy_minimal_n
))
337 return __gnu_parallel::parallel_unique_copy(begin
, last
, out
, pred
);
339 return _GLIBCXX_STD_P::unique_copy(begin
, last
, out
, pred
);
343 template<typename InputIterator
, typename OutputIterator
>
344 inline OutputIterator
345 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
)
347 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
348 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
349 typedef typename
iteratori_traits::iterator_category iteratori_category
;
350 typedef typename
iteratori_traits::value_type value_type
;
351 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
353 return unique_copy_switch(begin1
, end1
, out
, equal_to
<value_type
>(),
354 iteratori_category(), iteratoro_category());
358 template<typename InputIterator
, typename OutputIterator
, typename Predicate
>
359 inline OutputIterator
360 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
,
363 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
364 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
365 typedef typename
iteratori_traits::iterator_category iteratori_category
;
366 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
368 return unique_copy_switch(begin1
, end1
, out
, pred
, iteratori_category(),
369 iteratoro_category());
372 // Sequential fallback
373 template<typename InputIterator1
, typename InputIterator2
,
374 typename OutputIterator
>
375 inline OutputIterator
376 set_union(InputIterator1 begin1
, InputIterator1 end1
,
377 InputIterator2 begin2
, InputIterator2 end2
,
378 OutputIterator out
, __gnu_parallel::sequential_tag
)
379 { return _GLIBCXX_STD_P::set_union(begin1
, end1
, begin2
, end2
, out
); }
381 // Sequential fallback
382 template<typename InputIterator1
, typename InputIterator2
,
383 typename OutputIterator
, typename Predicate
>
384 inline OutputIterator
385 set_union(InputIterator1 begin1
, InputIterator1 end1
,
386 InputIterator2 begin2
, InputIterator2 end2
,
387 OutputIterator out
, Predicate pred
,
388 __gnu_parallel::sequential_tag
)
389 { return _GLIBCXX_STD_P::set_union(begin1
, end1
,
390 begin2
, end2
, out
, pred
); }
392 // Sequential fallback for input iterator case
393 template<typename InputIterator1
, typename InputIterator2
,
394 typename Predicate
, typename OutputIterator
,
395 typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
396 inline OutputIterator
397 set_union_switch(InputIterator1 begin1
, InputIterator1 end1
,
398 InputIterator2 begin2
, InputIterator2 end2
,
399 OutputIterator result
, Predicate pred
, IteratorTag1
,
400 IteratorTag2
, IteratorTag3
)
401 { return _GLIBCXX_STD_P::set_union(begin1
, end1
,
402 begin2
, end2
, result
, pred
); }
404 // Parallel set_union for random access iterators
405 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
406 typename OutputRandomAccessIterator
, typename Predicate
>
407 OutputRandomAccessIterator
408 set_union_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
,
409 RandomAccessIterator2 begin2
, RandomAccessIterator2 end2
,
410 OutputRandomAccessIterator result
, Predicate pred
,
411 random_access_iterator_tag
, random_access_iterator_tag
,
412 random_access_iterator_tag
)
414 if (_GLIBCXX_PARALLEL_CONDITION(
415 static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
)
416 >= __gnu_parallel::Settings::set_union_minimal_n
417 || static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
)
418 >= __gnu_parallel::Settings::set_union_minimal_n
))
419 return __gnu_parallel::parallel_set_union(begin1
, end1
,
420 begin2
, end2
, result
, pred
);
422 return _GLIBCXX_STD_P::set_union(begin1
, end1
,
423 begin2
, end2
, result
, pred
);
427 template<typename InputIterator1
, typename InputIterator2
,
428 typename OutputIterator
>
429 inline OutputIterator
430 set_union(InputIterator1 begin1
, InputIterator1 end1
,
431 InputIterator2 begin2
, InputIterator2 end2
, OutputIterator out
)
433 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
434 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
435 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
436 typedef typename
iteratori1_traits::iterator_category
438 typedef typename
iteratori2_traits::iterator_category
440 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
441 typedef typename
iteratori1_traits::value_type value1_type
;
442 typedef typename
iteratori2_traits::value_type value2_type
;
444 return set_union_switch(begin1
, end1
, begin2
, end2
, out
,
445 __gnu_parallel::less
<value1_type
, value2_type
>(),
446 iteratori1_category(), iteratori2_category(),
447 iteratoro_category());
451 template<typename InputIterator1
, typename InputIterator2
,
452 typename OutputIterator
, typename Predicate
>
453 inline OutputIterator
454 set_union(InputIterator1 begin1
, InputIterator1 end1
,
455 InputIterator2 begin2
, InputIterator2 end2
,
456 OutputIterator out
, Predicate pred
)
458 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
459 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
460 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
461 typedef typename
iteratori1_traits::iterator_category
463 typedef typename
iteratori2_traits::iterator_category
465 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
467 return set_union_switch(begin1
, end1
, begin2
, end2
, out
, pred
,
468 iteratori1_category(), iteratori2_category(),
469 iteratoro_category());
472 // Sequential fallback.
473 template<typename InputIterator1
, typename InputIterator2
,
474 typename OutputIterator
>
475 inline OutputIterator
476 set_intersection(InputIterator1 begin1
, InputIterator1 end1
,
477 InputIterator2 begin2
, InputIterator2 end2
,
478 OutputIterator out
, __gnu_parallel::sequential_tag
)
479 { return _GLIBCXX_STD_P::set_intersection(begin1
, end1
,
480 begin2
, end2
, out
); }
482 // Sequential fallback.
483 template<typename InputIterator1
, typename InputIterator2
,
484 typename OutputIterator
, typename Predicate
>
485 inline OutputIterator
486 set_intersection(InputIterator1 begin1
, InputIterator1 end1
,
487 InputIterator2 begin2
, InputIterator2 end2
,
488 OutputIterator out
, Predicate pred
,
489 __gnu_parallel::sequential_tag
)
490 { return _GLIBCXX_STD_P::set_intersection(begin1
, end1
, begin2
, end2
,
493 // Sequential fallback for input iterator case
494 template<typename InputIterator1
, typename InputIterator2
,
495 typename Predicate
, typename OutputIterator
,
496 typename IteratorTag1
, typename IteratorTag2
,
497 typename IteratorTag3
>
498 inline OutputIterator
499 set_intersection_switch(InputIterator1 begin1
, InputIterator1 end1
,
500 InputIterator2 begin2
, InputIterator2 end2
,
501 OutputIterator result
, Predicate pred
,
502 IteratorTag1
, IteratorTag2
, IteratorTag3
)
503 { return _GLIBCXX_STD_P::set_intersection(begin1
, end1
, begin2
,
504 end2
, result
, pred
); }
506 // Parallel set_intersection for random access iterators
507 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
508 typename OutputRandomAccessIterator
, typename Predicate
>
509 OutputRandomAccessIterator
510 set_intersection_switch(RandomAccessIterator1 begin1
,
511 RandomAccessIterator1 end1
,
512 RandomAccessIterator2 begin2
,
513 RandomAccessIterator2 end2
,
514 OutputRandomAccessIterator result
,
516 random_access_iterator_tag
,
517 random_access_iterator_tag
,
518 random_access_iterator_tag
)
520 if (_GLIBCXX_PARALLEL_CONDITION(
521 static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
)
522 >= __gnu_parallel::Settings::set_union_minimal_n
523 || static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
)
524 >= __gnu_parallel::Settings::set_union_minimal_n
))
525 return __gnu_parallel::parallel_set_intersection(begin1
, end1
, begin2
,
528 return _GLIBCXX_STD_P::set_intersection(begin1
, end1
, begin2
,
533 template<typename InputIterator1
, typename InputIterator2
,
534 typename OutputIterator
>
535 inline OutputIterator
536 set_intersection(InputIterator1 begin1
, InputIterator1 end1
,
537 InputIterator2 begin2
, InputIterator2 end2
,
540 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
541 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
542 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
543 typedef typename
iteratori1_traits::iterator_category
545 typedef typename
iteratori2_traits::iterator_category
547 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
548 typedef typename
iteratori1_traits::value_type value1_type
;
549 typedef typename
iteratori2_traits::value_type value2_type
;
551 return set_intersection_switch(begin1
, end1
, begin2
, end2
, out
,
553 less
<value1_type
, value2_type
>(),
554 iteratori1_category(),
555 iteratori2_category(),
556 iteratoro_category());
559 template<typename InputIterator1
, typename InputIterator2
,
560 typename OutputIterator
, typename Predicate
>
561 inline OutputIterator
562 set_intersection(InputIterator1 begin1
, InputIterator1 end1
,
563 InputIterator2 begin2
, InputIterator2 end2
,
564 OutputIterator out
, Predicate pred
)
566 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
567 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
568 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
569 typedef typename
iteratori1_traits::iterator_category
571 typedef typename
iteratori2_traits::iterator_category
573 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
575 return set_intersection_switch(begin1
, end1
, begin2
, end2
, out
, pred
,
576 iteratori1_category(),
577 iteratori2_category(),
578 iteratoro_category());
581 // Sequential fallback
582 template<typename InputIterator1
, typename InputIterator2
,
583 typename OutputIterator
>
584 inline OutputIterator
585 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
,
586 InputIterator2 begin2
, InputIterator2 end2
,
588 __gnu_parallel::sequential_tag
)
589 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1
,end1
,
590 begin2
, end2
, out
); }
592 // Sequential fallback
593 template<typename InputIterator1
, typename InputIterator2
,
594 typename OutputIterator
, typename Predicate
>
595 inline OutputIterator
596 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
,
597 InputIterator2 begin2
, InputIterator2 end2
,
598 OutputIterator out
, Predicate pred
,
599 __gnu_parallel::sequential_tag
)
600 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1
, end1
, begin2
,
603 // Sequential fallback for input iterator case
604 template<typename InputIterator1
, typename InputIterator2
,
605 typename Predicate
, typename OutputIterator
,
606 typename IteratorTag1
, typename IteratorTag2
,
607 typename IteratorTag3
>
608 inline OutputIterator
609 set_symmetric_difference_switch(InputIterator1 begin1
,
611 InputIterator2 begin2
,
613 OutputIterator result
, Predicate pred
,
614 IteratorTag1
, IteratorTag2
, IteratorTag3
)
615 { return _GLIBCXX_STD_P::set_symmetric_difference(begin1
, end1
,
619 // Parallel set_symmetric_difference for random access iterators
620 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
621 typename OutputRandomAccessIterator
, typename Predicate
>
622 OutputRandomAccessIterator
623 set_symmetric_difference_switch(RandomAccessIterator1 begin1
,
624 RandomAccessIterator1 end1
,
625 RandomAccessIterator2 begin2
,
626 RandomAccessIterator2 end2
,
627 OutputRandomAccessIterator result
,
629 random_access_iterator_tag
,
630 random_access_iterator_tag
,
631 random_access_iterator_tag
)
633 if (_GLIBCXX_PARALLEL_CONDITION(
634 static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
)
635 >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n
636 || static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
)
637 >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n
))
638 return __gnu_parallel::parallel_set_symmetric_difference(begin1
, end1
,
642 return _GLIBCXX_STD_P::set_symmetric_difference(begin1
, end1
,
648 template<typename InputIterator1
, typename InputIterator2
,
649 typename OutputIterator
>
650 inline OutputIterator
651 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
,
652 InputIterator2 begin2
, InputIterator2 end2
,
655 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
656 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
657 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
658 typedef typename
iteratori1_traits::iterator_category
660 typedef typename
iteratori2_traits::iterator_category
662 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
663 typedef typename
iteratori1_traits::value_type value1_type
;
664 typedef typename
iteratori2_traits::value_type value2_type
;
666 return set_symmetric_difference_switch(begin1
, end1
, begin2
, end2
, out
,
668 less
<value1_type
, value2_type
>(),
669 iteratori1_category(),
670 iteratori2_category(),
671 iteratoro_category());
675 template<typename InputIterator1
, typename InputIterator2
,
676 typename OutputIterator
, typename Predicate
>
677 inline OutputIterator
678 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
,
679 InputIterator2 begin2
, InputIterator2 end2
,
680 OutputIterator out
, Predicate pred
)
682 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
683 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
684 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
685 typedef typename
iteratori1_traits::iterator_category
687 typedef typename
iteratori2_traits::iterator_category
689 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
691 return set_symmetric_difference_switch(begin1
, end1
, begin2
, end2
, out
,
692 pred
, iteratori1_category(),
693 iteratori2_category(),
694 iteratoro_category());
697 // Sequential fallback.
698 template<typename InputIterator1
, typename InputIterator2
,
699 typename OutputIterator
>
700 inline OutputIterator
701 set_difference(InputIterator1 begin1
, InputIterator1 end1
,
702 InputIterator2 begin2
, InputIterator2 end2
,
703 OutputIterator out
, __gnu_parallel::sequential_tag
)
704 { return _GLIBCXX_STD_P::set_difference(begin1
,end1
, begin2
, end2
, out
); }
706 // Sequential fallback.
707 template<typename InputIterator1
, typename InputIterator2
,
708 typename OutputIterator
, typename Predicate
>
709 inline OutputIterator
710 set_difference(InputIterator1 begin1
, InputIterator1 end1
,
711 InputIterator2 begin2
, InputIterator2 end2
,
712 OutputIterator out
, Predicate pred
,
713 __gnu_parallel::sequential_tag
)
714 { return _GLIBCXX_STD_P::set_difference(begin1
, end1
,
715 begin2
, end2
, out
, pred
); }
717 // Sequential fallback for input iterator case.
718 template<typename InputIterator1
, typename InputIterator2
,
719 typename Predicate
, typename OutputIterator
,
720 typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
721 inline OutputIterator
722 set_difference_switch(InputIterator1 begin1
, InputIterator1 end1
,
723 InputIterator2 begin2
, InputIterator2 end2
,
724 OutputIterator result
, Predicate pred
,
725 IteratorTag1
, IteratorTag2
, IteratorTag3
)
726 { return _GLIBCXX_STD_P::set_difference(begin1
, end1
,
727 begin2
, end2
, result
, pred
); }
729 // Parallel set_difference for random access iterators
730 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
731 typename OutputRandomAccessIterator
, typename Predicate
>
732 OutputRandomAccessIterator
733 set_difference_switch(RandomAccessIterator1 begin1
,
734 RandomAccessIterator1 end1
,
735 RandomAccessIterator2 begin2
,
736 RandomAccessIterator2 end2
,
737 OutputRandomAccessIterator result
, Predicate pred
,
738 random_access_iterator_tag
,
739 random_access_iterator_tag
,
740 random_access_iterator_tag
)
742 if (_GLIBCXX_PARALLEL_CONDITION(
743 static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
)
744 >= __gnu_parallel::Settings::set_difference_minimal_n
745 || static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
)
746 >= __gnu_parallel::Settings::set_difference_minimal_n
))
747 return __gnu_parallel::parallel_set_difference(begin1
, end1
,
751 return _GLIBCXX_STD_P::set_difference(begin1
, end1
,
752 begin2
, end2
, result
, pred
);
756 template<typename InputIterator1
, typename InputIterator2
,
757 typename OutputIterator
>
758 inline OutputIterator
759 set_difference(InputIterator1 begin1
, InputIterator1 end1
,
760 InputIterator2 begin2
, InputIterator2 end2
,
763 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
764 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
765 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
766 typedef typename
iteratori1_traits::iterator_category
768 typedef typename
iteratori2_traits::iterator_category
770 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
771 typedef typename
iteratori1_traits::value_type value1_type
;
772 typedef typename
iteratori2_traits::value_type value2_type
;
774 return set_difference_switch(begin1
, end1
, begin2
, end2
, out
,
776 less
<value1_type
, value2_type
>(),
777 iteratori1_category(),
778 iteratori2_category(),
779 iteratoro_category());
783 template<typename InputIterator1
, typename InputIterator2
,
784 typename OutputIterator
, typename Predicate
>
785 inline OutputIterator
786 set_difference(InputIterator1 begin1
, InputIterator1 end1
,
787 InputIterator2 begin2
, InputIterator2 end2
,
788 OutputIterator out
, Predicate pred
)
790 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
791 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
792 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
793 typedef typename
iteratori1_traits::iterator_category
795 typedef typename
iteratori2_traits::iterator_category
797 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
799 return set_difference_switch(begin1
, end1
, begin2
, end2
, out
, pred
,
800 iteratori1_category(),
801 iteratori2_category(),
802 iteratoro_category());
805 // Sequential fallback
806 template<typename ForwardIterator
>
807 inline ForwardIterator
808 adjacent_find(ForwardIterator begin
, ForwardIterator end
,
809 __gnu_parallel::sequential_tag
)
810 { return _GLIBCXX_STD_P::adjacent_find(begin
, end
); }
812 // Sequential fallback
813 template<typename ForwardIterator
, typename BinaryPredicate
>
814 inline ForwardIterator
815 adjacent_find(ForwardIterator begin
, ForwardIterator end
,
816 BinaryPredicate binary_pred
, __gnu_parallel::sequential_tag
)
817 { return _GLIBCXX_STD_P::adjacent_find(begin
, end
, binary_pred
); }
819 // Parallel algorithm for random access iterators
820 template<typename RandomAccessIterator
>
822 adjacent_find_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
823 random_access_iterator_tag
)
825 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
826 typedef typename
traits_type::value_type value_type
;
828 if (_GLIBCXX_PARALLEL_CONDITION(true))
830 RandomAccessIterator spot
= __gnu_parallel::
831 find_template(begin
, end
- 1, begin
, equal_to
<value_type
>(),
832 __gnu_parallel::adjacent_find_selector()).first
;
833 if (spot
== (end
- 1))
839 return adjacent_find(begin
, end
, __gnu_parallel::sequential_tag());
842 // Sequential fallback for input iterator case
843 template<typename ForwardIterator
, typename IteratorTag
>
844 inline ForwardIterator
845 adjacent_find_switch(ForwardIterator begin
, ForwardIterator end
,
847 { return adjacent_find(begin
, end
, __gnu_parallel::sequential_tag()); }
850 template<typename ForwardIterator
>
851 inline ForwardIterator
852 adjacent_find(ForwardIterator begin
, ForwardIterator end
)
854 typedef iterator_traits
<ForwardIterator
> traits_type
;
855 typedef typename
traits_type::iterator_category iterator_category
;
856 return adjacent_find_switch(begin
, end
, iterator_category());
859 // Sequential fallback for input iterator case
860 template<typename ForwardIterator
, typename BinaryPredicate
,
861 typename IteratorTag
>
862 inline ForwardIterator
863 adjacent_find_switch(ForwardIterator begin
, ForwardIterator end
,
864 BinaryPredicate pred
, IteratorTag
)
865 { return adjacent_find(begin
, end
, pred
,
866 __gnu_parallel::sequential_tag()); }
868 // Parallel algorithm for random access iterators
869 template<typename RandomAccessIterator
, typename BinaryPredicate
>
871 adjacent_find_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
872 BinaryPredicate pred
, random_access_iterator_tag
)
874 if (_GLIBCXX_PARALLEL_CONDITION(true))
875 return __gnu_parallel::find_template(begin
, end
, begin
, pred
,
877 adjacent_find_selector()).first
;
879 return adjacent_find(begin
, end
, pred
,
880 __gnu_parallel::sequential_tag());
884 template<typename ForwardIterator
, typename BinaryPredicate
>
885 inline ForwardIterator
886 adjacent_find(ForwardIterator begin
, ForwardIterator end
,
887 BinaryPredicate pred
)
889 typedef iterator_traits
<ForwardIterator
> traits_type
;
890 typedef typename
traits_type::iterator_category iterator_category
;
891 return adjacent_find_switch(begin
, end
, pred
, iterator_category());
894 // Sequential fallback
895 template<typename InputIterator
, typename T
>
896 inline typename iterator_traits
<InputIterator
>::difference_type
897 count(InputIterator begin
, InputIterator end
, const T
& value
,
898 __gnu_parallel::sequential_tag
)
899 { return _GLIBCXX_STD_P::count(begin
, end
, value
); }
901 // Parallel code for random access iterators
902 template<typename RandomAccessIterator
, typename T
>
903 typename iterator_traits
<RandomAccessIterator
>::difference_type
904 count_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
905 const T
& value
, random_access_iterator_tag
,
906 __gnu_parallel::parallelism parallelism_tag
907 = __gnu_parallel::parallel_unbalanced
)
909 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
910 typedef typename
traits_type::value_type value_type
;
911 typedef typename
traits_type::difference_type difference_type
;
912 typedef __gnu_parallel::sequence_index_t sequence_index_t
;
914 if (_GLIBCXX_PARALLEL_CONDITION(
915 static_cast<sequence_index_t
>(end
- begin
)
916 >= __gnu_parallel::Settings::count_minimal_n
917 && __gnu_parallel::is_parallel(parallelism_tag
)))
919 __gnu_parallel::count_selector
<RandomAccessIterator
, difference_type
>
921 difference_type res
= 0;
923 for_each_template_random_access(begin
, end
, value
,
925 std::plus
<sequence_index_t
>(),
926 res
, res
, -1, parallelism_tag
);
930 return count(begin
, end
, value
, __gnu_parallel::sequential_tag());
933 // Sequential fallback for input iterator case.
934 template<typename InputIterator
, typename T
, typename IteratorTag
>
935 inline typename iterator_traits
<InputIterator
>::difference_type
936 count_switch(InputIterator begin
, InputIterator end
, const T
& value
,
938 { return count(begin
, end
, value
, __gnu_parallel::sequential_tag()); }
941 template<typename InputIterator
, typename T
>
942 inline typename iterator_traits
<InputIterator
>::difference_type
943 count(InputIterator begin
, InputIterator end
, const T
& value
,
944 __gnu_parallel::parallelism parallelism_tag
)
946 typedef iterator_traits
<InputIterator
> traits_type
;
947 typedef typename
traits_type::iterator_category iterator_category
;
948 return count_switch(begin
, end
, value
, iterator_category(),
952 template<typename InputIterator
, typename T
>
953 inline typename iterator_traits
<InputIterator
>::difference_type
954 count(InputIterator begin
, InputIterator end
, const T
& value
)
956 typedef iterator_traits
<InputIterator
> traits_type
;
957 typedef typename
traits_type::iterator_category iterator_category
;
958 return count_switch(begin
, end
, value
, iterator_category());
962 // Sequential fallback.
963 template<typename InputIterator
, typename Predicate
>
964 inline typename iterator_traits
<InputIterator
>::difference_type
965 count_if(InputIterator begin
, InputIterator end
, Predicate pred
,
966 __gnu_parallel::sequential_tag
)
967 { return _GLIBCXX_STD_P::count_if(begin
, end
, pred
); }
969 // Parallel count_if for random access iterators
970 template<typename RandomAccessIterator
, typename Predicate
>
971 typename iterator_traits
<RandomAccessIterator
>::difference_type
972 count_if_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
973 Predicate pred
, random_access_iterator_tag
,
974 __gnu_parallel::parallelism parallelism_tag
975 = __gnu_parallel::parallel_unbalanced
)
977 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
978 typedef typename
traits_type::value_type value_type
;
979 typedef typename
traits_type::difference_type difference_type
;
980 typedef __gnu_parallel::sequence_index_t sequence_index_t
;
982 if (_GLIBCXX_PARALLEL_CONDITION(
983 static_cast<sequence_index_t
>(end
- begin
)
984 >= __gnu_parallel::Settings::count_minimal_n
985 && __gnu_parallel::is_parallel(parallelism_tag
)))
987 difference_type res
= 0;
989 count_if_selector
<RandomAccessIterator
, difference_type
>
992 for_each_template_random_access(begin
, end
, pred
,
994 std::plus
<sequence_index_t
>(),
995 res
, res
, -1, parallelism_tag
);
999 return count_if(begin
, end
, pred
, __gnu_parallel::sequential_tag());
1002 // Sequential fallback for input iterator case.
1003 template<typename InputIterator
, typename Predicate
, typename IteratorTag
>
1004 inline typename iterator_traits
<InputIterator
>::difference_type
1005 count_if_switch(InputIterator begin
, InputIterator end
, Predicate pred
,
1007 { return count_if(begin
, end
, pred
, __gnu_parallel::sequential_tag()); }
1009 // Public interface.
1010 template<typename InputIterator
, typename Predicate
>
1011 inline typename iterator_traits
<InputIterator
>::difference_type
1012 count_if(InputIterator begin
, InputIterator end
, Predicate pred
,
1013 __gnu_parallel::parallelism parallelism_tag
)
1015 typedef iterator_traits
<InputIterator
> traits_type
;
1016 typedef typename
traits_type::iterator_category iterator_category
;
1017 return count_if_switch(begin
, end
, pred
, iterator_category(),
1021 template<typename InputIterator
, typename Predicate
>
1022 inline typename iterator_traits
<InputIterator
>::difference_type
1023 count_if(InputIterator begin
, InputIterator end
, Predicate pred
)
1025 typedef iterator_traits
<InputIterator
> traits_type
;
1026 typedef typename
traits_type::iterator_category iterator_category
;
1027 return count_if_switch(begin
, end
, pred
, iterator_category());
1031 // Sequential fallback.
1032 template<typename ForwardIterator1
, typename ForwardIterator2
>
1033 inline ForwardIterator1
1034 search(ForwardIterator1 begin1
, ForwardIterator1 end1
,
1035 ForwardIterator2 begin2
, ForwardIterator2 end2
,
1036 __gnu_parallel::sequential_tag
)
1037 { return _GLIBCXX_STD_P::search(begin1
, end1
, begin2
, end2
); }
1039 // Parallel algorithm for random access iterator
1040 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
>
1041 RandomAccessIterator1
1042 search_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
,
1043 RandomAccessIterator2 begin2
, RandomAccessIterator2 end2
,
1044 random_access_iterator_tag
, random_access_iterator_tag
)
1046 typedef std::iterator_traits
<RandomAccessIterator1
> iterator1_traits
;
1047 typedef typename
iterator1_traits::value_type value1_type
;
1048 typedef std::iterator_traits
<RandomAccessIterator2
> iterator2_traits
;
1049 typedef typename
iterator2_traits::value_type value2_type
;
1051 if (_GLIBCXX_PARALLEL_CONDITION(true))
1052 return __gnu_parallel::
1053 search_template(begin1
, end1
, begin2
, end2
, __gnu_parallel::
1054 equal_to
<value1_type
, value2_type
>());
1056 return search(begin1
, end1
, begin2
, end2
,
1057 __gnu_parallel::sequential_tag());
1060 // Sequential fallback for input iterator case
1061 template<typename ForwardIterator1
, typename ForwardIterator2
,
1062 typename IteratorTag1
, typename IteratorTag2
>
1063 inline ForwardIterator1
1064 search_switch(ForwardIterator1 begin1
, ForwardIterator1 end1
,
1065 ForwardIterator2 begin2
, ForwardIterator2 end2
,
1066 IteratorTag1
, IteratorTag2
)
1067 { return search(begin1
, end1
, begin2
, end2
,
1068 __gnu_parallel::sequential_tag()); }
1070 // Public interface.
1071 template<typename ForwardIterator1
, typename ForwardIterator2
>
1072 inline ForwardIterator1
1073 search(ForwardIterator1 begin1
, ForwardIterator1 end1
,
1074 ForwardIterator2 begin2
, ForwardIterator2 end2
)
1076 typedef std::iterator_traits
<ForwardIterator1
> iterator1_traits
;
1077 typedef typename
iterator1_traits::iterator_category iterator1_category
;
1078 typedef std::iterator_traits
<ForwardIterator2
> iterator2_traits
;
1079 typedef typename
iterator2_traits::iterator_category iterator2_category
;
1081 return search_switch(begin1
, end1
, begin2
, end2
,
1082 iterator1_category(), iterator2_category());
1085 // Public interface.
1086 template<typename ForwardIterator1
, typename ForwardIterator2
,
1087 typename BinaryPredicate
>
1088 inline ForwardIterator1
1089 search(ForwardIterator1 begin1
, ForwardIterator1 end1
,
1090 ForwardIterator2 begin2
, ForwardIterator2 end2
,
1091 BinaryPredicate pred
, __gnu_parallel::sequential_tag
)
1092 { return _GLIBCXX_STD_P::search(begin1
, end1
, begin2
, end2
, pred
); }
1094 // Parallel algorithm for random access iterator.
1095 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
1096 typename BinaryPredicate
>
1097 RandomAccessIterator1
1098 search_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
,
1099 RandomAccessIterator2 begin2
, RandomAccessIterator2 end2
,
1100 BinaryPredicate pred
,
1101 random_access_iterator_tag
, random_access_iterator_tag
)
1103 if (_GLIBCXX_PARALLEL_CONDITION(true))
1104 return __gnu_parallel::search_template(begin1
, end1
,
1105 begin2
, end2
, pred
);
1107 return search(begin1
, end1
, begin2
, end2
, pred
,
1108 __gnu_parallel::sequential_tag());
1111 // Sequential fallback for input iterator case
1112 template<typename ForwardIterator1
, typename ForwardIterator2
,
1113 typename BinaryPredicate
, typename IteratorTag1
,
1114 typename IteratorTag2
>
1115 inline ForwardIterator1
1116 search_switch(ForwardIterator1 begin1
, ForwardIterator1 end1
,
1117 ForwardIterator2 begin2
, ForwardIterator2 end2
,
1118 BinaryPredicate pred
, IteratorTag1
, IteratorTag2
)
1119 { return search(begin1
, end1
, begin2
, end2
, pred
,
1120 __gnu_parallel::sequential_tag()); }
1123 template<typename ForwardIterator1
, typename ForwardIterator2
,
1124 typename BinaryPredicate
>
1125 inline ForwardIterator1
1126 search(ForwardIterator1 begin1
, ForwardIterator1 end1
,
1127 ForwardIterator2 begin2
, ForwardIterator2 end2
,
1128 BinaryPredicate pred
)
1130 typedef std::iterator_traits
<ForwardIterator1
> iterator1_traits
;
1131 typedef typename
iterator1_traits::iterator_category iterator1_category
;
1132 typedef std::iterator_traits
<ForwardIterator2
> iterator2_traits
;
1133 typedef typename
iterator2_traits::iterator_category iterator2_category
;
1134 return search_switch(begin1
, end1
, begin2
, end2
, pred
,
1135 iterator1_category(), iterator2_category());
1138 // Sequential fallback
1139 template<typename ForwardIterator
, typename Integer
, typename T
>
1140 inline ForwardIterator
1141 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
,
1142 const T
& val
, __gnu_parallel::sequential_tag
)
1143 { return _GLIBCXX_STD_P::search_n(begin
, end
, count
, val
); }
1145 // Sequential fallback
1146 template<typename ForwardIterator
, typename Integer
, typename T
,
1147 typename BinaryPredicate
>
1148 inline ForwardIterator
1149 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
,
1150 const T
& val
, BinaryPredicate binary_pred
,
1151 __gnu_parallel::sequential_tag
)
1152 { return _GLIBCXX_STD_P::search_n(begin
, end
, count
, val
, binary_pred
); }
1154 // Public interface.
1155 template<typename ForwardIterator
, typename Integer
, typename T
>
1156 inline ForwardIterator
1157 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
,
1160 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
1161 return search_n(begin
, end
, count
, val
,
1162 __gnu_parallel::equal_to
<value_type
, T
>());
1165 // Parallel algorithm for random access iterators.
1166 template<typename RandomAccessIterator
, typename Integer
,
1167 typename T
, typename BinaryPredicate
>
1168 RandomAccessIterator
1169 search_n_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
1170 Integer count
, const T
& val
, BinaryPredicate binary_pred
,
1171 random_access_iterator_tag
)
1173 if (_GLIBCXX_PARALLEL_CONDITION(true))
1175 __gnu_parallel::pseudo_sequence
<T
, Integer
> ps(val
, count
);
1176 return __gnu_parallel::search_template(begin
, end
, ps
.begin(),
1177 ps
.end(), binary_pred
);
1180 return std::__search_n(begin
, end
, count
, val
,
1181 binary_pred
, random_access_iterator_tag());
1184 // Sequential fallback for input iterator case.
1185 template<typename ForwardIterator
, typename Integer
, typename T
,
1186 typename BinaryPredicate
, typename IteratorTag
>
1187 inline ForwardIterator
1188 search_n_switch(ForwardIterator begin
, ForwardIterator end
, Integer count
,
1189 const T
& val
, BinaryPredicate binary_pred
, IteratorTag
)
1190 { return __search_n(begin
, end
, count
, val
, binary_pred
, IteratorTag()); }
1192 // Public interface.
1193 template<typename ForwardIterator
, typename Integer
, typename T
,
1194 typename BinaryPredicate
>
1195 inline ForwardIterator
1196 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
,
1197 const T
& val
, BinaryPredicate binary_pred
)
1199 return search_n_switch(begin
, end
, count
, val
, binary_pred
,
1200 typename
std::iterator_traits
<ForwardIterator
>::
1201 iterator_category());
1205 // Sequential fallback.
1206 template<typename InputIterator
, typename OutputIterator
,
1207 typename UnaryOperation
>
1208 inline OutputIterator
1209 transform(InputIterator begin
, InputIterator end
, OutputIterator result
,
1210 UnaryOperation unary_op
, __gnu_parallel::sequential_tag
)
1211 { return _GLIBCXX_STD_P::transform(begin
, end
, result
, unary_op
); }
1213 // Parallel unary transform for random access iterators.
1214 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
1215 typename UnaryOperation
>
1216 RandomAccessIterator2
1217 transform1_switch(RandomAccessIterator1 begin
, RandomAccessIterator1 end
,
1218 RandomAccessIterator2 result
, UnaryOperation unary_op
,
1219 random_access_iterator_tag
, random_access_iterator_tag
,
1220 __gnu_parallel::parallelism parallelism_tag
1221 = __gnu_parallel::parallel_balanced
)
1223 if (_GLIBCXX_PARALLEL_CONDITION(
1224 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1225 >= __gnu_parallel::Settings::transform_minimal_n
1226 && __gnu_parallel::is_parallel(parallelism_tag
)))
1229 typedef __gnu_parallel::iterator_pair
<RandomAccessIterator1
,
1230 RandomAccessIterator2
, random_access_iterator_tag
> ip
;
1231 ip
begin_pair(begin
, result
), end_pair(end
, result
+ (end
- begin
));
1232 __gnu_parallel::transform1_selector
<ip
> functionality
;
1234 for_each_template_random_access(begin_pair
, end_pair
,
1235 unary_op
, functionality
,
1236 __gnu_parallel::dummy_reduct(),
1237 dummy
, dummy
, -1, parallelism_tag
);
1238 return functionality
.finish_iterator
;
1241 return transform(begin
, end
, result
, unary_op
,
1242 __gnu_parallel::sequential_tag());
1245 // Sequential fallback for input iterator case.
1246 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
1247 typename UnaryOperation
, typename IteratorTag1
,
1248 typename IteratorTag2
>
1249 inline RandomAccessIterator2
1250 transform1_switch(RandomAccessIterator1 begin
, RandomAccessIterator1 end
,
1251 RandomAccessIterator2 result
, UnaryOperation unary_op
,
1252 IteratorTag1
, IteratorTag2
)
1253 { return transform(begin
, end
, result
, unary_op
,
1254 __gnu_parallel::sequential_tag()); }
1256 // Public interface.
1257 template<typename InputIterator
, typename OutputIterator
,
1258 typename UnaryOperation
>
1259 inline OutputIterator
1260 transform(InputIterator begin
, InputIterator end
, OutputIterator result
,
1261 UnaryOperation unary_op
,
1262 __gnu_parallel::parallelism parallelism_tag
)
1264 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
1265 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1266 typedef typename
iteratori_traits::iterator_category iteratori_category
;
1267 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1269 return transform1_switch(begin
, end
, result
, unary_op
,
1270 iteratori_category(), iteratoro_category(),
1274 template<typename InputIterator
, typename OutputIterator
,
1275 typename UnaryOperation
>
1276 inline OutputIterator
1277 transform(InputIterator begin
, InputIterator end
, OutputIterator result
,
1278 UnaryOperation unary_op
)
1280 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
1281 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1282 typedef typename
iteratori_traits::iterator_category iteratori_category
;
1283 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1285 return transform1_switch(begin
, end
, result
, unary_op
,
1286 iteratori_category(), iteratoro_category());
1290 // Sequential fallback
1291 template<typename InputIterator1
, typename InputIterator2
,
1292 typename OutputIterator
, typename BinaryOperation
>
1293 inline OutputIterator
1294 transform(InputIterator1 begin1
, InputIterator1 end1
,
1295 InputIterator2 begin2
, OutputIterator result
,
1296 BinaryOperation binary_op
, __gnu_parallel::sequential_tag
)
1297 { return _GLIBCXX_STD_P::transform(begin1
, end1
,
1298 begin2
, result
, binary_op
); }
1300 // Parallel binary transform for random access iterators.
1301 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
1302 typename RandomAccessIterator3
, typename BinaryOperation
>
1303 RandomAccessIterator3
1304 transform2_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
,
1305 RandomAccessIterator2 begin2
,
1306 RandomAccessIterator3 result
, BinaryOperation binary_op
,
1307 random_access_iterator_tag
, random_access_iterator_tag
,
1308 random_access_iterator_tag
,
1309 __gnu_parallel::parallelism parallelism_tag
1310 = __gnu_parallel::parallel_balanced
)
1312 if (_GLIBCXX_PARALLEL_CONDITION(
1313 (end1
- begin1
) >= __gnu_parallel::Settings::transform_minimal_n
1314 && __gnu_parallel::is_parallel(parallelism_tag
)))
1317 typedef __gnu_parallel::iterator_triple
<RandomAccessIterator1
,
1318 RandomAccessIterator2
, RandomAccessIterator3
,
1319 random_access_iterator_tag
> ip
;
1320 ip
begin_triple(begin1
, begin2
, result
),
1321 end_triple(end1
, begin2
+ (end1
- begin1
),
1322 result
+ (end1
- begin1
));
1323 __gnu_parallel::transform2_selector
<ip
> functionality
;
1325 for_each_template_random_access(begin_triple
, end_triple
,
1326 binary_op
, functionality
,
1327 __gnu_parallel::dummy_reduct(),
1330 return functionality
.finish_iterator
;
1333 return transform(begin1
, end1
, begin2
, result
, binary_op
,
1334 __gnu_parallel::sequential_tag());
1337 // Sequential fallback for input iterator case.
1338 template<typename InputIterator1
, typename InputIterator2
,
1339 typename OutputIterator
, typename BinaryOperation
,
1340 typename tag1
, typename tag2
, typename tag3
>
1341 inline OutputIterator
1342 transform2_switch(InputIterator1 begin1
, InputIterator1 end1
,
1343 InputIterator2 begin2
, OutputIterator result
,
1344 BinaryOperation binary_op
, tag1
, tag2
, tag3
)
1345 { return transform(begin1
, end1
, begin2
, result
, binary_op
,
1346 __gnu_parallel::sequential_tag()); }
1348 // Public interface.
1349 template<typename InputIterator1
, typename InputIterator2
,
1350 typename OutputIterator
, typename BinaryOperation
>
1351 inline OutputIterator
1352 transform(InputIterator1 begin1
, InputIterator1 end1
,
1353 InputIterator2 begin2
, OutputIterator result
,
1354 BinaryOperation binary_op
,
1355 __gnu_parallel::parallelism parallelism_tag
)
1357 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
1358 typedef typename
iteratori1_traits::iterator_category
1359 iteratori1_category
;
1360 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
1361 typedef typename
iteratori2_traits::iterator_category
1362 iteratori2_category
;
1363 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1364 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1366 return transform2_switch(begin1
, end1
, begin2
, result
, binary_op
,
1367 iteratori1_category(), iteratori2_category(),
1368 iteratoro_category(), parallelism_tag
);
1371 template<typename InputIterator1
, typename InputIterator2
,
1372 typename OutputIterator
, typename BinaryOperation
>
1373 inline OutputIterator
1374 transform(InputIterator1 begin1
, InputIterator1 end1
,
1375 InputIterator2 begin2
, OutputIterator result
,
1376 BinaryOperation binary_op
)
1378 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
1379 typedef typename
iteratori1_traits::iterator_category
1380 iteratori1_category
;
1381 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
1382 typedef typename
iteratori2_traits::iterator_category
1383 iteratori2_category
;
1384 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1385 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1387 return transform2_switch(begin1
, end1
, begin2
, result
, binary_op
,
1388 iteratori1_category(), iteratori2_category(),
1389 iteratoro_category());
1392 // Sequential fallback
1393 template<typename ForwardIterator
, typename T
>
1395 replace(ForwardIterator begin
, ForwardIterator end
, const T
& old_value
,
1396 const T
& new_value
, __gnu_parallel::sequential_tag
)
1397 { _GLIBCXX_STD_P::replace(begin
, end
, old_value
, new_value
); }
1399 // Sequential fallback for input iterator case
1400 template<typename ForwardIterator
, typename T
, typename IteratorTag
>
1402 replace_switch(ForwardIterator begin
, ForwardIterator end
,
1403 const T
& old_value
, const T
& new_value
, IteratorTag
)
1404 { replace(begin
, end
, old_value
, new_value
,
1405 __gnu_parallel::sequential_tag()); }
1407 // Parallel replace for random access iterators
1408 template<typename RandomAccessIterator
, typename T
>
1410 replace_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
1411 const T
& old_value
, const T
& new_value
,
1412 random_access_iterator_tag
,
1413 __gnu_parallel::parallelism parallelism_tag
1414 = __gnu_parallel::parallel_balanced
)
1416 // XXX parallel version is where?
1417 replace(begin
, end
, old_value
, new_value
,
1418 __gnu_parallel::sequential_tag());
1422 template<typename ForwardIterator
, typename T
>
1424 replace(ForwardIterator begin
, ForwardIterator end
, const T
& old_value
,
1425 const T
& new_value
, __gnu_parallel::parallelism parallelism_tag
)
1427 typedef iterator_traits
<ForwardIterator
> traits_type
;
1428 typedef typename
traits_type::iterator_category iterator_category
;
1429 replace_switch(begin
, end
, old_value
, new_value
, iterator_category(),
1433 template<typename ForwardIterator
, typename T
>
1435 replace(ForwardIterator begin
, ForwardIterator end
, const T
& old_value
,
1438 typedef iterator_traits
<ForwardIterator
> traits_type
;
1439 typedef typename
traits_type::iterator_category iterator_category
;
1440 replace_switch(begin
, end
, old_value
, new_value
, iterator_category());
1444 // Sequential fallback
1445 template<typename ForwardIterator
, typename Predicate
, typename T
>
1447 replace_if(ForwardIterator begin
, ForwardIterator end
, Predicate pred
,
1448 const T
& new_value
, __gnu_parallel::sequential_tag
)
1449 { _GLIBCXX_STD_P::replace_if(begin
, end
, pred
, new_value
); }
1451 // Sequential fallback for input iterator case
1452 template<typename ForwardIterator
, typename Predicate
, typename T
,
1453 typename IteratorTag
>
1455 replace_if_switch(ForwardIterator begin
, ForwardIterator end
,
1456 Predicate pred
, const T
& new_value
, IteratorTag
)
1457 { replace_if(begin
, end
, pred
, new_value
,
1458 __gnu_parallel::sequential_tag()); }
1460 // Parallel algorithm for random access iterators.
1461 template<typename RandomAccessIterator
, typename Predicate
, typename T
>
1463 replace_if_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
1464 Predicate pred
, const T
& new_value
,
1465 random_access_iterator_tag
,
1466 __gnu_parallel::parallelism parallelism_tag
1467 = __gnu_parallel::parallel_balanced
)
1469 if (_GLIBCXX_PARALLEL_CONDITION(
1470 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1471 >= __gnu_parallel::Settings::replace_minimal_n
1472 && __gnu_parallel::is_parallel(parallelism_tag
)))
1476 replace_if_selector
<RandomAccessIterator
, Predicate
, T
>
1477 functionality(new_value
);
1479 for_each_template_random_access(begin
, end
, pred
,
1481 __gnu_parallel::dummy_reduct(),
1482 true, dummy
, -1, parallelism_tag
);
1485 replace_if(begin
, end
, pred
, new_value
,
1486 __gnu_parallel::sequential_tag());
1489 // Public interface.
1490 template<typename ForwardIterator
, typename Predicate
, typename T
>
1492 replace_if(ForwardIterator begin
, ForwardIterator end
,
1493 Predicate pred
, const T
& new_value
,
1494 __gnu_parallel::parallelism parallelism_tag
)
1496 typedef std::iterator_traits
<ForwardIterator
> iterator_traits
;
1497 typedef typename
iterator_traits::iterator_category iterator_category
;
1498 replace_if_switch(begin
, end
, pred
, new_value
, iterator_category(),
1502 template<typename ForwardIterator
, typename Predicate
, typename T
>
1504 replace_if(ForwardIterator begin
, ForwardIterator end
,
1505 Predicate pred
, const T
& new_value
)
1507 typedef std::iterator_traits
<ForwardIterator
> iterator_traits
;
1508 typedef typename
iterator_traits::iterator_category iterator_category
;
1509 replace_if_switch(begin
, end
, pred
, new_value
, iterator_category());
1512 // Sequential fallback
1513 template<typename ForwardIterator
, typename Generator
>
1515 generate(ForwardIterator begin
, ForwardIterator end
, Generator gen
,
1516 __gnu_parallel::sequential_tag
)
1517 { _GLIBCXX_STD_P::generate(begin
, end
, gen
); }
1519 // Sequential fallback for input iterator case.
1520 template<typename ForwardIterator
, typename Generator
, typename IteratorTag
>
1522 generate_switch(ForwardIterator begin
, ForwardIterator end
, Generator gen
,
1524 { generate(begin
, end
, gen
, __gnu_parallel::sequential_tag()); }
1526 // Parallel algorithm for random access iterators.
1527 template<typename RandomAccessIterator
, typename Generator
>
1529 generate_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
1530 Generator gen
, random_access_iterator_tag
,
1531 __gnu_parallel::parallelism parallelism_tag
1532 = __gnu_parallel::parallel_balanced
)
1534 if (_GLIBCXX_PARALLEL_CONDITION(
1535 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1536 >= __gnu_parallel::Settings::generate_minimal_n
1537 && __gnu_parallel::is_parallel(parallelism_tag
)))
1540 __gnu_parallel::generate_selector
<RandomAccessIterator
>
1543 for_each_template_random_access(begin
, end
, gen
, functionality
,
1544 __gnu_parallel::dummy_reduct(),
1545 true, dummy
, -1, parallelism_tag
);
1548 generate(begin
, end
, gen
, __gnu_parallel::sequential_tag());
1551 // Public interface.
1552 template<typename ForwardIterator
, typename Generator
>
1554 generate(ForwardIterator begin
, ForwardIterator end
,
1555 Generator gen
, __gnu_parallel::parallelism parallelism_tag
)
1557 typedef std::iterator_traits
<ForwardIterator
> iterator_traits
;
1558 typedef typename
iterator_traits::iterator_category iterator_category
;
1559 generate_switch(begin
, end
, gen
, iterator_category(), parallelism_tag
);
1562 template<typename ForwardIterator
, typename Generator
>
1564 generate(ForwardIterator begin
, ForwardIterator end
, Generator gen
)
1566 typedef std::iterator_traits
<ForwardIterator
> iterator_traits
;
1567 typedef typename
iterator_traits::iterator_category iterator_category
;
1568 generate_switch(begin
, end
, gen
, iterator_category());
1572 // Sequential fallback.
1573 template<typename OutputIterator
, typename Size
, typename Generator
>
1574 inline OutputIterator
1575 generate_n(OutputIterator begin
, Size n
, Generator gen
,
1576 __gnu_parallel::sequential_tag
)
1577 { return _GLIBCXX_STD_P::generate_n(begin
, n
, gen
); }
1579 // Sequential fallback for input iterator case.
1580 template<typename OutputIterator
, typename Size
, typename Generator
,
1581 typename IteratorTag
>
1582 inline OutputIterator
1583 generate_n_switch(OutputIterator begin
, Size n
, Generator gen
, IteratorTag
)
1584 { return generate_n(begin
, n
, gen
, __gnu_parallel::sequential_tag()); }
1586 // Parallel algorithm for random access iterators.
1587 template<typename RandomAccessIterator
, typename Size
, typename Generator
>
1588 inline RandomAccessIterator
1589 generate_n_switch(RandomAccessIterator begin
, Size n
, Generator gen
,
1590 random_access_iterator_tag
,
1591 __gnu_parallel::parallelism parallelism_tag
1592 = __gnu_parallel::parallel_balanced
)
1594 // XXX parallel version is where?
1595 return generate_n(begin
, n
, gen
, __gnu_parallel::sequential_tag());
1598 // Public interface.
1599 template<typename OutputIterator
, typename Size
, typename Generator
>
1600 inline OutputIterator
1601 generate_n(OutputIterator begin
, Size n
, Generator gen
,
1602 __gnu_parallel::parallelism parallelism_tag
)
1604 typedef std::iterator_traits
<OutputIterator
> iterator_traits
;
1605 typedef typename
iterator_traits::iterator_category iterator_category
;
1606 return generate_n_switch(begin
, n
, gen
, iterator_category(),
1610 template<typename OutputIterator
, typename Size
, typename Generator
>
1611 inline OutputIterator
1612 generate_n(OutputIterator begin
, Size n
, Generator gen
)
1614 typedef std::iterator_traits
<OutputIterator
> iterator_traits
;
1615 typedef typename
iterator_traits::iterator_category iterator_category
;
1616 return generate_n_switch(begin
, n
, gen
, iterator_category());
1620 // Sequential fallback.
1621 template<typename RandomAccessIterator
>
1623 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
,
1624 __gnu_parallel::sequential_tag
)
1625 { _GLIBCXX_STD_P::random_shuffle(begin
, end
); }
1627 // Sequential fallback.
1628 template<typename RandomAccessIterator
, typename RandomNumberGenerator
>
1630 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
,
1631 RandomNumberGenerator
& rand
, __gnu_parallel::sequential_tag
)
1632 { _GLIBCXX_STD_P::random_shuffle(begin
, end
, rand
); }
1635 /** @brief Functor wrapper for std::rand(). */
1636 template<typename must_be_int
= int>
1637 struct c_rand_number
1640 operator()(int limit
)
1641 { return rand() % limit
; }
1644 // Fill in random number generator.
1645 template<typename RandomAccessIterator
>
1647 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
)
1650 // Parallelization still possible.
1651 random_shuffle(begin
, end
, r
);
1654 // Parallel algorithm for random access iterators.
1655 template<typename RandomAccessIterator
, typename RandomNumberGenerator
>
1657 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
,
1658 RandomNumberGenerator
& rand
)
1662 if (_GLIBCXX_PARALLEL_CONDITION(
1663 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1664 >= __gnu_parallel::Settings::random_shuffle_minimal_n
))
1665 __gnu_parallel::parallel_random_shuffle(begin
, end
, rand
);
1667 __gnu_parallel::sequential_random_shuffle(begin
, end
, rand
);
1670 // Sequential fallback.
1671 template<typename ForwardIterator
, typename Predicate
>
1672 inline ForwardIterator
1673 partition(ForwardIterator begin
, ForwardIterator end
,
1674 Predicate pred
, __gnu_parallel::sequential_tag
)
1675 { return _GLIBCXX_STD_P::partition(begin
, end
, pred
); }
1677 // Sequential fallback for input iterator case.
1678 template<typename ForwardIterator
, typename Predicate
, typename IteratorTag
>
1679 inline ForwardIterator
1680 partition_switch(ForwardIterator begin
, ForwardIterator end
,
1681 Predicate pred
, IteratorTag
)
1682 { return partition(begin
, end
, pred
, __gnu_parallel::sequential_tag()); }
1684 // Parallel algorithm for random access iterators.
1685 template<typename RandomAccessIterator
, typename Predicate
>
1686 RandomAccessIterator
1687 partition_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
1688 Predicate pred
, random_access_iterator_tag
)
1690 if (_GLIBCXX_PARALLEL_CONDITION(
1691 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1692 >= __gnu_parallel::Settings::partition_minimal_n
))
1694 typedef typename
std::iterator_traits
<RandomAccessIterator
>::
1695 difference_type difference_type
;
1696 difference_type middle
= __gnu_parallel::
1697 parallel_partition(begin
, end
, pred
,
1698 __gnu_parallel::get_max_threads());
1699 return begin
+ middle
;
1702 return partition(begin
, end
, pred
, __gnu_parallel::sequential_tag());
1705 // Public interface.
1706 template<typename ForwardIterator
, typename Predicate
>
1707 inline ForwardIterator
1708 partition(ForwardIterator begin
, ForwardIterator end
, Predicate pred
)
1710 typedef iterator_traits
<ForwardIterator
> traits_type
;
1711 typedef typename
traits_type::iterator_category iterator_category
;
1712 return partition_switch(begin
, end
, pred
, iterator_category());
1715 // Sequential fallback
1716 template<typename RandomAccessIterator
>
1718 sort(RandomAccessIterator begin
, RandomAccessIterator end
,
1719 __gnu_parallel::sequential_tag
)
1720 { _GLIBCXX_STD_P::sort(begin
, end
); }
1722 // Sequential fallback
1723 template<typename RandomAccessIterator
, typename Comparator
>
1725 sort(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
,
1726 __gnu_parallel::sequential_tag
)
1727 { _GLIBCXX_STD_P::sort
<RandomAccessIterator
, Comparator
>(begin
, end
,
1730 // Public interface, insert default comparator
1731 template<typename RandomAccessIterator
>
1733 sort(RandomAccessIterator begin
, RandomAccessIterator end
)
1735 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1736 typedef typename
traits_type::value_type value_type
;
1737 sort(begin
, end
, std::less
<value_type
>());
1740 template<typename RandomAccessIterator
, typename Comparator
>
1742 sort(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
)
1744 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1745 typedef typename
traits_type::value_type value_type
;
1749 if (_GLIBCXX_PARALLEL_CONDITION(
1750 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1751 >= __gnu_parallel::Settings::sort_minimal_n
))
1752 __gnu_parallel::parallel_sort(begin
, end
, comp
, false);
1754 sort(begin
, end
, comp
, __gnu_parallel::sequential_tag());
1758 // Sequential fallback.
1759 template<typename RandomAccessIterator
>
1761 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
,
1762 __gnu_parallel::sequential_tag
)
1763 { return _GLIBCXX_STD_P::stable_sort(begin
, end
); }
1765 // Sequential fallback.
1766 template<typename RandomAccessIterator
, typename Comparator
>
1768 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
,
1769 Comparator comp
, __gnu_parallel::sequential_tag
)
1770 { return _GLIBCXX_STD_P::stable_sort(begin
, end
, comp
); }
1772 template<typename RandomAccessIterator
>
1774 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
)
1776 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1777 typedef typename
traits_type::value_type value_type
;
1778 stable_sort(begin
, end
, std::less
<value_type
>());
1781 // Parallel algorithm for random access iterators
1782 template<typename RandomAccessIterator
, typename Comparator
>
1784 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
,
1789 if (_GLIBCXX_PARALLEL_CONDITION(
1790 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1791 >= __gnu_parallel::Settings::sort_minimal_n
))
1792 __gnu_parallel::parallel_sort(begin
, end
, comp
, true);
1794 stable_sort(begin
, end
, comp
, __gnu_parallel::sequential_tag());
1798 // Sequential fallback
1799 template<typename InputIterator1
, typename InputIterator2
,
1800 typename OutputIterator
>
1801 inline OutputIterator
1802 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
1803 InputIterator2 end2
, OutputIterator result
,
1804 __gnu_parallel::sequential_tag
)
1805 { return _GLIBCXX_STD_P::merge(begin1
, end1
, begin2
, end2
, result
); }
1807 // Sequential fallback
1808 template<typename InputIterator1
, typename InputIterator2
,
1809 typename OutputIterator
, typename Comparator
>
1810 inline OutputIterator
1811 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
1812 InputIterator2 end2
, OutputIterator result
, Comparator comp
,
1813 __gnu_parallel::sequential_tag
)
1814 { return _GLIBCXX_STD_P::merge(begin1
, end1
, begin2
, end2
, result
, comp
); }
1816 // Sequential fallback for input iterator case
1817 template<typename InputIterator1
, typename InputIterator2
,
1818 typename OutputIterator
, typename Comparator
,
1819 typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
1820 inline OutputIterator
1821 merge_switch(InputIterator1 begin1
, InputIterator1 end1
,
1822 InputIterator2 begin2
, InputIterator2 end2
,
1823 OutputIterator result
, Comparator comp
,
1824 IteratorTag1
, IteratorTag2
, IteratorTag3
)
1825 { return _GLIBCXX_STD_P::merge(begin1
, end1
, begin2
, end2
,
1828 // Parallel algorithm for random access iterators
1829 template<typename InputIterator1
, typename InputIterator2
,
1830 typename OutputIterator
, typename Comparator
>
1832 merge_switch(InputIterator1 begin1
, InputIterator1 end1
,
1833 InputIterator2 begin2
, InputIterator2 end2
,
1834 OutputIterator result
, Comparator comp
,
1835 random_access_iterator_tag
, random_access_iterator_tag
,
1836 random_access_iterator_tag
)
1838 if (_GLIBCXX_PARALLEL_CONDITION(
1839 (static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
)
1840 >= __gnu_parallel::Settings::merge_minimal_n
1841 || static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
)
1842 >= __gnu_parallel::Settings::merge_minimal_n
)))
1843 return __gnu_parallel::parallel_merge_advance(begin1
, end1
,
1845 result
, (end1
- begin1
)
1846 + (end2
- begin2
), comp
);
1848 return __gnu_parallel::merge_advance(begin1
, end1
, begin2
, end2
,
1849 result
, (end1
- begin1
)
1850 + (end2
- begin2
), comp
);
1854 template<typename InputIterator1
, typename InputIterator2
,
1855 typename OutputIterator
, typename Comparator
>
1856 inline OutputIterator
1857 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
1858 InputIterator2 end2
, OutputIterator result
, Comparator comp
)
1860 typedef typename iterator_traits
<InputIterator1
>::value_type value_type
;
1862 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
1863 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
1864 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1865 typedef typename
iteratori1_traits::iterator_category
1866 iteratori1_category
;
1867 typedef typename
iteratori2_traits::iterator_category
1868 iteratori2_category
;
1869 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1871 return merge_switch(begin1
, end1
, begin2
, end2
, result
, comp
,
1872 iteratori1_category(), iteratori2_category(),
1873 iteratoro_category());
1877 // Public interface, insert default comparator
1878 template<typename InputIterator1
, typename InputIterator2
,
1879 typename OutputIterator
>
1880 inline OutputIterator
1881 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
1882 InputIterator2 end2
, OutputIterator result
)
1884 typedef std::iterator_traits
<InputIterator1
> iterator1_traits
;
1885 typedef std::iterator_traits
<InputIterator2
> iterator2_traits
;
1886 typedef typename
iterator1_traits::value_type value1_type
;
1887 typedef typename
iterator2_traits::value_type value2_type
;
1889 return merge(begin1
, end1
, begin2
, end2
, result
,
1890 __gnu_parallel::less
<value1_type
, value2_type
>());
1893 // Sequential fallback
1894 template<typename RandomAccessIterator
>
1896 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
,
1897 RandomAccessIterator end
, __gnu_parallel::sequential_tag
)
1898 { return _GLIBCXX_STD_P::nth_element(begin
, nth
, end
); }
1900 // Sequential fallback
1901 template<typename RandomAccessIterator
, typename Comparator
>
1903 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
,
1904 RandomAccessIterator end
, Comparator comp
,
1905 __gnu_parallel::sequential_tag
)
1906 { return _GLIBCXX_STD_P::nth_element(begin
, nth
, end
, comp
); }
1909 template<typename RandomAccessIterator
, typename Comparator
>
1911 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
,
1912 RandomAccessIterator end
, Comparator comp
)
1914 if (_GLIBCXX_PARALLEL_CONDITION(
1915 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1916 >= __gnu_parallel::Settings::nth_element_minimal_n
))
1917 __gnu_parallel::parallel_nth_element(begin
, nth
, end
, comp
);
1919 nth_element(begin
, nth
, end
, comp
, __gnu_parallel::sequential_tag());
1922 // Public interface, insert default comparator
1923 template<typename RandomAccessIterator
>
1925 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
,
1926 RandomAccessIterator end
)
1928 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1929 typedef typename
traits_type::value_type value_type
;
1930 nth_element(begin
, nth
, end
, std::less
<value_type
>());
1933 // Sequential fallback
1934 template<typename RandomAccessIterator
, typename _Compare
>
1936 partial_sort(RandomAccessIterator begin
, RandomAccessIterator middle
,
1937 RandomAccessIterator end
, _Compare comp
,
1938 __gnu_parallel::sequential_tag
)
1939 { _GLIBCXX_STD_P::partial_sort(begin
, middle
, end
, comp
); }
1941 // Sequential fallback
1942 template<typename RandomAccessIterator
>
1944 partial_sort(RandomAccessIterator begin
, RandomAccessIterator middle
,
1945 RandomAccessIterator end
, __gnu_parallel::sequential_tag
)
1946 { _GLIBCXX_STD_P::partial_sort(begin
, middle
, end
); }
1948 // Public interface, parallel algorithm for random access iterators
1949 template<typename RandomAccessIterator
, typename _Compare
>
1951 partial_sort(RandomAccessIterator begin
, RandomAccessIterator middle
,
1952 RandomAccessIterator end
, _Compare comp
)
1954 if (_GLIBCXX_PARALLEL_CONDITION(
1955 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
1956 >= __gnu_parallel::Settings::partial_sort_minimal_n
))
1957 __gnu_parallel::parallel_partial_sort(begin
, middle
, end
, comp
);
1959 partial_sort(begin
, middle
, end
, comp
,
1960 __gnu_parallel::sequential_tag());
1963 // Public interface, insert default comparator
1964 template<typename RandomAccessIterator
>
1966 partial_sort(RandomAccessIterator begin
, RandomAccessIterator middle
,
1967 RandomAccessIterator end
)
1969 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1970 typedef typename
traits_type::value_type value_type
;
1971 partial_sort(begin
, middle
, end
, std::less
<value_type
>());
1974 // Sequential fallback
1975 template<typename ForwardIterator
>
1976 inline ForwardIterator
1977 max_element(ForwardIterator begin
, ForwardIterator end
,
1978 __gnu_parallel::sequential_tag
)
1979 { return _GLIBCXX_STD_P::max_element(begin
, end
); }
1981 // Sequential fallback
1982 template<typename ForwardIterator
, typename Comparator
>
1983 inline ForwardIterator
1984 max_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
,
1985 __gnu_parallel::sequential_tag
)
1986 { return _GLIBCXX_STD_P::max_element(begin
, end
, comp
); }
1988 // Sequential fallback for input iterator case
1989 template<typename ForwardIterator
, typename Comparator
, typename IteratorTag
>
1990 inline ForwardIterator
1991 max_element_switch(ForwardIterator begin
, ForwardIterator end
,
1992 Comparator comp
, IteratorTag
)
1993 { return max_element(begin
, end
, comp
, __gnu_parallel::sequential_tag()); }
1995 // Parallel algorithm for random access iterators
1996 template<typename RandomAccessIterator
, typename Comparator
>
1997 RandomAccessIterator
1998 max_element_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
1999 Comparator comp
, random_access_iterator_tag
,
2000 __gnu_parallel::parallelism parallelism_tag
2001 = __gnu_parallel::parallel_balanced
)
2003 if (_GLIBCXX_PARALLEL_CONDITION(
2004 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
2005 >= __gnu_parallel::Settings::max_element_minimal_n
2006 && __gnu_parallel::is_parallel(parallelism_tag
)))
2008 RandomAccessIterator
res(begin
);
2009 __gnu_parallel::identity_selector
<RandomAccessIterator
>
2012 for_each_template_random_access(begin
, end
,
2013 __gnu_parallel::nothing(),
2016 max_element_reduct
<Comparator
,
2017 RandomAccessIterator
>(comp
),
2018 res
, res
, -1, parallelism_tag
);
2022 return max_element(begin
, end
, comp
, __gnu_parallel::sequential_tag());
2025 // Public interface, insert default comparator
2026 template<typename ForwardIterator
>
2027 inline ForwardIterator
2028 max_element(ForwardIterator begin
, ForwardIterator end
,
2029 __gnu_parallel::parallelism parallelism_tag
)
2031 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
2032 return max_element(begin
, end
, std::less
<value_type
>(), parallelism_tag
);
2035 template<typename ForwardIterator
>
2036 inline ForwardIterator
2037 max_element(ForwardIterator begin
, ForwardIterator end
)
2039 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
2040 return max_element(begin
, end
, std::less
<value_type
>());
2044 template<typename ForwardIterator
, typename Comparator
>
2045 inline ForwardIterator
2046 max_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
,
2047 __gnu_parallel::parallelism parallelism_tag
)
2049 typedef iterator_traits
<ForwardIterator
> traits_type
;
2050 typedef typename
traits_type::iterator_category iterator_category
;
2051 return max_element_switch(begin
, end
, comp
, iterator_category(),
2055 template<typename ForwardIterator
, typename Comparator
>
2056 inline ForwardIterator
2057 max_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
)
2059 typedef iterator_traits
<ForwardIterator
> traits_type
;
2060 typedef typename
traits_type::iterator_category iterator_category
;
2061 return max_element_switch(begin
, end
, comp
, iterator_category());
2065 // Sequential fallback
2066 template<typename ForwardIterator
>
2067 inline ForwardIterator
2068 min_element(ForwardIterator begin
, ForwardIterator end
,
2069 __gnu_parallel::sequential_tag
)
2070 { return _GLIBCXX_STD_P::min_element(begin
, end
); }
2072 // Sequential fallback
2073 template<typename ForwardIterator
, typename Comparator
>
2074 inline ForwardIterator
2075 min_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
,
2076 __gnu_parallel::sequential_tag
)
2077 { return _GLIBCXX_STD_P::min_element(begin
, end
, comp
); }
2079 // Sequential fallback for input iterator case
2080 template<typename ForwardIterator
, typename Comparator
, typename IteratorTag
>
2081 inline ForwardIterator
2082 min_element_switch(ForwardIterator begin
, ForwardIterator end
,
2083 Comparator comp
, IteratorTag
)
2084 { return min_element(begin
, end
, comp
, __gnu_parallel::sequential_tag()); }
2086 // Parallel algorithm for random access iterators
2087 template<typename RandomAccessIterator
, typename Comparator
>
2088 RandomAccessIterator
2089 min_element_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
2090 Comparator comp
, random_access_iterator_tag
,
2091 __gnu_parallel::parallelism parallelism_tag
2092 = __gnu_parallel::parallel_balanced
)
2094 if (_GLIBCXX_PARALLEL_CONDITION(
2095 static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
)
2096 >= __gnu_parallel::Settings::min_element_minimal_n
2097 && __gnu_parallel::is_parallel(parallelism_tag
)))
2099 RandomAccessIterator
res(begin
);
2100 __gnu_parallel::identity_selector
<RandomAccessIterator
>
2103 for_each_template_random_access(begin
, end
,
2104 __gnu_parallel::nothing(),
2107 min_element_reduct
<Comparator
,
2108 RandomAccessIterator
>(comp
),
2109 res
, res
, -1, parallelism_tag
);
2113 return min_element(begin
, end
, comp
, __gnu_parallel::sequential_tag());
2116 // Public interface, insert default comparator
2117 template<typename ForwardIterator
>
2118 inline ForwardIterator
2119 min_element(ForwardIterator begin
, ForwardIterator end
,
2120 __gnu_parallel::parallelism parallelism_tag
)
2122 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
2123 return min_element(begin
, end
, std::less
<value_type
>(), parallelism_tag
);
2126 template<typename ForwardIterator
>
2127 inline ForwardIterator
2128 min_element(ForwardIterator begin
, ForwardIterator end
)
2130 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
2131 return min_element(begin
, end
, std::less
<value_type
>());
2135 template<typename ForwardIterator
, typename Comparator
>
2136 inline ForwardIterator
2137 min_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
,
2138 __gnu_parallel::parallelism parallelism_tag
)
2140 typedef iterator_traits
<ForwardIterator
> traits_type
;
2141 typedef typename
traits_type::iterator_category iterator_category
;
2142 return min_element_switch(begin
, end
, comp
, iterator_category(),
2146 template<typename ForwardIterator
, typename Comparator
>
2147 inline ForwardIterator
2148 min_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
)
2150 typedef iterator_traits
<ForwardIterator
> traits_type
;
2151 typedef typename
traits_type::iterator_category iterator_category
;
2152 return min_element_switch(begin
, end
, comp
, iterator_category());
2157 #endif /* _GLIBCXX_ALGORITHM_H */