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