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