3 // Copyright (C) 2007 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
, __gnu_parallel::sequential_tag
)
76 return _GLIBCXX_STD_P::for_each
<InputIterator
, Function
>(begin
, end
, f
);
79 // Sequential fallback for input iterator case
80 template<typename InputIterator
, typename Function
, typename IteratorTag
>
82 for_each_switch(InputIterator begin
, InputIterator end
, Function f
, IteratorTag
, __gnu_parallel::parallelism parallelism_tag
)
84 return for_each
<InputIterator
, Function
>(begin
, end
, f
, __gnu_parallel::sequential_tag());
87 // Parallel algorithm for random access iterators
88 template<typename RandomAccessIterator
, typename Function
>
90 for_each_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Function f
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
92 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::for_each_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
95 __gnu_parallel::for_each_selector
<RandomAccessIterator
> functionality
;
96 return __gnu_parallel::for_each_template_random_access(begin
, end
, f
, functionality
, __gnu_parallel::dummy_reduct(), true, dummy
, -1, parallelism_tag
);
99 return for_each
<RandomAccessIterator
, Function
>(begin
, end
, f
, __gnu_parallel::sequential_tag());
103 template<typename Iterator
, typename Function
>
105 for_each(Iterator begin
, Iterator end
, Function f
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
107 typedef std::iterator_traits
<Iterator
> iterator_traits
;
108 typedef typename
iterator_traits::iterator_category iterator_category
;
110 return for_each_switch(begin
, end
, f
, iterator_category(), parallelism_tag
);
114 // Sequential fallback
115 template<typename InputIterator
, typename T
>
117 find(InputIterator begin
, InputIterator end
, const T
& val
, __gnu_parallel::sequential_tag
)
118 { return _GLIBCXX_STD_P::find
<InputIterator
, T
>(begin
, end
, val
); }
120 // Sequential fallback for input iterator case
121 template<typename InputIterator
, typename T
, typename IteratorTag
>
123 find_switch(InputIterator begin
, InputIterator end
, const T
& val
, IteratorTag
)
124 { return _GLIBCXX_STD_P::find(begin
, end
, val
); }
126 // Parallel find for random access iterators
127 template<typename RandomAccessIterator
, typename T
>
129 find_switch(RandomAccessIterator begin
, RandomAccessIterator end
, const T
& val
, random_access_iterator_tag
)
131 typedef typename iterator_traits
<RandomAccessIterator
>::value_type value_type
;
133 if (_GLIBCXX_PARALLEL_CONDITION(true))
135 binder2nd
<__gnu_parallel::equal_to
<value_type
, T
> > comp(__gnu_parallel::equal_to
<value_type
, T
>(), val
);
136 return __gnu_parallel::find_template(begin
, end
, begin
, comp
, __gnu_parallel::find_if_selector()).first
;
139 return _GLIBCXX_STD_P::find(begin
, end
, val
);
143 template<typename InputIterator
, typename T
>
145 find(InputIterator begin
, InputIterator end
, const T
& val
)
147 typedef std::iterator_traits
<InputIterator
> iterator_traits
;
148 typedef typename
iterator_traits::iterator_category iterator_category
;
149 return find_switch(begin
, end
, val
, iterator_category());
152 // Sequential fallback
153 template<typename InputIterator
, typename Predicate
>
155 find_if(InputIterator begin
, InputIterator end
, Predicate pred
, __gnu_parallel::sequential_tag
)
157 return _GLIBCXX_STD_P::find_if
<InputIterator
, Predicate
>(begin
, end
, pred
);
160 // Sequential fallback for input iterator case
161 template<typename InputIterator
, typename Predicate
, typename IteratorTag
>
163 find_if_switch(InputIterator begin
, InputIterator end
, Predicate pred
, IteratorTag
)
165 return _GLIBCXX_STD_P::find_if(begin
, end
, pred
);
168 // Parallel find_if for random access iterators
169 template<typename RandomAccessIterator
, typename Predicate
>
171 find_if_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Predicate pred
, random_access_iterator_tag
)
173 if (_GLIBCXX_PARALLEL_CONDITION(true))
174 return __gnu_parallel::find_template(begin
, end
, begin
, pred
, __gnu_parallel::find_if_selector()).first
;
176 return _GLIBCXX_STD_P::find_if(begin
, end
, pred
);
180 template<typename InputIterator
, typename Predicate
>
182 find_if (InputIterator begin
, InputIterator end
, Predicate pred
)
184 typedef std::iterator_traits
<InputIterator
> iterator_traits
;
185 typedef typename
iterator_traits::iterator_category iterator_category
;
186 return find_if_switch(begin
, end
, pred
, iterator_category());
189 // Sequential fallback
190 template<typename InputIterator
, typename ForwardIterator
>
192 find_first_of(InputIterator begin1
, InputIterator end1
, ForwardIterator begin2
, ForwardIterator end2
, __gnu_parallel::sequential_tag
)
194 return _GLIBCXX_STD_P::find_first_of(begin1
, end1
, begin2
, end2
);
197 // Sequential fallback
198 template<typename InputIterator
, typename ForwardIterator
,
199 typename BinaryPredicate
>
201 find_first_of(InputIterator begin1
, InputIterator end1
,
202 ForwardIterator begin2
, ForwardIterator end2
,
203 BinaryPredicate comp
, __gnu_parallel::sequential_tag
)
205 return _GLIBCXX_STD_P::find_first_of(begin1
, end1
, begin2
, end2
, comp
);
208 // Sequential fallback for input iterator type
209 template<typename InputIterator
, typename ForwardIterator
, typename IteratorTag1
, typename IteratorTag2
>
211 find_first_of_switch(InputIterator begin1
, InputIterator end1
,
212 ForwardIterator begin2
, ForwardIterator end2
, IteratorTag1
, IteratorTag2
)
214 return find_first_of(begin1
, end1
, begin2
, end2
, __gnu_parallel::sequential_tag());
217 // Parallel algorithm for random access iterators
218 template<typename RandomAccessIterator
, typename ForwardIterator
, typename BinaryPredicate
, typename IteratorTag
>
219 inline RandomAccessIterator
220 find_first_of_switch(RandomAccessIterator begin1
, RandomAccessIterator end1
,
221 ForwardIterator begin2
, ForwardIterator end2
, BinaryPredicate comp
, random_access_iterator_tag
, IteratorTag
)
223 return __gnu_parallel::find_template(begin1
, end1
, begin1
, comp
, __gnu_parallel::find_first_of_selector
<ForwardIterator
>(begin2
, end2
)).first
;
226 // Sequential fallback for input iterator type
227 template<typename InputIterator
, typename ForwardIterator
, typename BinaryPredicate
, typename IteratorTag1
, typename IteratorTag2
>
230 find_first_of_switch(InputIterator begin1
, InputIterator end1
,
231 ForwardIterator begin2
, ForwardIterator end2
, BinaryPredicate comp
, IteratorTag1
, IteratorTag2
)
233 return find_first_of(begin1
, end1
, begin2
, end2
, comp
, __gnu_parallel::sequential_tag());
237 template<typename InputIterator
, typename ForwardIterator
, typename BinaryPredicate
>
239 find_first_of(InputIterator begin1
, InputIterator end1
,
240 ForwardIterator begin2
, ForwardIterator end2
, BinaryPredicate comp
)
242 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
243 typedef std::iterator_traits
<ForwardIterator
> iteratorf_traits
;
244 typedef typename
iteratori_traits::iterator_category iteratori_category
;
245 typedef typename
iteratorf_traits::iterator_category iteratorf_category
;
247 return find_first_of_switch(begin1
, end1
, begin2
, end2
, comp
, iteratori_category(), iteratorf_category());
250 // Public interface, insert default comparator
251 template<typename InputIterator
, typename ForwardIterator
>
253 find_first_of(InputIterator begin1
, InputIterator end1
, ForwardIterator begin2
, ForwardIterator end2
)
255 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
256 typedef std::iterator_traits
<ForwardIterator
> iteratorf_traits
;
257 typedef typename
iteratori_traits::value_type valuei_type
;
258 typedef typename
iteratorf_traits::value_type valuef_type
;
260 return find_first_of(begin1
, end1
, begin2
, end2
, __gnu_parallel::equal_to
<valuei_type
, valuef_type
>());
263 // Sequential fallback
264 template<typename InputIterator
, typename OutputIterator
>
265 inline OutputIterator
266 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
,
267 __gnu_parallel::sequential_tag
)
269 return _GLIBCXX_STD_P::unique_copy
<InputIterator
, OutputIterator
>(begin1
, end1
, out
);
272 // Sequential fallback
273 template<typename InputIterator
, typename OutputIterator
, typename Predicate
>
274 inline OutputIterator
275 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
,
276 Predicate pred
, __gnu_parallel::sequential_tag
)
278 return _GLIBCXX_STD_P::unique_copy
<InputIterator
, OutputIterator
, Predicate
>(begin1
, end1
, out
, pred
);
281 // Sequential fallback for input iterator case
282 template<typename InputIterator
, typename OutputIterator
, typename Predicate
, typename IteratorTag1
, typename IteratorTag2
>
283 inline OutputIterator
284 unique_copy_switch(InputIterator begin
, InputIterator last
, OutputIterator out
,
285 Predicate pred
, IteratorTag1
, IteratorTag2
)
287 return _GLIBCXX_STD_P::unique_copy(begin
, last
, out
, pred
);
290 // Parallel unique_copy for random access iterators
291 template<typename RandomAccessIterator
, typename RandomAccessOutputIterator
, typename Predicate
>
292 RandomAccessOutputIterator
293 unique_copy_switch(RandomAccessIterator begin
, RandomAccessIterator last
, RandomAccessOutputIterator out
,
294 Predicate pred
, random_access_iterator_tag
, random_access_iterator_tag
)
296 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(last
- begin
) > __gnu_parallel::Settings::unique_copy_minimal_n
))
297 return __gnu_parallel::parallel_unique_copy(begin
, last
, out
, pred
);
299 return _GLIBCXX_STD_P::unique_copy(begin
, last
, out
, pred
);
303 template<typename InputIterator
, typename OutputIterator
>
304 inline OutputIterator
305 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
)
307 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
308 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
309 typedef typename
iteratori_traits::iterator_category iteratori_category
;
310 typedef typename
iteratori_traits::value_type value_type
;
311 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
313 return unique_copy_switch(begin1
, end1
, out
, equal_to
<value_type
>(),
314 iteratori_category(), iteratoro_category());
318 template<typename InputIterator
, typename OutputIterator
, typename Predicate
>
319 inline OutputIterator
320 unique_copy(InputIterator begin1
, InputIterator end1
, OutputIterator out
,
323 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
324 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
325 typedef typename
iteratori_traits::iterator_category iteratori_category
;
326 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
328 return unique_copy_switch(begin1
, end1
, out
, pred
, iteratori_category(), iteratoro_category());
331 // Sequential fallback
332 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
333 inline OutputIterator
334 set_union(InputIterator1 begin1
, InputIterator1 end1
,
335 InputIterator2 begin2
, InputIterator2 end2
,
336 OutputIterator out
, __gnu_parallel::sequential_tag
)
338 return _GLIBCXX_STD_P::set_union(begin1
, end1
, begin2
, end2
, out
);
341 // Sequential fallback
342 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Predicate
>
343 inline OutputIterator
344 set_union(InputIterator1 begin1
, InputIterator1 end1
,
345 InputIterator2 begin2
, InputIterator2 end2
,
346 OutputIterator out
, Predicate pred
, __gnu_parallel::sequential_tag
)
348 return _GLIBCXX_STD_P::set_union(begin1
, end1
, begin2
, end2
, out
, pred
);
351 // Sequential fallback for input iterator case
352 template<typename InputIterator1
, typename InputIterator2
, typename Predicate
,
353 typename OutputIterator
, typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
354 inline OutputIterator
355 set_union_switch(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
356 InputIterator2 end2
, OutputIterator result
, Predicate pred
, IteratorTag1
,
357 IteratorTag2
, IteratorTag3
)
359 return _GLIBCXX_STD_P::set_union(begin1
, end1
, begin2
, end2
, result
, pred
);
362 // Parallel set_union for random access iterators
363 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
364 typename OutputRandomAccessIterator
, typename Predicate
>
365 OutputRandomAccessIterator
366 set_union_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
, RandomAccessIterator2 begin2
,
367 RandomAccessIterator2 end2
, OutputRandomAccessIterator result
, Predicate pred
,
368 random_access_iterator_tag
, random_access_iterator_tag
, random_access_iterator_tag
)
370 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
) >= __gnu_parallel::Settings::set_union_minimal_n
|| static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
) >= __gnu_parallel::Settings::set_union_minimal_n
))
371 return __gnu_parallel::parallel_set_union(begin1
, end1
, begin2
, end2
, result
, pred
);
373 return _GLIBCXX_STD_P::set_union(begin1
, end1
, begin2
, end2
, result
, pred
);
377 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
378 inline OutputIterator
379 set_union(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator out
)
381 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
382 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
383 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
384 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
385 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
386 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
387 typedef typename
iteratori1_traits::value_type value1_type
;
388 typedef typename
iteratori2_traits::value_type value2_type
;
390 return set_union_switch(begin1
, end1
, begin2
, end2
, out
, __gnu_parallel::less
<value1_type
, value2_type
>(),
391 iteratori1_category(), iteratori2_category(), iteratoro_category());
395 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Predicate
>
396 inline OutputIterator
397 set_union(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
398 InputIterator2 end2
, OutputIterator out
, Predicate pred
)
400 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
401 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
402 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
403 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
404 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
405 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
407 return set_union_switch(begin1
, end1
, begin2
, end2
, out
, pred
,
408 iteratori1_category(), iteratori2_category(), iteratoro_category());
411 // Sequential fallback.
412 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
413 inline OutputIterator
414 set_intersection(InputIterator1 begin1
, InputIterator1 end1
,
415 InputIterator2 begin2
, InputIterator2 end2
,
416 OutputIterator out
, __gnu_parallel::sequential_tag
)
418 return _GLIBCXX_STD_P::set_intersection(begin1
, end1
, begin2
, end2
, out
);
421 // Sequential fallback.
422 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Predicate
>
423 inline OutputIterator
424 set_intersection(InputIterator1 begin1
, InputIterator1 end1
,
425 InputIterator2 begin2
, InputIterator2 end2
,
426 OutputIterator out
, Predicate pred
, __gnu_parallel::sequential_tag
)
428 return _GLIBCXX_STD_P::set_intersection(begin1
, end1
, begin2
, end2
, out
, pred
);
431 // Sequential fallback for input iterator case
432 template<typename InputIterator1
, typename InputIterator2
, typename Predicate
,
433 typename OutputIterator
, typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
434 inline OutputIterator
435 set_intersection_switch(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
436 InputIterator2 end2
, OutputIterator result
, Predicate pred
, IteratorTag1
,
437 IteratorTag2
, IteratorTag3
)
439 return _GLIBCXX_STD_P::set_intersection(begin1
, end1
, begin2
, end2
, result
, pred
);
442 // Parallel set_intersection for random access iterators
443 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
444 typename OutputRandomAccessIterator
, typename Predicate
>
445 OutputRandomAccessIterator
446 set_intersection_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
, RandomAccessIterator2 begin2
,
447 RandomAccessIterator2 end2
, OutputRandomAccessIterator result
, Predicate pred
,
448 random_access_iterator_tag
, random_access_iterator_tag
, random_access_iterator_tag
)
450 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
) >= __gnu_parallel::Settings::set_union_minimal_n
|| static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
) >= __gnu_parallel::Settings::set_union_minimal_n
))
451 return __gnu_parallel::parallel_set_intersection(begin1
, end1
, begin2
, end2
, result
, pred
);
453 return _GLIBCXX_STD_P::set_intersection(begin1
, end1
, begin2
, end2
, result
, pred
);
457 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
458 inline OutputIterator
459 set_intersection(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator out
)
461 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
462 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
463 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
464 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
465 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
466 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
467 typedef typename
iteratori1_traits::value_type value1_type
;
468 typedef typename
iteratori2_traits::value_type value2_type
;
470 return set_intersection_switch(begin1
, end1
, begin2
, end2
, out
, __gnu_parallel::less
<value1_type
, value2_type
>(),
471 iteratori1_category(), iteratori2_category(), iteratoro_category());
474 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Predicate
>
475 inline OutputIterator
476 set_intersection(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
477 InputIterator2 end2
, OutputIterator out
, Predicate pred
)
479 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
480 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
481 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
482 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
483 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
484 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
486 return set_intersection_switch(begin1
, end1
, begin2
, end2
, out
, pred
,
487 iteratori1_category(), iteratori2_category(), iteratoro_category());
490 // Sequential fallback
491 template<typename InputIterator1
, typename InputIterator2
,
492 typename OutputIterator
>
493 inline OutputIterator
494 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
,
495 InputIterator2 begin2
, InputIterator2 end2
,
496 OutputIterator out
, __gnu_parallel::sequential_tag
)
498 return _GLIBCXX_STD_P::set_symmetric_difference(begin1
,end1
, begin2
, end2
, out
);
501 // Sequential fallback
502 template<typename InputIterator1
, typename InputIterator2
,
503 typename OutputIterator
, typename Predicate
>
504 inline OutputIterator
505 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
,
506 InputIterator2 begin2
, InputIterator2 end2
,
507 OutputIterator out
, Predicate pred
, __gnu_parallel::sequential_tag
)
509 return _GLIBCXX_STD_P::set_symmetric_difference(begin1
, end1
, begin2
, end2
, out
, pred
);
512 // Sequential fallback for input iterator case
513 template<typename InputIterator1
, typename InputIterator2
, typename Predicate
, typename OutputIterator
, typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
514 inline OutputIterator
515 set_symmetric_difference_switch(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator result
, Predicate pred
, IteratorTag1
, IteratorTag2
, IteratorTag3
)
517 return _GLIBCXX_STD_P::set_symmetric_difference(begin1
, end1
, begin2
, end2
, result
, pred
);
520 // Parallel set_symmetric_difference for random access iterators
521 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
522 typename OutputRandomAccessIterator
, typename Predicate
>
523 OutputRandomAccessIterator
524 set_symmetric_difference_switch(RandomAccessIterator1 begin1
,
525 RandomAccessIterator1 end1
, RandomAccessIterator2 begin2
,
526 RandomAccessIterator2 end2
, OutputRandomAccessIterator result
, Predicate pred
,
527 random_access_iterator_tag
, random_access_iterator_tag
, random_access_iterator_tag
)
529 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
) >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n
|| static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
) >= __gnu_parallel::Settings::set_symmetric_difference_minimal_n
))
530 return __gnu_parallel::parallel_set_symmetric_difference(begin1
, end1
, begin2
, end2
, result
, pred
);
532 return _GLIBCXX_STD_P::set_symmetric_difference(begin1
, end1
, begin2
, end2
, result
, pred
);
536 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
537 inline OutputIterator
538 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator out
)
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 iteratori1_category
;
544 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
545 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
546 typedef typename
iteratori1_traits::value_type value1_type
;
547 typedef typename
iteratori2_traits::value_type value2_type
;
549 return set_symmetric_difference_switch(begin1
, end1
, begin2
, end2
, out
, __gnu_parallel::less
<value1_type
, value2_type
>(),
550 iteratori1_category(), iteratori2_category(), iteratoro_category());
554 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Predicate
>
555 inline OutputIterator
556 set_symmetric_difference(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
557 InputIterator2 end2
, OutputIterator out
, Predicate pred
)
559 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
560 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
561 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
562 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
563 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
564 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
566 return set_symmetric_difference_switch(begin1
, end1
, begin2
, end2
, out
, pred
,
567 iteratori1_category(), iteratori2_category(), iteratoro_category());
570 // Sequential fallback.
571 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
572 inline OutputIterator
573 set_difference(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator out
, __gnu_parallel::sequential_tag
)
575 return _GLIBCXX_STD_P::set_difference(begin1
,end1
, begin2
, end2
, out
);
578 // Sequential fallback.
579 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Predicate
>
580 inline OutputIterator
581 set_difference(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator out
, Predicate pred
, __gnu_parallel::sequential_tag
)
583 return _GLIBCXX_STD_P::set_difference(begin1
, end1
, begin2
, end2
, out
, pred
);
586 // Sequential fallback for input iterator case.
587 template<typename InputIterator1
, typename InputIterator2
, typename Predicate
,
588 typename OutputIterator
, typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
589 inline OutputIterator
590 set_difference_switch(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
591 InputIterator2 end2
, OutputIterator result
, Predicate pred
, IteratorTag1
, IteratorTag2
, IteratorTag3
)
593 return _GLIBCXX_STD_P::set_difference(begin1
, end1
, begin2
, end2
, result
, pred
);
596 // Parallel set_difference for random access iterators
597 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
598 typename OutputRandomAccessIterator
, typename Predicate
>
599 OutputRandomAccessIterator
600 set_difference_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
, RandomAccessIterator2 begin2
,
601 RandomAccessIterator2 end2
, OutputRandomAccessIterator result
, Predicate pred
,
602 random_access_iterator_tag
, random_access_iterator_tag
, random_access_iterator_tag
)
604 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
) >= __gnu_parallel::Settings::set_difference_minimal_n
|| static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
) >= __gnu_parallel::Settings::set_difference_minimal_n
))
605 return __gnu_parallel::parallel_set_difference(begin1
, end1
, begin2
, end2
, result
, pred
);
607 return _GLIBCXX_STD_P::set_difference(begin1
, end1
, begin2
, end2
, result
, pred
);
611 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
612 inline OutputIterator
613 set_difference(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator out
)
615 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
616 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
617 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
618 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
619 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
620 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
621 typedef typename
iteratori1_traits::value_type value1_type
;
622 typedef typename
iteratori2_traits::value_type value2_type
;
624 return set_difference_switch(begin1
, end1
, begin2
, end2
, out
, __gnu_parallel::less
<value1_type
, value2_type
>(),
625 iteratori1_category(), iteratori2_category(), iteratoro_category());
629 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Predicate
>
630 inline OutputIterator
631 set_difference(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
,
632 InputIterator2 end2
, OutputIterator out
, Predicate pred
)
634 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
635 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
636 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
637 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
638 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
639 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
641 return set_difference_switch(begin1
, end1
, begin2
, end2
, out
, pred
,
642 iteratori1_category(), iteratori2_category(), iteratoro_category());
645 // Sequential fallback
646 template<typename ForwardIterator
>
647 inline ForwardIterator
648 adjacent_find(ForwardIterator begin
, ForwardIterator end
, __gnu_parallel::sequential_tag
)
650 return _GLIBCXX_STD_P::adjacent_find
<ForwardIterator
>(begin
, end
);
653 // Sequential fallback
654 template<typename ForwardIterator
, typename BinaryPredicate
>
655 inline ForwardIterator
656 adjacent_find(ForwardIterator begin
, ForwardIterator end
, BinaryPredicate binary_pred
, __gnu_parallel::sequential_tag
)
658 return _GLIBCXX_STD_P::adjacent_find
<ForwardIterator
, BinaryPredicate
>(begin
, end
, binary_pred
);
661 // Parallel algorithm for random access iterators
662 template<typename RandomAccessIterator
>
664 adjacent_find_switch(RandomAccessIterator begin
, RandomAccessIterator end
, random_access_iterator_tag
)
666 typedef typename iterator_traits
<RandomAccessIterator
>::value_type value_type
;
668 if (_GLIBCXX_PARALLEL_CONDITION(true))
670 RandomAccessIterator spot
= __gnu_parallel::find_template(begin
, end
- 1, begin
, equal_to
<value_type
>(), __gnu_parallel::adjacent_find_selector()).first
;
671 if (spot
== (end
- 1))
677 return adjacent_find
<RandomAccessIterator
>(begin
, end
, __gnu_parallel::sequential_tag());
680 // Sequential fallback for input iterator case
681 template<typename ForwardIterator
, typename IteratorTag
>
682 inline ForwardIterator
683 adjacent_find_switch(ForwardIterator begin
, ForwardIterator end
, IteratorTag
)
685 return adjacent_find
<ForwardIterator
>(begin
, end
, __gnu_parallel::sequential_tag());
689 template<typename ForwardIterator
>
690 inline ForwardIterator
691 adjacent_find(ForwardIterator begin
, ForwardIterator end
)
693 return adjacent_find_switch(begin
, end
, typename
std::iterator_traits
<ForwardIterator
>::iterator_category());
696 // Sequential fallback for input iterator case
697 template<typename ForwardIterator
, typename BinaryPredicate
, typename IteratorTag
>
698 inline ForwardIterator
699 adjacent_find_switch(ForwardIterator begin
, ForwardIterator end
, BinaryPredicate binary_pred
, IteratorTag
)
701 return adjacent_find
<ForwardIterator
, BinaryPredicate
>(begin
, end
, binary_pred
, __gnu_parallel::sequential_tag());
704 // Parallel algorithm for random access iterators
705 template<typename RandomAccessIterator
, typename BinaryPredicate
>
707 adjacent_find_switch(RandomAccessIterator begin
, RandomAccessIterator end
, BinaryPredicate binary_pred
, random_access_iterator_tag
)
709 if (_GLIBCXX_PARALLEL_CONDITION(true))
710 return __gnu_parallel::find_template(begin
, end
, begin
, binary_pred
, __gnu_parallel::adjacent_find_selector()).first
;
712 return adjacent_find(begin
, end
, binary_pred
, __gnu_parallel::sequential_tag());
716 template<typename ForwardIterator
, typename BinaryPredicate
>
717 inline ForwardIterator
718 adjacent_find(ForwardIterator begin
, ForwardIterator end
, BinaryPredicate binary_pred
)
720 return adjacent_find_switch
<ForwardIterator
, BinaryPredicate
>(begin
, end
, binary_pred
, typename
std::iterator_traits
<ForwardIterator
>::iterator_category());
723 // Sequential fallback
724 template<typename InputIterator
, typename T
>
725 inline typename iterator_traits
<InputIterator
>::difference_type
726 count(InputIterator begin
, InputIterator end
, const T
& value
, __gnu_parallel::sequential_tag
)
728 return _GLIBCXX_STD_P::count
<InputIterator
, T
>(begin
, end
, value
);
731 // Parallel code for random access iterators
732 template<typename RandomAccessIterator
, typename T
>
733 typename iterator_traits
<RandomAccessIterator
>::difference_type
734 count_switch(RandomAccessIterator begin
, RandomAccessIterator end
, const T
& value
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
736 typedef typename iterator_traits
<RandomAccessIterator
>::value_type value_type
;
737 typedef typename iterator_traits
<RandomAccessIterator
>::difference_type difference_type
;
739 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::count_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
741 difference_type res
= 0;
742 __gnu_parallel::count_selector
<RandomAccessIterator
, difference_type
> functionality
;
743 __gnu_parallel::for_each_template_random_access(begin
, end
, value
, functionality
, std::plus
<__gnu_parallel::sequence_index_t
>(), res
, res
, -1, parallelism_tag
);
747 return count
<RandomAccessIterator
, T
>(begin
, end
, value
, __gnu_parallel::sequential_tag());
750 // Sequential fallback for input iterator case.
751 template<typename InputIterator
, typename T
, typename IteratorTag
>
752 typename iterator_traits
<InputIterator
>::difference_type
753 count_switch(InputIterator begin
, InputIterator end
, const T
& value
, IteratorTag
, __gnu_parallel::parallelism parallelism_tag
)
755 return count
<InputIterator
, T
>(begin
, end
, value
, __gnu_parallel::sequential_tag());
759 template<typename InputIterator
, typename T
>
760 inline typename iterator_traits
<InputIterator
>::difference_type
761 count(InputIterator begin
, InputIterator end
, const T
& value
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_unbalanced
)
763 return count_switch(begin
, end
, value
, typename
std::iterator_traits
<InputIterator
>::iterator_category(), parallelism_tag
);
766 // Sequential fallback.
767 template<typename InputIterator
, typename Predicate
>
768 inline typename iterator_traits
<InputIterator
>::difference_type
769 count_if(InputIterator begin
, InputIterator end
, Predicate pred
, __gnu_parallel::sequential_tag
)
771 return _GLIBCXX_STD_P::count_if(begin
, end
, pred
);
774 // Parallel count_if for random access iterators
775 template<typename RandomAccessIterator
, typename Predicate
>
776 typename iterator_traits
<RandomAccessIterator
>::difference_type
777 count_if_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Predicate pred
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
779 typedef typename iterator_traits
<RandomAccessIterator
>::value_type value_type
;
780 typedef typename iterator_traits
<RandomAccessIterator
>::difference_type difference_type
;
782 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::count_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
784 difference_type res
= 0;
785 __gnu_parallel::count_if_selector
<RandomAccessIterator
, difference_type
> functionality
;
786 __gnu_parallel::for_each_template_random_access(begin
, end
, pred
, functionality
, std::plus
<__gnu_parallel::sequence_index_t
>(), res
, res
, -1, parallelism_tag
);
790 return count_if
<RandomAccessIterator
, Predicate
>(begin
, end
, pred
, __gnu_parallel::sequential_tag());
793 // Sequential fallback for input iterator case.
794 template<typename InputIterator
, typename Predicate
, typename IteratorTag
>
795 typename iterator_traits
<InputIterator
>::difference_type
796 count_if_switch(InputIterator begin
, InputIterator end
, Predicate pred
, IteratorTag
, __gnu_parallel::parallelism
)
798 return count_if
<InputIterator
, Predicate
>(begin
, end
, pred
, __gnu_parallel::sequential_tag());
802 template<typename InputIterator
, typename Predicate
>
803 inline typename iterator_traits
<InputIterator
>::difference_type
804 count_if(InputIterator begin
, InputIterator end
, Predicate pred
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_unbalanced
)
806 typedef iterator_traits
<InputIterator
> traits_type
;
807 typedef typename
traits_type::iterator_category iterator_category
;
808 return count_if_switch(begin
, end
, pred
, iterator_category(), parallelism_tag
);
812 // Sequential fallback.
813 template<typename ForwardIterator1
, typename ForwardIterator2
>
814 inline ForwardIterator1
815 search(ForwardIterator1 begin1
, ForwardIterator1 end1
, ForwardIterator2 begin2
, ForwardIterator2 end2
, __gnu_parallel::sequential_tag
)
817 return _GLIBCXX_STD_P::search(begin1
, end1
, begin2
, end2
);
820 // Parallel algorithm for random access iterator
821 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
>
822 RandomAccessIterator1
823 search_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
, RandomAccessIterator2 begin2
, RandomAccessIterator2 end2
, random_access_iterator_tag
, random_access_iterator_tag
)
825 typedef std::iterator_traits
<RandomAccessIterator1
> iterator1_traits
;
826 typedef typename
iterator1_traits::value_type value1_type
;
827 typedef std::iterator_traits
<RandomAccessIterator2
> iterator2_traits
;
828 typedef typename
iterator2_traits::value_type value2_type
;
830 if (_GLIBCXX_PARALLEL_CONDITION(true))
831 return __gnu_parallel::search_template(begin1
, end1
, begin2
, end2
, __gnu_parallel::equal_to
<value1_type
, value2_type
>());
833 return search(begin1
, end1
, begin2
, end2
, __gnu_parallel::sequential_tag());
836 // Sequential fallback for input iterator case
837 template<typename ForwardIterator1
, typename ForwardIterator2
, typename IteratorTag1
, typename IteratorTag2
>
838 inline ForwardIterator1
839 search_switch(ForwardIterator1 begin1
, ForwardIterator1 end1
, ForwardIterator2 begin2
, ForwardIterator2 end2
, IteratorTag1
, IteratorTag2
)
841 return search(begin1
, end1
, begin2
, end2
, __gnu_parallel::sequential_tag());
845 template<typename ForwardIterator1
, typename ForwardIterator2
>
846 inline ForwardIterator1
847 search(ForwardIterator1 begin1
, ForwardIterator1 end1
, ForwardIterator2 begin2
, ForwardIterator2 end2
)
849 typedef std::iterator_traits
<ForwardIterator1
> iterator1_traits
;
850 typedef typename
iterator1_traits::iterator_category iterator1_category
;
851 typedef std::iterator_traits
<ForwardIterator2
> iterator2_traits
;
852 typedef typename
iterator2_traits::iterator_category iterator2_category
;
854 return search_switch(begin1
, end1
, begin2
, end2
, iterator1_category(), iterator2_category());
858 template<typename ForwardIterator1
, typename ForwardIterator2
, typename BinaryPredicate
>
859 inline ForwardIterator1
860 search(ForwardIterator1 begin1
, ForwardIterator1 end1
, ForwardIterator2 begin2
, ForwardIterator2 end2
, BinaryPredicate pred
, __gnu_parallel::sequential_tag
)
862 return _GLIBCXX_STD_P::search(begin1
, end1
, begin2
, end2
, pred
);
865 // Parallel algorithm for random access iterator.
866 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
,
867 typename BinaryPredicate
>
868 RandomAccessIterator1
869 search_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
,
870 RandomAccessIterator2 begin2
, RandomAccessIterator2 end2
, BinaryPredicate pred
, random_access_iterator_tag
, random_access_iterator_tag
)
872 if (_GLIBCXX_PARALLEL_CONDITION(true))
873 return __gnu_parallel::search_template(begin1
, end1
, begin2
, end2
, pred
);
875 return search(begin1
, end1
, begin2
, end2
, pred
, __gnu_parallel::sequential_tag());
878 // Sequential fallback for input iterator case
879 template<typename ForwardIterator1
, typename ForwardIterator2
,
880 typename BinaryPredicate
, typename IteratorTag1
, typename IteratorTag2
>
881 inline ForwardIterator1
882 search_switch(ForwardIterator1 begin1
, ForwardIterator1 end1
,
883 ForwardIterator2 begin2
, ForwardIterator2 end2
, BinaryPredicate pred
, IteratorTag1
, IteratorTag2
)
885 return search(begin1
, end1
, begin2
, end2
, pred
, __gnu_parallel::sequential_tag());
889 template<typename ForwardIterator1
, typename ForwardIterator2
, typename BinaryPredicate
>
890 inline ForwardIterator1
891 search(ForwardIterator1 begin1
, ForwardIterator1 end1
, ForwardIterator2 begin2
, ForwardIterator2 end2
, BinaryPredicate pred
)
893 typedef std::iterator_traits
<ForwardIterator1
> iterator1_traits
;
894 typedef typename
iterator1_traits::iterator_category iterator1_category
;
895 typedef std::iterator_traits
<ForwardIterator2
> iterator2_traits
;
896 typedef typename
iterator2_traits::iterator_category iterator2_category
;
897 return search_switch(begin1
, end1
, begin2
, end2
, pred
, iterator1_category(), iterator2_category());
900 // Sequential fallback
901 template<typename ForwardIterator
, typename Integer
, typename T
>
902 inline ForwardIterator
903 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
, const T
& val
, __gnu_parallel::sequential_tag
)
904 { return _GLIBCXX_STD_P::search_n(begin
, end
, count
, val
); }
906 // Sequential fallback
907 template<typename ForwardIterator
, typename Integer
, typename T
, typename BinaryPredicate
>
908 inline ForwardIterator
909 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
, const T
& val
, BinaryPredicate binary_pred
, __gnu_parallel::sequential_tag
)
911 return _GLIBCXX_STD_P::search_n(begin
, end
, count
, val
, binary_pred
);
915 template<typename ForwardIterator
, typename Integer
, typename T
>
916 inline ForwardIterator
917 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
, const T
& val
)
919 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
920 return search_n(begin
, end
, count
, val
, __gnu_parallel::equal_to
<value_type
, T
>());
923 // Parallel algorithm for random access iterators.
924 template<typename RandomAccessIterator
, typename Integer
, typename T
, typename BinaryPredicate
>
926 search_n_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Integer count
, const T
& val
, BinaryPredicate binary_pred
, random_access_iterator_tag
)
928 if (_GLIBCXX_PARALLEL_CONDITION(true))
930 __gnu_parallel::pseudo_sequence
<T
, Integer
> ps(val
, count
);
931 return __gnu_parallel::search_template(begin
, end
, ps
.begin(), ps
.end(), binary_pred
);
934 return std::__search_n(begin
, end
, count
, val
, binary_pred
, random_access_iterator_tag());
937 // Sequential fallback for input iterator case.
938 template<typename ForwardIterator
, typename Integer
, typename T
, typename BinaryPredicate
, typename IteratorTag
>
939 inline ForwardIterator
940 search_n_switch(ForwardIterator begin
, ForwardIterator end
, Integer count
, const T
& val
, BinaryPredicate binary_pred
, IteratorTag
)
942 return __search_n(begin
, end
, count
, val
, binary_pred
, IteratorTag());
946 template<typename ForwardIterator
, typename Integer
, typename T
, typename BinaryPredicate
>
947 inline ForwardIterator
948 search_n(ForwardIterator begin
, ForwardIterator end
, Integer count
, const T
& val
, BinaryPredicate binary_pred
)
950 return search_n_switch(begin
, end
, count
, val
, binary_pred
, typename
std::iterator_traits
<ForwardIterator
>::iterator_category());
953 // Sequential fallback.
954 template<typename InputIterator
, typename OutputIterator
, typename UnaryOperation
>
955 inline OutputIterator
956 transform(InputIterator begin
, InputIterator end
, OutputIterator result
, UnaryOperation unary_op
, __gnu_parallel::sequential_tag
)
958 return _GLIBCXX_STD_P::transform(begin
, end
, result
, unary_op
);
961 // Sequential fallback
962 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename BinaryOperation
>
963 inline OutputIterator
964 transform(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, OutputIterator result
, BinaryOperation binary_op
, __gnu_parallel::sequential_tag
)
966 return _GLIBCXX_STD_P::transform(begin1
, end1
, begin2
, result
, binary_op
);
969 // Parallel unary transform for random access iterators.
970 template<typename RandomAccessIterator1
, typename RandomAccessIterator3
, typename UnaryOperation
>
971 RandomAccessIterator3
972 transform1_switch(RandomAccessIterator1 begin
, RandomAccessIterator1 end
, RandomAccessIterator3 result
, UnaryOperation unary_op
, random_access_iterator_tag
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
974 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::transform_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
977 typedef __gnu_parallel::iterator_pair
<RandomAccessIterator1
, RandomAccessIterator3
, random_access_iterator_tag
> ip
;
978 ip
begin_pair(begin
, result
), end_pair(end
, result
+ (end
- begin
));
979 __gnu_parallel::transform1_selector
<ip
> functionality
;
980 __gnu_parallel::for_each_template_random_access(begin_pair
, end_pair
, unary_op
, functionality
, __gnu_parallel::dummy_reduct(), dummy
, dummy
, -1, parallelism_tag
);
981 return functionality
.finish_iterator
;
984 return transform(begin
, end
, result
, unary_op
, __gnu_parallel::sequential_tag());
987 // Sequential fallback for input iterator case.
988 template<typename RandomAccessIterator1
, typename RandomAccessIterator3
, typename UnaryOperation
, typename IteratorTag1
, typename IteratorTag2
>
989 inline RandomAccessIterator3
990 transform1_switch(RandomAccessIterator1 begin
, RandomAccessIterator1 end
, RandomAccessIterator3 result
, UnaryOperation unary_op
, IteratorTag1
, IteratorTag2
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
992 return _GLIBCXX_STD_P::transform(begin
, end
, result
, unary_op
);
996 // Parallel binary transform for random access iterators.
997 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
, typename RandomAccessIterator3
, typename BinaryOperation
>
998 RandomAccessIterator3
999 transform2_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
, RandomAccessIterator2 begin2
, RandomAccessIterator3 result
, BinaryOperation binary_op
, random_access_iterator_tag
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1001 if (_GLIBCXX_PARALLEL_CONDITION((end1
- begin1
) >= __gnu_parallel::Settings::transform_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
1004 typedef __gnu_parallel::iterator_triple
<RandomAccessIterator1
, RandomAccessIterator2
, RandomAccessIterator3
, random_access_iterator_tag
> ip
;
1005 ip
begin_triple(begin1
, begin2
, result
), end_triple(end1
, begin2
+ (end1
- begin1
), result
+ (end1
- begin1
));
1006 __gnu_parallel::transform2_selector
<ip
> functionality
;
1007 __gnu_parallel::for_each_template_random_access(begin_triple
, end_triple
, binary_op
, functionality
, __gnu_parallel::dummy_reduct(), dummy
, dummy
, -1, parallelism_tag
);
1008 return functionality
.finish_iterator
;
1011 return transform(begin1
, end1
, begin2
, result
, binary_op
, __gnu_parallel::sequential_tag());
1014 // Sequential fallback for input iterator case.
1015 template<typename RandomAccessIterator1
, typename RandomAccessIterator2
, typename RandomAccessIterator3
, typename BinaryOperation
, typename tag1
, typename tag2
, typename tag3
>
1016 inline RandomAccessIterator3
1017 transform2_switch(RandomAccessIterator1 begin1
, RandomAccessIterator1 end1
, RandomAccessIterator2 begin2
, RandomAccessIterator3 result
, BinaryOperation binary_op
, tag1
, tag2
, tag3
, __gnu_parallel::parallelism
)
1019 return _GLIBCXX_STD_P::transform(begin1
, end1
, begin2
, result
, binary_op
);
1022 // Public interface.
1023 template<typename InputIterator
, typename OutputIterator
, typename UnaryOperation
>
1024 inline OutputIterator
1025 transform(InputIterator begin
, InputIterator end
, OutputIterator result
,
1026 UnaryOperation unary_op
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1028 typedef std::iterator_traits
<InputIterator
> iteratori_traits
;
1029 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1030 typedef typename
iteratori_traits::iterator_category iteratori_category
;
1031 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1033 return transform1_switch(begin
, end
, result
, unary_op
,
1034 iteratori_category(), iteratoro_category(), parallelism_tag
);
1037 // Public interface.
1038 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename BinaryOperation
>
1039 inline OutputIterator
1040 transform(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, OutputIterator result
, BinaryOperation binary_op
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1042 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
1043 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
1044 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
1045 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
1046 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1047 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1050 return transform2_switch(begin1
, end1
, begin2
, result
, binary_op
,
1051 iteratori1_category(), iteratori2_category(), iteratoro_category(), parallelism_tag
);
1054 // Sequential fallback
1055 template<typename ForwardIterator
, typename T
>
1057 replace(ForwardIterator begin
, ForwardIterator end
, const T
& old_value
, const T
& new_value
, __gnu_parallel::sequential_tag
)
1058 { _GLIBCXX_STD_P::replace(begin
, end
, old_value
, new_value
); }
1060 // Sequential fallback for input iterator case
1061 template<typename ForwardIterator
, typename T
, typename IteratorTag
>
1063 replace_switch(ForwardIterator begin
, ForwardIterator end
, const T
& old_value
, const T
& new_value
, IteratorTag
, __gnu_parallel::parallelism parallelism_tag
)
1064 { replace(begin
, end
, old_value
, new_value
, __gnu_parallel::sequential_tag()); }
1066 // Parallel replace for random access iterators
1067 template<typename RandomAccessIterator
, typename T
>
1069 replace_switch(RandomAccessIterator begin
, RandomAccessIterator end
, const T
& old_value
, const T
& new_value
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
1070 { replace(begin
, end
, old_value
, new_value
, __gnu_parallel::sequential_tag()); }
1073 template<typename ForwardIterator
, typename T
>
1075 replace(ForwardIterator begin
, ForwardIterator end
, const T
& old_value
, const T
& new_value
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1077 replace_switch(begin
, end
, old_value
, new_value
, typename
std::iterator_traits
<ForwardIterator
>::iterator_category(), parallelism_tag
);
1081 // Sequential fallback
1082 template<typename ForwardIterator
, typename Predicate
, typename T
>
1084 replace_if(ForwardIterator begin
, ForwardIterator end
, Predicate pred
, const T
& new_value
, __gnu_parallel::sequential_tag
)
1085 { _GLIBCXX_STD_P::replace_if(begin
, end
, pred
, new_value
); }
1087 // Sequential fallback for input iterator case
1088 template<typename ForwardIterator
, typename Predicate
, typename T
, typename IteratorTag
>
1090 replace_if_switch(ForwardIterator begin
, ForwardIterator end
, Predicate pred
, const T
& new_value
, IteratorTag
, __gnu_parallel::parallelism parallelism_tag
)
1091 { replace_if(begin
, end
, pred
, new_value
, __gnu_parallel::sequential_tag()); }
1093 // Parallel algorithm for random access iterators.
1094 template<typename RandomAccessIterator
, typename Predicate
, typename T
>
1096 replace_if_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Predicate pred
, const T
& new_value
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
1098 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::replace_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
1101 __gnu_parallel::replace_if_selector
<RandomAccessIterator
, Predicate
, T
> functionality(new_value
);
1102 __gnu_parallel::for_each_template_random_access(begin
, end
, pred
, functionality
, __gnu_parallel::dummy_reduct(), true, dummy
, -1, parallelism_tag
);
1105 replace_if(begin
, end
, pred
, new_value
, __gnu_parallel::sequential_tag());
1108 // Public interface.
1109 template<typename ForwardIterator
, typename Predicate
, typename T
>
1111 replace_if(ForwardIterator begin
, ForwardIterator end
,
1112 Predicate pred
, const T
& new_value
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1114 typedef std::iterator_traits
<ForwardIterator
> iterator_traits
;
1115 typedef typename
iterator_traits::iterator_category iterator_category
;
1117 replace_if_switch(begin
, end
, pred
, new_value
, iterator_category(), parallelism_tag
);
1120 // Sequential fallback
1121 template<typename ForwardIterator
, typename Generator
>
1123 generate(ForwardIterator begin
, ForwardIterator end
, Generator gen
, __gnu_parallel::sequential_tag
)
1124 { _GLIBCXX_STD_P::generate
<ForwardIterator
, Generator
>(begin
, end
, gen
); }
1126 // Sequential fallback for input iterator case.
1127 template<typename ForwardIterator
, typename Generator
, typename IteratorTag
>
1129 generate_switch(ForwardIterator begin
, ForwardIterator end
, Generator gen
, IteratorTag
, __gnu_parallel::parallelism parallelism_tag
)
1130 { generate(begin
, end
, gen
, __gnu_parallel::sequential_tag()); }
1132 // Parallel algorithm for random access iterators.
1133 template<typename RandomAccessIterator
, typename Generator
>
1135 generate_switch(RandomAccessIterator begin
, RandomAccessIterator end
,
1136 Generator gen
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
1138 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::generate_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
1141 __gnu_parallel::generate_selector
<RandomAccessIterator
> functionality
;
1142 __gnu_parallel::for_each_template_random_access(begin
, end
, gen
, functionality
, __gnu_parallel::dummy_reduct(), true, dummy
, -1, parallelism_tag
);
1145 generate(begin
, end
, gen
, __gnu_parallel::sequential_tag());
1148 // Public interface.
1149 template<typename ForwardIterator
, typename Generator
>
1151 generate(ForwardIterator begin
, ForwardIterator end
,
1152 Generator gen
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1154 typedef std::iterator_traits
<ForwardIterator
> iterator_traits
;
1155 typedef typename
iterator_traits::iterator_category iterator_category
;
1156 generate_switch(begin
, end
, gen
, iterator_category(), parallelism_tag
);
1160 // Sequential fallback.
1161 template<typename OutputIterator
, typename Size
, typename Generator
>
1162 inline OutputIterator
1163 generate_n(OutputIterator begin
, Size n
, Generator gen
, __gnu_parallel::sequential_tag
)
1164 { return _GLIBCXX_STD_P::generate_n(begin
, n
, gen
); }
1166 // Sequential fallback for input iterator case.
1167 template<typename OutputIterator
, typename Size
, typename Generator
, typename IteratorTag
>
1169 generate_n_switch(OutputIterator begin
, Size n
, Generator gen
, IteratorTag
, __gnu_parallel::parallelism
)
1170 { return generate_n(begin
, n
, gen
, __gnu_parallel::sequential_tag()); }
1172 // Parallel algorithm for random access iterators.
1173 template<typename RandomAccessIterator
, typename Size
, typename Generator
>
1174 RandomAccessIterator
1175 generate_n_switch(RandomAccessIterator begin
, Size n
, Generator gen
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
1176 { return generate_n(begin
, n
, gen
, __gnu_parallel::sequential_tag()); }
1178 // Public interface.
1179 template<typename OutputIterator
, typename Size
, typename Generator
>
1180 inline OutputIterator
1181 generate_n(OutputIterator begin
, Size n
, Generator gen
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1183 typedef std::iterator_traits
<OutputIterator
> iterator_traits
;
1184 typedef typename
iterator_traits::iterator_category iterator_category
;
1185 return generate_n_switch(begin
, n
, gen
, iterator_category(), parallelism_tag
);
1189 // Sequential fallback.
1190 template<typename RandomAccessIterator
>
1192 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
, __gnu_parallel::sequential_tag
)
1193 { _GLIBCXX_STD_P::random_shuffle(begin
, end
); }
1195 // Sequential fallback.
1196 template<typename RandomAccessIterator
, typename RandomNumberGenerator
>
1198 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
, RandomNumberGenerator
& rand
, __gnu_parallel::sequential_tag
)
1199 { _GLIBCXX_STD_P::random_shuffle(begin
, end
, rand
); }
1202 /** @brief Functor wrapper for std::rand(). */
1203 template<typename must_be_int
= int>
1204 struct c_rand_number
1206 inline int operator()(int limit
)
1207 { return rand() % limit
; }
1210 // Fill in random number generator.
1211 template<typename RandomAccessIterator
>
1213 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
)
1216 // Parallelization still possible.
1217 random_shuffle(begin
, end
, r
);
1220 // Parallel algorithm for random access iterators.
1221 template<typename RandomAccessIterator
, typename RandomNumberGenerator
>
1223 random_shuffle(RandomAccessIterator begin
, RandomAccessIterator end
, RandomNumberGenerator
& rand
)
1227 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::random_shuffle_minimal_n
))
1228 __gnu_parallel::parallel_random_shuffle(begin
, end
, rand
);
1230 __gnu_parallel::sequential_random_shuffle(begin
, end
, rand
);
1233 // Sequential fallback.
1234 template<typename ForwardIterator
, typename Predicate
>
1235 inline ForwardIterator
1236 partition(ForwardIterator begin
, ForwardIterator end
, Predicate pred
, __gnu_parallel::sequential_tag
)
1237 { return _GLIBCXX_STD_P::partition(begin
, end
, pred
); }
1239 // Sequential fallback for input iterator case.
1240 template<typename ForwardIterator
, typename Predicate
, typename IteratorTag
>
1241 inline ForwardIterator
1242 partition_switch(ForwardIterator begin
, ForwardIterator end
, Predicate pred
, IteratorTag
)
1243 { return partition(begin
, end
, pred
, __gnu_parallel::sequential_tag()); }
1245 // Parallel algorithm for random access iterators.
1246 template<typename RandomAccessIterator
, typename Predicate
>
1247 RandomAccessIterator
1248 partition_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Predicate pred
, random_access_iterator_tag
)
1250 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::partition_minimal_n
))
1252 typedef typename
std::iterator_traits
<RandomAccessIterator
>::difference_type difference_type
;
1253 difference_type middle
= __gnu_parallel::parallel_partition(begin
, end
, pred
, __gnu_parallel::get_max_threads());
1254 return begin
+ middle
;
1257 return partition(begin
, end
, pred
, __gnu_parallel::sequential_tag());
1260 // Public interface.
1261 template<typename ForwardIterator
, typename Predicate
>
1262 inline ForwardIterator
1263 partition(ForwardIterator begin
, ForwardIterator end
, Predicate pred
)
1265 return partition_switch(begin
, end
, pred
, typename
std::iterator_traits
<ForwardIterator
>::iterator_category());
1268 // Sequential fallback
1269 template<typename RandomAccessIterator
>
1271 sort(RandomAccessIterator begin
, RandomAccessIterator end
, __gnu_parallel::sequential_tag
)
1272 { _GLIBCXX_STD_P::sort
<RandomAccessIterator
>(begin
, end
); }
1274 // Sequential fallback
1275 template<typename RandomAccessIterator
, typename Comparator
>
1277 sort(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
, __gnu_parallel::sequential_tag
)
1278 { _GLIBCXX_STD_P::sort
<RandomAccessIterator
, Comparator
>(begin
, end
, comp
); }
1280 // Public interface, insert default comparator
1281 template<typename RandomAccessIterator
>
1283 sort(RandomAccessIterator begin
, RandomAccessIterator end
)
1285 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1286 typedef typename
traits_type::value_type value_type
;
1287 sort(begin
, end
, std::less
<value_type
>());
1290 template<typename RandomAccessIterator
, typename Comparator
>
1292 sort(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
)
1294 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1295 typedef typename
traits_type::value_type value_type
;
1299 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::sort_minimal_n
))
1300 __gnu_parallel::parallel_sort(begin
, end
, comp
, false);
1302 sort
<RandomAccessIterator
, Comparator
>(begin
, end
, comp
, __gnu_parallel::sequential_tag());
1306 // Sequential fallback.
1307 template<typename RandomAccessIterator
>
1309 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
, __gnu_parallel::sequential_tag
)
1311 return _GLIBCXX_STD_P::stable_sort
<RandomAccessIterator
>(begin
, end
);
1314 // Sequential fallback.
1315 template<typename RandomAccessIterator
, typename Comparator
>
1317 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
, __gnu_parallel::sequential_tag
)
1319 return _GLIBCXX_STD_P::stable_sort
<RandomAccessIterator
, Comparator
>(begin
, end
, comp
);
1322 template<typename RandomAccessIterator
>
1324 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
)
1326 typedef iterator_traits
<RandomAccessIterator
> traits_type
;
1327 typedef typename
traits_type::value_type value_type
;
1329 stable_sort(begin
, end
, std::less
<value_type
>());
1332 // Parallel algorithm for random access iterators
1333 template<typename RandomAccessIterator
, typename Comparator
>
1335 stable_sort(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
)
1339 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::sort_minimal_n
))
1340 __gnu_parallel::parallel_sort(begin
, end
, comp
, true);
1342 stable_sort
<RandomAccessIterator
, Comparator
>(begin
, end
, comp
, __gnu_parallel::sequential_tag());
1346 // Sequential fallback
1347 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
1348 inline OutputIterator
1349 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator result
,
1350 __gnu_parallel::sequential_tag
)
1352 return _GLIBCXX_STD_P::merge(begin1
, end1
, begin2
, end2
, result
);
1355 // Sequential fallback
1356 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Comparator
>
1357 inline OutputIterator
1358 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator result
, Comparator comp
,
1359 __gnu_parallel::sequential_tag
)
1361 return _GLIBCXX_STD_P::merge(begin1
, end1
, begin2
, end2
, result
, comp
);
1364 // Sequential fallback for input iterator case
1365 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Comparator
, typename IteratorTag1
, typename IteratorTag2
, typename IteratorTag3
>
1366 inline OutputIterator
1367 merge_switch(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator result
, Comparator comp
, IteratorTag1
, IteratorTag2
, IteratorTag3
)
1369 return _GLIBCXX_STD_P::merge(begin1
, end1
, begin2
, end2
, result
, comp
);
1372 // Parallel algorithm for random access iterators
1373 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Comparator
>
1375 merge_switch(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator result
, Comparator comp
, random_access_iterator_tag
, random_access_iterator_tag
, random_access_iterator_tag
)
1377 if (_GLIBCXX_PARALLEL_CONDITION((static_cast<__gnu_parallel::sequence_index_t
>(end1
- begin1
) >= __gnu_parallel::Settings::merge_minimal_n
|| static_cast<__gnu_parallel::sequence_index_t
>(end2
- begin2
) >= __gnu_parallel::Settings::merge_minimal_n
)))
1378 return __gnu_parallel::parallel_merge_advance(begin1
, end1
, begin2
, end2
, result
, (end1
- begin1
) + (end2
- begin2
), comp
);
1380 return __gnu_parallel::merge_advance(begin1
, end1
, begin2
, end2
, result
, (end1
- begin1
) + (end2
- begin2
), comp
);
1384 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
, typename Comparator
>
1385 inline OutputIterator
1386 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator result
, Comparator comp
)
1388 typedef typename iterator_traits
<InputIterator1
>::value_type value_type
;
1390 typedef std::iterator_traits
<InputIterator1
> iteratori1_traits
;
1391 typedef std::iterator_traits
<InputIterator2
> iteratori2_traits
;
1392 typedef std::iterator_traits
<OutputIterator
> iteratoro_traits
;
1393 typedef typename
iteratori1_traits::iterator_category iteratori1_category
;
1394 typedef typename
iteratori2_traits::iterator_category iteratori2_category
;
1395 typedef typename
iteratoro_traits::iterator_category iteratoro_category
;
1397 return merge_switch(begin1
, end1
, begin2
, end2
, result
, comp
, iteratori1_category(), iteratori2_category(), iteratoro_category());
1401 // Public interface, insert default comparator
1402 template<typename InputIterator1
, typename InputIterator2
, typename OutputIterator
>
1403 inline OutputIterator
1404 merge(InputIterator1 begin1
, InputIterator1 end1
, InputIterator2 begin2
, InputIterator2 end2
, OutputIterator result
)
1406 typedef std::iterator_traits
<InputIterator1
> iterator1_traits
;
1407 typedef std::iterator_traits
<InputIterator2
> iterator2_traits
;
1408 typedef typename
iterator1_traits::value_type value1_type
;
1409 typedef typename
iterator2_traits::value_type value2_type
;
1411 return merge(begin1
, end1
, begin2
, end2
, result
, __gnu_parallel::less
<value1_type
, value2_type
>());
1414 // Sequential fallback
1415 template<typename RandomAccessIterator
>
1417 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
, RandomAccessIterator end
, __gnu_parallel::sequential_tag
)
1418 { return _GLIBCXX_STD_P::nth_element(begin
, nth
, end
); }
1420 // Sequential fallback
1421 template<typename RandomAccessIterator
, typename Comparator
>
1423 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
, RandomAccessIterator end
, Comparator comp
, __gnu_parallel::sequential_tag
)
1424 { return _GLIBCXX_STD_P::nth_element(begin
, nth
, end
, comp
); }
1427 template<typename RandomAccessIterator
, typename Comparator
>
1429 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
, RandomAccessIterator end
, Comparator comp
)
1431 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::nth_element_minimal_n
))
1432 __gnu_parallel::parallel_nth_element(begin
, nth
, end
, comp
);
1434 nth_element(begin
, nth
, end
, comp
, __gnu_parallel::sequential_tag());
1437 // Public interface, insert default comparator
1438 template<typename RandomAccessIterator
>
1440 nth_element(RandomAccessIterator begin
, RandomAccessIterator nth
, RandomAccessIterator end
)
1442 typedef typename iterator_traits
<RandomAccessIterator
>::value_type value_type
;
1443 nth_element(begin
, nth
, end
, std::less
<value_type
>());
1446 // Sequential fallback
1447 template<typename _RandomAccessIterator
, typename _Compare
>
1449 partial_sort(_RandomAccessIterator begin
, _RandomAccessIterator middle
, _RandomAccessIterator end
, _Compare comp
, __gnu_parallel::sequential_tag
)
1450 { _GLIBCXX_STD_P::partial_sort(begin
, middle
, end
, comp
); }
1452 // Sequential fallback
1453 template<typename _RandomAccessIterator
>
1455 partial_sort(_RandomAccessIterator begin
, _RandomAccessIterator middle
, _RandomAccessIterator end
, __gnu_parallel::sequential_tag
)
1456 { _GLIBCXX_STD_P::partial_sort(begin
, middle
, end
); }
1458 // Public interface, parallel algorithm for random access iterators
1459 template<typename _RandomAccessIterator
, typename _Compare
>
1461 partial_sort(_RandomAccessIterator begin
, _RandomAccessIterator middle
, _RandomAccessIterator end
, _Compare comp
)
1463 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::partial_sort_minimal_n
))
1464 __gnu_parallel::parallel_partial_sort(begin
, middle
, end
, comp
);
1466 partial_sort(begin
, middle
, end
, comp
, __gnu_parallel::sequential_tag());
1469 // Public interface, insert default comparator
1470 template<typename _RandomAccessIterator
>
1472 partial_sort(_RandomAccessIterator begin
, _RandomAccessIterator middle
, _RandomAccessIterator end
)
1474 typedef typename iterator_traits
<_RandomAccessIterator
>::value_type value_type
;
1475 partial_sort(begin
, middle
, end
, std::less
<value_type
>());
1478 // Sequential fallback
1479 template<typename ForwardIterator
>
1480 inline ForwardIterator
1481 max_element(ForwardIterator begin
, ForwardIterator end
, __gnu_parallel::sequential_tag
)
1482 { return _GLIBCXX_STD_P::max_element(begin
, end
); }
1484 // Sequential fallback
1485 template<typename ForwardIterator
, typename Comparator
>
1486 inline ForwardIterator
1487 max_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
, __gnu_parallel::sequential_tag
)
1488 { return _GLIBCXX_STD_P::max_element(begin
, end
, comp
); }
1490 // Sequential fallback for input iterator case
1491 template<typename ForwardIterator
, typename Comparator
, typename IteratorTag
>
1493 max_element_switch(ForwardIterator begin
, ForwardIterator end
, Comparator comp
, IteratorTag
, __gnu_parallel::parallelism parallelism_tag
)
1494 { return max_element(begin
, end
, comp
, __gnu_parallel::sequential_tag()); }
1496 // Public interface, insert default comparator
1497 template<typename ForwardIterator
>
1498 inline ForwardIterator
1499 max_element(ForwardIterator begin
, ForwardIterator end
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1501 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
1502 return max_element(begin
, end
, std::less
<value_type
>(), parallelism_tag
);
1505 template<typename RandomAccessIterator
, typename Comparator
>
1506 RandomAccessIterator
1507 max_element_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
1509 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::max_element_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
1511 RandomAccessIterator
res(begin
);
1512 __gnu_parallel::identity_selector
<RandomAccessIterator
> functionality
;
1513 __gnu_parallel::for_each_template_random_access(begin
, end
, __gnu_parallel::nothing(), functionality
, __gnu_parallel::max_element_reduct
<Comparator
, RandomAccessIterator
>(comp
), res
, res
, -1, parallelism_tag
);
1517 return max_element(begin
, end
, __gnu_parallel::sequential_tag());
1521 template<typename ForwardIterator
, typename Comparator
>
1522 inline ForwardIterator
1523 max_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1525 return max_element_switch(begin
, end
, comp
, typename
std::iterator_traits
<ForwardIterator
>::iterator_category(), parallelism_tag
);
1528 // Sequential fallback
1529 template<typename ForwardIterator
>
1532 min_element(ForwardIterator begin
, ForwardIterator end
, __gnu_parallel::sequential_tag
)
1533 { return _GLIBCXX_STD_P::min_element(begin
, end
); }
1535 // Sequential fallback
1536 template<typename ForwardIterator
, typename Comparator
>
1537 inline ForwardIterator
1538 min_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
, __gnu_parallel::sequential_tag
)
1539 { return _GLIBCXX_STD_P::min_element(begin
, end
, comp
); }
1542 template<typename ForwardIterator
>
1543 inline ForwardIterator
1544 min_element(ForwardIterator begin
, ForwardIterator end
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1546 typedef typename iterator_traits
<ForwardIterator
>::value_type value_type
;
1547 return min_element(begin
, end
, std::less
<value_type
>(), parallelism_tag
);
1550 // Sequential fallback for input iterator case
1551 template<typename ForwardIterator
, typename Comparator
, typename IteratorTag
>
1553 min_element_switch(ForwardIterator begin
, ForwardIterator end
, Comparator comp
, IteratorTag
, __gnu_parallel::parallelism parallelism_tag
)
1554 { return min_element(begin
, end
, comp
, __gnu_parallel::sequential_tag()); }
1556 // Parallel algorithm for random access iterators
1557 template<typename RandomAccessIterator
, typename Comparator
>
1558 RandomAccessIterator
1559 min_element_switch(RandomAccessIterator begin
, RandomAccessIterator end
, Comparator comp
, random_access_iterator_tag
, __gnu_parallel::parallelism parallelism_tag
)
1561 if (_GLIBCXX_PARALLEL_CONDITION(static_cast<__gnu_parallel::sequence_index_t
>(end
- begin
) >= __gnu_parallel::Settings::min_element_minimal_n
&& __gnu_parallel::is_parallel(parallelism_tag
)))
1563 RandomAccessIterator
res(begin
);
1564 __gnu_parallel::identity_selector
<RandomAccessIterator
> functionality
;
1565 __gnu_parallel::for_each_template_random_access(begin
, end
, __gnu_parallel::nothing(), functionality
, __gnu_parallel::min_element_reduct
<Comparator
, RandomAccessIterator
>(comp
), res
, res
, -1, parallelism_tag
);
1569 return min_element(begin
, end
, __gnu_parallel::sequential_tag());
1573 template<typename ForwardIterator
, typename Comparator
>
1574 inline ForwardIterator
1575 min_element(ForwardIterator begin
, ForwardIterator end
, Comparator comp
, __gnu_parallel::parallelism parallelism_tag
= __gnu_parallel::parallel_balanced
)
1577 typedef iterator_traits
<ForwardIterator
> traits_type
;
1578 typedef typename
traits_type::iterator_category iterator_category
;
1579 return min_element_switch(begin
, end
, comp
, iterator_category(), parallelism_tag
);
1584 #endif /* _GLIBCXX_ALGORITHM_H */