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