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