Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/11/bits/ranges_algo.h
$ cat -n /usr/include/c++/11/bits/ranges_algo.h 1 // Core algorithmic facilities -*- C++ -*- 2 3 // Copyright (C) 2020-2021 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 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU 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 //
. 24 25 /** @file bits/ranges_algo.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{algorithm} 28 */ 29 30 #ifndef _RANGES_ALGO_H 31 #define _RANGES_ALGO_H 1 32 33 #if __cplusplus > 201703L 34 35 #include
36 #include
37 #include
// concept uniform_random_bit_generator 38 39 #if __cpp_lib_concepts 40 namespace std _GLIBCXX_VISIBILITY(default) 41 { 42 _GLIBCXX_BEGIN_NAMESPACE_VERSION 43 namespace ranges 44 { 45 namespace __detail 46 { 47 template
48 constexpr auto 49 __make_comp_proj(_Comp& __comp, _Proj& __proj) 50 { 51 return [&] (auto&& __lhs, auto&& __rhs) -> bool { 52 using _TL = decltype(__lhs); 53 using _TR = decltype(__rhs); 54 return std::__invoke(__comp, 55 std::__invoke(__proj, std::forward<_TL>(__lhs)), 56 std::__invoke(__proj, std::forward<_TR>(__rhs))); 57 }; 58 } 59 60 template
61 constexpr auto 62 __make_pred_proj(_Pred& __pred, _Proj& __proj) 63 { 64 return [&]
(_Tp&& __arg) -> bool { 65 return std::__invoke(__pred, 66 std::__invoke(__proj, std::forward<_Tp>(__arg))); 67 }; 68 } 69 } // namespace __detail 70 71 struct __all_of_fn 72 { 73 template
_Sent, 74 typename _Proj = identity, 75 indirect_unary_predicate
> _Pred> 76 constexpr bool 77 operator()(_Iter __first, _Sent __last, 78 _Pred __pred, _Proj __proj = {}) const 79 { 80 for (; __first != __last; ++__first) 81 if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first))) 82 return false; 83 return true; 84 } 85 86 template
, _Proj>> 88 _Pred> 89 constexpr bool 90 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 91 { 92 return (*this)(ranges::begin(__r), ranges::end(__r), 93 std::move(__pred), std::move(__proj)); 94 } 95 }; 96 97 inline constexpr __all_of_fn all_of{}; 98 99 struct __any_of_fn 100 { 101 template
_Sent, 102 typename _Proj = identity, 103 indirect_unary_predicate
> _Pred> 104 constexpr bool 105 operator()(_Iter __first, _Sent __last, 106 _Pred __pred, _Proj __proj = {}) const 107 { 108 for (; __first != __last; ++__first) 109 if (std::__invoke(__pred, std::__invoke(__proj, *__first))) 110 return true; 111 return false; 112 } 113 114 template
, _Proj>> 116 _Pred> 117 constexpr bool 118 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 119 { 120 return (*this)(ranges::begin(__r), ranges::end(__r), 121 std::move(__pred), std::move(__proj)); 122 } 123 }; 124 125 inline constexpr __any_of_fn any_of{}; 126 127 struct __none_of_fn 128 { 129 template
_Sent, 130 typename _Proj = identity, 131 indirect_unary_predicate
> _Pred> 132 constexpr bool 133 operator()(_Iter __first, _Sent __last, 134 _Pred __pred, _Proj __proj = {}) const 135 { 136 for (; __first != __last; ++__first) 137 if (std::__invoke(__pred, std::__invoke(__proj, *__first))) 138 return false; 139 return true; 140 } 141 142 template
, _Proj>> 144 _Pred> 145 constexpr bool 146 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 147 { 148 return (*this)(ranges::begin(__r), ranges::end(__r), 149 std::move(__pred), std::move(__proj)); 150 } 151 }; 152 153 inline constexpr __none_of_fn none_of{}; 154 155 template
156 struct in_fun_result 157 { 158 [[no_unique_address]] _Iter in; 159 [[no_unique_address]] _Fp fun; 160 161 template
162 requires convertible_to
163 && convertible_to
164 constexpr 165 operator in_fun_result<_Iter2, _F2p>() const & 166 { return {in, fun}; } 167 168 template
169 requires convertible_to<_Iter, _Iter2> && convertible_to<_Fp, _F2p> 170 constexpr 171 operator in_fun_result<_Iter2, _F2p>() && 172 { return {std::move(in), std::move(fun)}; } 173 }; 174 175 template
176 using for_each_result = in_fun_result<_Iter, _Fp>; 177 178 struct __for_each_fn 179 { 180 template
_Sent, 181 typename _Proj = identity, 182 indirectly_unary_invocable
> _Fun> 183 constexpr for_each_result<_Iter, _Fun> 184 operator()(_Iter __first, _Sent __last, _Fun __f, _Proj __proj = {}) const 185 { 186 for (; __first != __last; ++__first) 187 std::__invoke(__f, std::__invoke(__proj, *__first)); 188 return { std::move(__first), std::move(__f) }; 189 } 190 191 template
, _Proj>> 193 _Fun> 194 constexpr for_each_result
, _Fun> 195 operator()(_Range&& __r, _Fun __f, _Proj __proj = {}) const 196 { 197 return (*this)(ranges::begin(__r), ranges::end(__r), 198 std::move(__f), std::move(__proj)); 199 } 200 }; 201 202 inline constexpr __for_each_fn for_each{}; 203 204 template
205 using for_each_n_result = in_fun_result<_Iter, _Fp>; 206 207 struct __for_each_n_fn 208 { 209 template
> _Fun> 211 constexpr for_each_n_result<_Iter, _Fun> 212 operator()(_Iter __first, iter_difference_t<_Iter> __n, 213 _Fun __f, _Proj __proj = {}) const 214 { 215 if constexpr (random_access_iterator<_Iter>) 216 { 217 if (__n <= 0) 218 return {std::move(__first), std::move(__f)}; 219 auto __last = __first + __n; 220 return ranges::for_each(std::move(__first), std::move(__last), 221 std::move(__f), std::move(__proj)); 222 } 223 else 224 { 225 while (__n-- > 0) 226 { 227 std::__invoke(__f, std::__invoke(__proj, *__first)); 228 ++__first; 229 } 230 return {std::move(__first), std::move(__f)}; 231 } 232 } 233 }; 234 235 inline constexpr __for_each_n_fn for_each_n{}; 236 237 // find, find_if and find_if_not are defined in
. 238 239 struct __find_first_of_fn 240 { 241 template
_Sent1, 242 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, 243 typename _Pred = ranges::equal_to, 244 typename _Proj1 = identity, typename _Proj2 = identity> 245 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> 246 constexpr _Iter1 247 operator()(_Iter1 __first1, _Sent1 __last1, 248 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {}, 249 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 250 { 251 for (; __first1 != __last1; ++__first1) 252 for (auto __iter = __first2; __iter != __last2; ++__iter) 253 if (std::__invoke(__pred, 254 std::__invoke(__proj1, *__first1), 255 std::__invoke(__proj2, *__iter))) 256 return __first1; 257 return __first1; 258 } 259 260 template
263 requires indirectly_comparable
, iterator_t<_Range2>, 264 _Pred, _Proj1, _Proj2> 265 constexpr borrowed_iterator_t<_Range1> 266 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, 267 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 268 { 269 return (*this)(ranges::begin(__r1), ranges::end(__r1), 270 ranges::begin(__r2), ranges::end(__r2), 271 std::move(__pred), 272 std::move(__proj1), std::move(__proj2)); 273 } 274 }; 275 276 inline constexpr __find_first_of_fn find_first_of{}; 277 278 struct __count_fn 279 { 280 template
_Sent, 281 typename _Tp, typename _Proj = identity> 282 requires indirect_binary_predicate
, 284 const _Tp*> 285 constexpr iter_difference_t<_Iter> 286 operator()(_Iter __first, _Sent __last, 287 const _Tp& __value, _Proj __proj = {}) const 288 { 289 iter_difference_t<_Iter> __n = 0; 290 for (; __first != __last; ++__first) 291 if (std::__invoke(__proj, *__first) == __value) 292 ++__n; 293 return __n; 294 } 295 296 template
297 requires indirect_binary_predicate
, _Proj>, 299 const _Tp*> 300 constexpr range_difference_t<_Range> 301 operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const 302 { 303 return (*this)(ranges::begin(__r), ranges::end(__r), 304 __value, std::move(__proj)); 305 } 306 }; 307 308 inline constexpr __count_fn count{}; 309 310 struct __count_if_fn 311 { 312 template
_Sent, 313 typename _Proj = identity, 314 indirect_unary_predicate
> _Pred> 315 constexpr iter_difference_t<_Iter> 316 operator()(_Iter __first, _Sent __last, 317 _Pred __pred, _Proj __proj = {}) const 318 { 319 iter_difference_t<_Iter> __n = 0; 320 for (; __first != __last; ++__first) 321 if (std::__invoke(__pred, std::__invoke(__proj, *__first))) 322 ++__n; 323 return __n; 324 } 325 326 template
, _Proj>> 329 _Pred> 330 constexpr range_difference_t<_Range> 331 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 332 { 333 return (*this)(ranges::begin(__r), ranges::end(__r), 334 std::move(__pred), std::move(__proj)); 335 } 336 }; 337 338 inline constexpr __count_if_fn count_if{}; 339 340 // in_in_result, mismatch and search are defined in
. 341 342 struct __search_n_fn 343 { 344 template
_Sent, typename _Tp, 345 typename _Pred = ranges::equal_to, typename _Proj = identity> 346 requires indirectly_comparable<_Iter, const _Tp*, _Pred, _Proj> 347 constexpr subrange<_Iter> 348 operator()(_Iter __first, _Sent __last, iter_difference_t<_Iter> __count, 349 const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const 350 { 351 if (__count <= 0) 352 return {__first, __first}; 353 354 auto __value_comp = [&]
(_Rp&& __arg) -> bool { 355 return std::__invoke(__pred, std::forward<_Rp>(__arg), __value); 356 }; 357 if (__count == 1) 358 { 359 __first = ranges::find_if(std::move(__first), __last, 360 std::move(__value_comp), 361 std::move(__proj)); 362 if (__first == __last) 363 return {__first, __first}; 364 else 365 { 366 auto __end = __first; 367 return {__first, ++__end}; 368 } 369 } 370 371 if constexpr (sized_sentinel_for<_Sent, _Iter> 372 && random_access_iterator<_Iter>) 373 { 374 auto __tail_size = __last - __first; 375 auto __remainder = __count; 376 377 while (__remainder <= __tail_size) 378 { 379 __first += __remainder; 380 __tail_size -= __remainder; 381 auto __backtrack = __first; 382 while (__value_comp(std::__invoke(__proj, *--__backtrack))) 383 { 384 if (--__remainder == 0) 385 return {__first - __count, __first}; 386 } 387 __remainder = __count + 1 - (__first - __backtrack); 388 } 389 auto __i = __first + __tail_size; 390 return {__i, __i}; 391 } 392 else 393 { 394 __first = ranges::find_if(__first, __last, __value_comp, __proj); 395 while (__first != __last) 396 { 397 auto __n = __count; 398 auto __i = __first; 399 ++__i; 400 while (__i != __last && __n != 1 401 && __value_comp(std::__invoke(__proj, *__i))) 402 { 403 ++__i; 404 --__n; 405 } 406 if (__n == 1) 407 return {__first, __i}; 408 if (__i == __last) 409 return {__i, __i}; 410 __first = ranges::find_if(++__i, __last, __value_comp, __proj); 411 } 412 return {__first, __first}; 413 } 414 } 415 416 template
418 requires indirectly_comparable
, const _Tp*, 419 _Pred, _Proj> 420 constexpr borrowed_subrange_t<_Range> 421 operator()(_Range&& __r, range_difference_t<_Range> __count, 422 const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const 423 { 424 return (*this)(ranges::begin(__r), ranges::end(__r), 425 std::move(__count), __value, 426 std::move(__pred), std::move(__proj)); 427 } 428 }; 429 430 inline constexpr __search_n_fn search_n{}; 431 432 struct __find_end_fn 433 { 434 template
_Sent1, 435 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, 436 typename _Pred = ranges::equal_to, 437 typename _Proj1 = identity, typename _Proj2 = identity> 438 requires indirectly_comparable<_Iter1, _Iter2, _Pred, _Proj1, _Proj2> 439 constexpr subrange<_Iter1> 440 operator()(_Iter1 __first1, _Sent1 __last1, 441 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {}, 442 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 443 { 444 if constexpr (bidirectional_iterator<_Iter1> 445 && bidirectional_iterator<_Iter2>) 446 { 447 auto __i1 = ranges::next(__first1, __last1); 448 auto __i2 = ranges::next(__first2, __last2); 449 auto __rresult 450 = ranges::search(reverse_iterator<_Iter1>{__i1}, 451 reverse_iterator<_Iter1>{__first1}, 452 reverse_iterator<_Iter2>{__i2}, 453 reverse_iterator<_Iter2>{__first2}, 454 std::move(__pred), 455 std::move(__proj1), std::move(__proj2)); 456 auto __result_first = ranges::end(__rresult).base(); 457 auto __result_last = ranges::begin(__rresult).base(); 458 if (__result_last == __first1) 459 return {__i1, __i1}; 460 else 461 return {__result_first, __result_last}; 462 } 463 else 464 { 465 auto __i = ranges::next(__first1, __last1); 466 if (__first2 == __last2) 467 return {__i, __i}; 468 469 auto __result_begin = __i; 470 auto __result_end = __i; 471 for (;;) 472 { 473 auto __new_range = ranges::search(__first1, __last1, 474 __first2, __last2, 475 __pred, __proj1, __proj2); 476 auto __new_result_begin = ranges::begin(__new_range); 477 auto __new_result_end = ranges::end(__new_range); 478 if (__new_result_begin == __last1) 479 return {__result_begin, __result_end}; 480 else 481 { 482 __result_begin = __new_result_begin; 483 __result_end = __new_result_end; 484 __first1 = __result_begin; 485 ++__first1; 486 } 487 } 488 } 489 } 490 491 template
494 requires indirectly_comparable
, iterator_t<_Range2>, 495 _Pred, _Proj1, _Proj2> 496 constexpr borrowed_subrange_t<_Range1> 497 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, 498 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 499 { 500 return (*this)(ranges::begin(__r1), ranges::end(__r1), 501 ranges::begin(__r2), ranges::end(__r2), 502 std::move(__pred), 503 std::move(__proj1), std::move(__proj2)); 504 } 505 }; 506 507 inline constexpr __find_end_fn find_end{}; 508 509 struct __adjacent_find_fn 510 { 511 template
_Sent, 512 typename _Proj = identity, 513 indirect_binary_predicate
, 514 projected<_Iter, _Proj>> _Pred 515 = ranges::equal_to> 516 constexpr _Iter 517 operator()(_Iter __first, _Sent __last, 518 _Pred __pred = {}, _Proj __proj = {}) const 519 { 520 if (__first == __last) 521 return __first; 522 auto __next = __first; 523 for (; ++__next != __last; __first = __next) 524 { 525 if (std::__invoke(__pred, 526 std::__invoke(__proj, *__first), 527 std::__invoke(__proj, *__next))) 528 return __first; 529 } 530 return __next; 531 } 532 533 template
, _Proj>, 536 projected
, _Proj>> _Pred = ranges::equal_to> 537 constexpr borrowed_iterator_t<_Range> 538 operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const 539 { 540 return (*this)(ranges::begin(__r), ranges::end(__r), 541 std::move(__pred), std::move(__proj)); 542 } 543 }; 544 545 inline constexpr __adjacent_find_fn adjacent_find{}; 546 547 struct __is_permutation_fn 548 { 549 template
_Sent1, 550 forward_iterator _Iter2, sentinel_for<_Iter2> _Sent2, 551 typename _Proj1 = identity, typename _Proj2 = identity, 552 indirect_equivalence_relation
, 553 projected<_Iter2, _Proj2>> _Pred 554 = ranges::equal_to> 555 constexpr bool 556 operator()(_Iter1 __first1, _Sent1 __last1, 557 _Iter2 __first2, _Sent2 __last2, _Pred __pred = {}, 558 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 559 { 560 constexpr bool __sized_iters 561 = (sized_sentinel_for<_Sent1, _Iter1> 562 && sized_sentinel_for<_Sent2, _Iter2>); 563 if constexpr (__sized_iters) 564 { 565 auto __d1 = ranges::distance(__first1, __last1); 566 auto __d2 = ranges::distance(__first2, __last2); 567 if (__d1 != __d2) 568 return false; 569 } 570 571 // Efficiently compare identical prefixes: O(N) if sequences 572 // have the same elements in the same order. 573 for (; __first1 != __last1 && __first2 != __last2; 574 ++__first1, (void)++__first2) 575 if (!(bool)std::__invoke(__pred, 576 std::__invoke(__proj1, *__first1), 577 std::__invoke(__proj2, *__first2))) 578 break; 579 580 if constexpr (__sized_iters) 581 { 582 if (__first1 == __last1) 583 return true; 584 } 585 else 586 { 587 auto __d1 = ranges::distance(__first1, __last1); 588 auto __d2 = ranges::distance(__first2, __last2); 589 if (__d1 == 0 && __d2 == 0) 590 return true; 591 if (__d1 != __d2) 592 return false; 593 } 594 595 for (auto __scan = __first1; __scan != __last1; ++__scan) 596 { 597 auto&& __proj_scan = std::__invoke(__proj1, *__scan); 598 auto __comp_scan = [&]
(_Tp&& __arg) -> bool { 599 return std::__invoke(__pred, __proj_scan, 600 std::forward<_Tp>(__arg)); 601 }; 602 if (__scan != ranges::find_if(__first1, __scan, 603 __comp_scan, __proj1)) 604 continue; // We've seen this one before. 605 606 auto __matches = ranges::count_if(__first2, __last2, 607 __comp_scan, __proj2); 608 if (__matches == 0 609 || ranges::count_if(__scan, __last1, 610 __comp_scan, __proj1) != __matches) 611 return false; 612 } 613 return true; 614 } 615 616 template
, _Proj1>, 620 projected
, _Proj2>> _Pred = ranges::equal_to> 621 constexpr bool 622 operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {}, 623 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 624 { 625 return (*this)(ranges::begin(__r1), ranges::end(__r1), 626 ranges::begin(__r2), ranges::end(__r2), 627 std::move(__pred), 628 std::move(__proj1), std::move(__proj2)); 629 } 630 }; 631 632 inline constexpr __is_permutation_fn is_permutation{}; 633 634 template
635 using copy_if_result = in_out_result<_Iter, _Out>; 636 637 struct __copy_if_fn 638 { 639 template
_Sent, 640 weakly_incrementable _Out, typename _Proj = identity, 641 indirect_unary_predicate
> _Pred> 642 requires indirectly_copyable<_Iter, _Out> 643 constexpr copy_if_result<_Iter, _Out> 644 operator()(_Iter __first, _Sent __last, _Out __result, 645 _Pred __pred, _Proj __proj = {}) const 646 { 647 for (; __first != __last; ++__first) 648 if (std::__invoke(__pred, std::__invoke(__proj, *__first))) 649 { 650 *__result = *__first; 651 ++__result; 652 } 653 return {std::move(__first), std::move(__result)}; 654 } 655 656 template
, _Proj>> 659 _Pred> 660 requires indirectly_copyable
, _Out> 661 constexpr copy_if_result
, _Out> 662 operator()(_Range&& __r, _Out __result, 663 _Pred __pred, _Proj __proj = {}) const 664 { 665 return (*this)(ranges::begin(__r), ranges::end(__r), 666 std::move(__result), 667 std::move(__pred), std::move(__proj)); 668 } 669 }; 670 671 inline constexpr __copy_if_fn copy_if{}; 672 673 template
674 using swap_ranges_result = in_in_result<_Iter1, _Iter2>; 675 676 struct __swap_ranges_fn 677 { 678 template
_Sent1, 679 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2> 680 requires indirectly_swappable<_Iter1, _Iter2> 681 constexpr swap_ranges_result<_Iter1, _Iter2> 682 operator()(_Iter1 __first1, _Sent1 __last1, 683 _Iter2 __first2, _Sent2 __last2) const 684 { 685 for (; __first1 != __last1 && __first2 != __last2; 686 ++__first1, (void)++__first2) 687 ranges::iter_swap(__first1, __first2); 688 return {std::move(__first1), std::move(__first2)}; 689 } 690 691 template
692 requires indirectly_swappable
, iterator_t<_Range2>> 693 constexpr swap_ranges_result
, 694 borrowed_iterator_t<_Range2>> 695 operator()(_Range1&& __r1, _Range2&& __r2) const 696 { 697 return (*this)(ranges::begin(__r1), ranges::end(__r1), 698 ranges::begin(__r2), ranges::end(__r2)); 699 } 700 }; 701 702 inline constexpr __swap_ranges_fn swap_ranges{}; 703 704 template
705 using unary_transform_result = in_out_result<_Iter, _Out>; 706 707 template
708 struct in_in_out_result 709 { 710 [[no_unique_address]] _Iter1 in1; 711 [[no_unique_address]] _Iter2 in2; 712 [[no_unique_address]] _Out out; 713 714 template
715 requires convertible_to
716 && convertible_to
717 && convertible_to
718 constexpr 719 operator in_in_out_result<_IIter1, _IIter2, _OOut>() const & 720 { return {in1, in2, out}; } 721 722 template
723 requires convertible_to<_Iter1, _IIter1> 724 && convertible_to<_Iter2, _IIter2> 725 && convertible_to<_Out, _OOut> 726 constexpr 727 operator in_in_out_result<_IIter1, _IIter2, _OOut>() && 728 { return {std::move(in1), std::move(in2), std::move(out)}; } 729 }; 730 731 template
732 using binary_transform_result = in_in_out_result<_Iter1, _Iter2, _Out>; 733 734 struct __transform_fn 735 { 736 template
_Sent, 737 weakly_incrementable _Out, 738 copy_constructible _Fp, typename _Proj = identity> 739 requires indirectly_writable<_Out, 740 indirect_result_t<_Fp&, 741 projected<_Iter, _Proj>>> 742 constexpr unary_transform_result<_Iter, _Out> 743 operator()(_Iter __first1, _Sent __last1, _Out __result, 744 _Fp __op, _Proj __proj = {}) const 745 { 746 for (; __first1 != __last1; ++__first1, (void)++__result) 747 *__result = std::__invoke(__op, std::__invoke(__proj, *__first1)); 748 return {std::move(__first1), std::move(__result)}; 749 } 750 751 template
753 requires indirectly_writable<_Out, 754 indirect_result_t<_Fp&, 755 projected
, _Proj>>> 756 constexpr unary_transform_result
, _Out> 757 operator()(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) const 758 { 759 return (*this)(ranges::begin(__r), ranges::end(__r), 760 std::move(__result), 761 std::move(__op), std::move(__proj)); 762 } 763 764 template
_Sent1, 765 input_iterator _Iter2, sentinel_for<_Iter2> _Sent2, 766 weakly_incrementable _Out, copy_constructible _Fp, 767 typename _Proj1 = identity, typename _Proj2 = identity> 768 requires indirectly_writable<_Out, 769 indirect_result_t<_Fp&, 770 projected<_Iter1, _Proj1>, 771 projected<_Iter2, _Proj2>>> 772 constexpr binary_transform_result<_Iter1, _Iter2, _Out> 773 operator()(_Iter1 __first1, _Sent1 __last1, 774 _Iter2 __first2, _Sent2 __last2, 775 _Out __result, _Fp __binary_op, 776 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 777 { 778 for (; __first1 != __last1 && __first2 != __last2; 779 ++__first1, (void)++__first2, ++__result) 780 *__result = std::__invoke(__binary_op, 781 std::__invoke(__proj1, *__first1), 782 std::__invoke(__proj2, *__first2)); 783 return {std::move(__first1), std::move(__first2), std::move(__result)}; 784 } 785 786 template
789 requires indirectly_writable<_Out, 790 indirect_result_t<_Fp&, 791 projected
, _Proj1>, 792 projected
, _Proj2>>> 793 constexpr binary_transform_result
, 794 borrowed_iterator_t<_Range2>, _Out> 795 operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Fp __binary_op, 796 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 797 { 798 return (*this)(ranges::begin(__r1), ranges::end(__r1), 799 ranges::begin(__r2), ranges::end(__r2), 800 std::move(__result), std::move(__binary_op), 801 std::move(__proj1), std::move(__proj2)); 802 } 803 }; 804 805 inline constexpr __transform_fn transform{}; 806 807 struct __replace_fn 808 { 809 template
_Sent, 810 typename _Tp1, typename _Tp2, typename _Proj = identity> 811 requires indirectly_writable<_Iter, const _Tp2&> 812 && indirect_binary_predicate
, 813 const _Tp1*> 814 constexpr _Iter 815 operator()(_Iter __first, _Sent __last, 816 const _Tp1& __old_value, const _Tp2& __new_value, 817 _Proj __proj = {}) const 818 { 819 for (; __first != __last; ++__first) 820 if (std::__invoke(__proj, *__first) == __old_value) 821 *__first = __new_value; 822 return __first; 823 } 824 825 template
827 requires indirectly_writable
, const _Tp2&> 828 && indirect_binary_predicate
, _Proj>, 830 const _Tp1*> 831 constexpr borrowed_iterator_t<_Range> 832 operator()(_Range&& __r, 833 const _Tp1& __old_value, const _Tp2& __new_value, 834 _Proj __proj = {}) const 835 { 836 return (*this)(ranges::begin(__r), ranges::end(__r), 837 __old_value, __new_value, std::move(__proj)); 838 } 839 }; 840 841 inline constexpr __replace_fn replace{}; 842 843 struct __replace_if_fn 844 { 845 template
_Sent, 846 typename _Tp, typename _Proj = identity, 847 indirect_unary_predicate
> _Pred> 848 requires indirectly_writable<_Iter, const _Tp&> 849 constexpr _Iter 850 operator()(_Iter __first, _Sent __last, 851 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const 852 { 853 for (; __first != __last; ++__first) 854 if (std::__invoke(__pred, std::__invoke(__proj, *__first))) 855 *__first = __new_value; 856 return std::move(__first); 857 } 858 859 template
, _Proj>> 861 _Pred> 862 requires indirectly_writable
, const _Tp&> 863 constexpr borrowed_iterator_t<_Range> 864 operator()(_Range&& __r, 865 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const 866 { 867 return (*this)(ranges::begin(__r), ranges::end(__r), 868 std::move(__pred), __new_value, std::move(__proj)); 869 } 870 }; 871 872 inline constexpr __replace_if_fn replace_if{}; 873 874 template
875 using replace_copy_result = in_out_result<_Iter, _Out>; 876 877 struct __replace_copy_fn 878 { 879 template
_Sent, 880 typename _Tp1, typename _Tp2, output_iterator
_Out, 881 typename _Proj = identity> 882 requires indirectly_copyable<_Iter, _Out> 883 && indirect_binary_predicate
, const _Tp1*> 885 constexpr replace_copy_result<_Iter, _Out> 886 operator()(_Iter __first, _Sent __last, _Out __result, 887 const _Tp1& __old_value, const _Tp2& __new_value, 888 _Proj __proj = {}) const 889 { 890 for (; __first != __last; ++__first, (void)++__result) 891 if (std::__invoke(__proj, *__first) == __old_value) 892 *__result = __new_value; 893 else 894 *__result = *__first; 895 return {std::move(__first), std::move(__result)}; 896 } 897 898 template
_Out, typename _Proj = identity> 900 requires indirectly_copyable
, _Out> 901 && indirect_binary_predicate
, _Proj>, 903 const _Tp1*> 904 constexpr replace_copy_result
, _Out> 905 operator()(_Range&& __r, _Out __result, 906 const _Tp1& __old_value, const _Tp2& __new_value, 907 _Proj __proj = {}) const 908 { 909 return (*this)(ranges::begin(__r), ranges::end(__r), 910 std::move(__result), __old_value, 911 __new_value, std::move(__proj)); 912 } 913 }; 914 915 inline constexpr __replace_copy_fn replace_copy{}; 916 917 template
918 using replace_copy_if_result = in_out_result<_Iter, _Out>; 919 920 struct __replace_copy_if_fn 921 { 922 template
_Sent, 923 typename _Tp, output_iterator
_Out, 924 typename _Proj = identity, 925 indirect_unary_predicate
> _Pred> 926 requires indirectly_copyable<_Iter, _Out> 927 constexpr replace_copy_if_result<_Iter, _Out> 928 operator()(_Iter __first, _Sent __last, _Out __result, 929 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const 930 { 931 for (; __first != __last; ++__first, (void)++__result) 932 if (std::__invoke(__pred, std::__invoke(__proj, *__first))) 933 *__result = __new_value; 934 else 935 *__result = *__first; 936 return {std::move(__first), std::move(__result)}; 937 } 938 939 template
_Out, 941 typename _Proj = identity, 942 indirect_unary_predicate
, _Proj>> 943 _Pred> 944 requires indirectly_copyable
, _Out> 945 constexpr replace_copy_if_result
, _Out> 946 operator()(_Range&& __r, _Out __result, 947 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const 948 { 949 return (*this)(ranges::begin(__r), ranges::end(__r), 950 std::move(__result), std::move(__pred), 951 __new_value, std::move(__proj)); 952 } 953 }; 954 955 inline constexpr __replace_copy_if_fn replace_copy_if{}; 956 957 struct __generate_n_fn 958 { 959 template
960 requires invocable<_Fp&> 961 && indirectly_writable<_Out, invoke_result_t<_Fp&>> 962 constexpr _Out 963 operator()(_Out __first, iter_difference_t<_Out> __n, _Fp __gen) const 964 { 965 for (; __n > 0; --__n, (void)++__first) 966 *__first = std::__invoke(__gen); 967 return __first; 968 } 969 }; 970 971 inline constexpr __generate_n_fn generate_n{}; 972 973 struct __generate_fn 974 { 975 template
_Sent, 976 copy_constructible _Fp> 977 requires invocable<_Fp&> 978 && indirectly_writable<_Out, invoke_result_t<_Fp&>> 979 constexpr _Out 980 operator()(_Out __first, _Sent __last, _Fp __gen) const 981 { 982 for (; __first != __last; ++__first) 983 *__first = std::__invoke(__gen); 984 return __first; 985 } 986 987 template
988 requires invocable<_Fp&> && output_range<_Range, invoke_result_t<_Fp&>> 989 constexpr borrowed_iterator_t<_Range> 990 operator()(_Range&& __r, _Fp __gen) const 991 { 992 return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__gen)); 993 } 994 }; 995 996 inline constexpr __generate_fn generate{}; 997 998 struct __remove_if_fn 999 { 1000 template
_Sent, 1001 typename _Proj = identity, 1002 indirect_unary_predicate
> _Pred> 1003 constexpr subrange<_Iter> 1004 operator()(_Iter __first, _Sent __last, 1005 _Pred __pred, _Proj __proj = {}) const 1006 { 1007 __first = ranges::find_if(__first, __last, __pred, __proj); 1008 if (__first == __last) 1009 return {__first, __first}; 1010 1011 auto __result = __first; 1012 ++__first; 1013 for (; __first != __last; ++__first) 1014 if (!std::__invoke(__pred, std::__invoke(__proj, *__first))) 1015 { 1016 *__result = std::move(*__first); 1017 ++__result; 1018 } 1019 1020 return {__result, __first}; 1021 } 1022 1023 template
, _Proj>> 1025 _Pred> 1026 requires permutable
> 1027 constexpr borrowed_subrange_t<_Range> 1028 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 1029 { 1030 return (*this)(ranges::begin(__r), ranges::end(__r), 1031 std::move(__pred), std::move(__proj)); 1032 } 1033 }; 1034 1035 inline constexpr __remove_if_fn remove_if{}; 1036 1037 struct __remove_fn 1038 { 1039 template
_Sent, 1040 typename _Tp, typename _Proj = identity> 1041 requires indirect_binary_predicate
, 1043 const _Tp*> 1044 constexpr subrange<_Iter> 1045 operator()(_Iter __first, _Sent __last, 1046 const _Tp& __value, _Proj __proj = {}) const 1047 { 1048 auto __pred = [&] (auto&& __arg) -> bool { 1049 return std::forward
(__arg) == __value; 1050 }; 1051 return ranges::remove_if(__first, __last, 1052 std::move(__pred), std::move(__proj)); 1053 } 1054 1055 template
1056 requires permutable
> 1057 && indirect_binary_predicate
, _Proj>, 1059 const _Tp*> 1060 constexpr borrowed_subrange_t<_Range> 1061 operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const 1062 { 1063 return (*this)(ranges::begin(__r), ranges::end(__r), 1064 __value, std::move(__proj)); 1065 } 1066 }; 1067 1068 inline constexpr __remove_fn remove{}; 1069 1070 template
1071 using remove_copy_if_result = in_out_result<_Iter, _Out>; 1072 1073 struct __remove_copy_if_fn 1074 { 1075 template
_Sent, 1076 weakly_incrementable _Out, typename _Proj = identity, 1077 indirect_unary_predicate
> _Pred> 1078 requires indirectly_copyable<_Iter, _Out> 1079 constexpr remove_copy_if_result<_Iter, _Out> 1080 operator()(_Iter __first, _Sent __last, _Out __result, 1081 _Pred __pred, _Proj __proj = {}) const 1082 { 1083 for (; __first != __last; ++__first) 1084 if (!std::__invoke(__pred, std::__invoke(__proj, *__first))) 1085 { 1086 *__result = *__first; 1087 ++__result; 1088 } 1089 return {std::move(__first), std::move(__result)}; 1090 } 1091 1092 template
, _Proj>> 1095 _Pred> 1096 requires indirectly_copyable
, _Out> 1097 constexpr remove_copy_if_result
, _Out> 1098 operator()(_Range&& __r, _Out __result, 1099 _Pred __pred, _Proj __proj = {}) const 1100 { 1101 return (*this)(ranges::begin(__r), ranges::end(__r), 1102 std::move(__result), 1103 std::move(__pred), std::move(__proj)); 1104 } 1105 }; 1106 1107 inline constexpr __remove_copy_if_fn remove_copy_if{}; 1108 1109 template
1110 using remove_copy_result = in_out_result<_Iter, _Out>; 1111 1112 struct __remove_copy_fn 1113 { 1114 template
_Sent, 1115 weakly_incrementable _Out, typename _Tp, typename _Proj = identity> 1116 requires indirectly_copyable<_Iter, _Out> 1117 && indirect_binary_predicate
, 1119 const _Tp*> 1120 constexpr remove_copy_result<_Iter, _Out> 1121 operator()(_Iter __first, _Sent __last, _Out __result, 1122 const _Tp& __value, _Proj __proj = {}) const 1123 { 1124 for (; __first != __last; ++__first) 1125 if (!(std::__invoke(__proj, *__first) == __value)) 1126 { 1127 *__result = *__first; 1128 ++__result; 1129 } 1130 return {std::move(__first), std::move(__result)}; 1131 } 1132 1133 template
1135 requires indirectly_copyable
, _Out> 1136 && indirect_binary_predicate
, _Proj>, 1138 const _Tp*> 1139 constexpr remove_copy_result
, _Out> 1140 operator()(_Range&& __r, _Out __result, 1141 const _Tp& __value, _Proj __proj = {}) const 1142 { 1143 return (*this)(ranges::begin(__r), ranges::end(__r), 1144 std::move(__result), __value, std::move(__proj)); 1145 } 1146 }; 1147 1148 inline constexpr __remove_copy_fn remove_copy{}; 1149 1150 struct __unique_fn 1151 { 1152 template
_Sent, 1153 typename _Proj = identity, 1154 indirect_equivalence_relation< 1155 projected<_Iter, _Proj>> _Comp = ranges::equal_to> 1156 constexpr subrange<_Iter> 1157 operator()(_Iter __first, _Sent __last, 1158 _Comp __comp = {}, _Proj __proj = {}) const 1159 { 1160 __first = ranges::adjacent_find(__first, __last, __comp, __proj); 1161 if (__first == __last) 1162 return {__first, __first}; 1163 1164 auto __dest = __first; 1165 ++__first; 1166 while (++__first != __last) 1167 if (!std::__invoke(__comp, 1168 std::__invoke(__proj, *__dest), 1169 std::__invoke(__proj, *__first))) 1170 *++__dest = std::move(*__first); 1171 return {++__dest, __first}; 1172 } 1173 1174 template
, _Proj>> _Comp = ranges::equal_to> 1177 requires permutable
> 1178 constexpr borrowed_subrange_t<_Range> 1179 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1180 { 1181 return (*this)(ranges::begin(__r), ranges::end(__r), 1182 std::move(__comp), std::move(__proj)); 1183 } 1184 }; 1185 1186 inline constexpr __unique_fn unique{}; 1187 1188 namespace __detail 1189 { 1190 template
1191 concept __can_reread_output = input_iterator<_Out> 1192 && same_as<_Tp, iter_value_t<_Out>>; 1193 } 1194 1195 template
1196 using unique_copy_result = in_out_result<_Iter, _Out>; 1197 1198 struct __unique_copy_fn 1199 { 1200 template
_Sent, 1201 weakly_incrementable _Out, typename _Proj = identity, 1202 indirect_equivalence_relation< 1203 projected<_Iter, _Proj>> _Comp = ranges::equal_to> 1204 requires indirectly_copyable<_Iter, _Out> 1205 && (forward_iterator<_Iter> 1206 || __detail::__can_reread_output<_Out, iter_value_t<_Iter>> 1207 || indirectly_copyable_storable<_Iter, _Out>) 1208 constexpr unique_copy_result<_Iter, _Out> 1209 operator()(_Iter __first, _Sent __last, _Out __result, 1210 _Comp __comp = {}, _Proj __proj = {}) const 1211 { 1212 if (__first == __last) 1213 return {std::move(__first), std::move(__result)}; 1214 1215 // TODO: perform a closer comparison with reference implementations 1216 if constexpr (forward_iterator<_Iter>) 1217 { 1218 auto __next = __first; 1219 *__result = *__next; 1220 while (++__next != __last) 1221 if (!std::__invoke(__comp, 1222 std::__invoke(__proj, *__first), 1223 std::__invoke(__proj, *__next))) 1224 { 1225 __first = __next; 1226 *++__result = *__first; 1227 } 1228 return {__next, std::move(++__result)}; 1229 } 1230 else if constexpr (__detail::__can_reread_output<_Out, iter_value_t<_Iter>>) 1231 { 1232 *__result = *__first; 1233 while (++__first != __last) 1234 if (!std::__invoke(__comp, 1235 std::__invoke(__proj, *__result), 1236 std::__invoke(__proj, *__first))) 1237 *++__result = *__first; 1238 return {std::move(__first), std::move(++__result)}; 1239 } 1240 else // indirectly_copyable_storable<_Iter, _Out> 1241 { 1242 auto __value = *__first; 1243 *__result = __value; 1244 while (++__first != __last) 1245 { 1246 if (!(bool)std::__invoke(__comp, 1247 std::__invoke(__proj, *__first), 1248 std::__invoke(__proj, __value))) 1249 { 1250 __value = *__first; 1251 *++__result = __value; 1252 } 1253 } 1254 return {std::move(__first), std::move(++__result)}; 1255 } 1256 } 1257 1258 template
, _Proj>> _Comp = ranges::equal_to> 1262 requires indirectly_copyable
, _Out> 1263 && (forward_iterator
> 1264 || __detail::__can_reread_output<_Out, range_value_t<_Range>> 1265 || indirectly_copyable_storable
, _Out>) 1266 constexpr unique_copy_result
, _Out> 1267 operator()(_Range&& __r, _Out __result, 1268 _Comp __comp = {}, _Proj __proj = {}) const 1269 { 1270 return (*this)(ranges::begin(__r), ranges::end(__r), 1271 std::move(__result), 1272 std::move(__comp), std::move(__proj)); 1273 } 1274 }; 1275 1276 inline constexpr __unique_copy_fn unique_copy{}; 1277 1278 struct __reverse_fn 1279 { 1280 template
_Sent> 1281 requires permutable<_Iter> 1282 constexpr _Iter 1283 operator()(_Iter __first, _Sent __last) const 1284 { 1285 auto __i = ranges::next(__first, __last); 1286 auto __tail = __i; 1287 1288 if constexpr (random_access_iterator<_Iter>) 1289 { 1290 if (__first != __last) 1291 { 1292 --__tail; 1293 while (__first < __tail) 1294 { 1295 ranges::iter_swap(__first, __tail); 1296 ++__first; 1297 --__tail; 1298 } 1299 } 1300 return __i; 1301 } 1302 else 1303 { 1304 for (;;) 1305 if (__first == __tail || __first == --__tail) 1306 break; 1307 else 1308 { 1309 ranges::iter_swap(__first, __tail); 1310 ++__first; 1311 } 1312 return __i; 1313 } 1314 } 1315 1316 template
1317 requires permutable
> 1318 constexpr borrowed_iterator_t<_Range> 1319 operator()(_Range&& __r) const 1320 { 1321 return (*this)(ranges::begin(__r), ranges::end(__r)); 1322 } 1323 }; 1324 1325 inline constexpr __reverse_fn reverse{}; 1326 1327 template
1328 using reverse_copy_result = in_out_result<_Iter, _Out>; 1329 1330 struct __reverse_copy_fn 1331 { 1332 template
_Sent, 1333 weakly_incrementable _Out> 1334 requires indirectly_copyable<_Iter, _Out> 1335 constexpr reverse_copy_result<_Iter, _Out> 1336 operator()(_Iter __first, _Sent __last, _Out __result) const 1337 { 1338 auto __i = ranges::next(__first, __last); 1339 auto __tail = __i; 1340 while (__first != __tail) 1341 { 1342 --__tail; 1343 *__result = *__tail; 1344 ++__result; 1345 } 1346 return {__i, std::move(__result)}; 1347 } 1348 1349 template
1350 requires indirectly_copyable
, _Out> 1351 constexpr reverse_copy_result
, _Out> 1352 operator()(_Range&& __r, _Out __result) const 1353 { 1354 return (*this)(ranges::begin(__r), ranges::end(__r), 1355 std::move(__result)); 1356 } 1357 }; 1358 1359 inline constexpr __reverse_copy_fn reverse_copy{}; 1360 1361 struct __rotate_fn 1362 { 1363 template
_Sent> 1364 constexpr subrange<_Iter> 1365 operator()(_Iter __first, _Iter __middle, _Sent __last) const 1366 { 1367 auto __lasti = ranges::next(__first, __last); 1368 if (__first == __middle) 1369 return {__lasti, __lasti}; 1370 if (__last == __middle) 1371 return {std::move(__first), std::move(__lasti)}; 1372 1373 if constexpr (random_access_iterator<_Iter>) 1374 { 1375 auto __n = __lasti - __first; 1376 auto __k = __middle - __first; 1377 1378 if (__k == __n - __k) 1379 { 1380 ranges::swap_ranges(__first, __middle, __middle, __middle + __k); 1381 return {std::move(__middle), std::move(__lasti)}; 1382 } 1383 1384 auto __p = __first; 1385 auto __ret = __first + (__lasti - __middle); 1386 1387 for (;;) 1388 { 1389 if (__k < __n - __k) 1390 { 1391 // TODO: is_pod is deprecated, but this condition is 1392 // consistent with the STL implementation. 1393 if constexpr (__is_pod(iter_value_t<_Iter>)) 1394 if (__k == 1) 1395 { 1396 auto __t = std::move(*__p); 1397 ranges::move(__p + 1, __p + __n, __p); 1398 *(__p + __n - 1) = std::move(__t); 1399 return {std::move(__ret), std::move(__lasti)}; 1400 } 1401 auto __q = __p + __k; 1402 for (decltype(__n) __i = 0; __i < __n - __k; ++ __i) 1403 { 1404 ranges::iter_swap(__p, __q); 1405 ++__p; 1406 ++__q; 1407 } 1408 __n %= __k; 1409 if (__n == 0) 1410 return {std::move(__ret), std::move(__lasti)}; 1411 ranges::swap(__n, __k); 1412 __k = __n - __k; 1413 } 1414 else 1415 { 1416 __k = __n - __k; 1417 // TODO: is_pod is deprecated, but this condition is 1418 // consistent with the STL implementation. 1419 if constexpr (__is_pod(iter_value_t<_Iter>)) 1420 if (__k == 1) 1421 { 1422 auto __t = std::move(*(__p + __n - 1)); 1423 ranges::move_backward(__p, __p + __n - 1, __p + __n); 1424 *__p = std::move(__t); 1425 return {std::move(__ret), std::move(__lasti)}; 1426 } 1427 auto __q = __p + __n; 1428 __p = __q - __k; 1429 for (decltype(__n) __i = 0; __i < __n - __k; ++ __i) 1430 { 1431 --__p; 1432 --__q; 1433 ranges::iter_swap(__p, __q); 1434 } 1435 __n %= __k; 1436 if (__n == 0) 1437 return {std::move(__ret), std::move(__lasti)}; 1438 std::swap(__n, __k); 1439 } 1440 } 1441 } 1442 else if constexpr (bidirectional_iterator<_Iter>) 1443 { 1444 auto __tail = __lasti; 1445 1446 ranges::reverse(__first, __middle); 1447 ranges::reverse(__middle, __tail); 1448 1449 while (__first != __middle && __middle != __tail) 1450 { 1451 ranges::iter_swap(__first, --__tail); 1452 ++__first; 1453 } 1454 1455 if (__first == __middle) 1456 { 1457 ranges::reverse(__middle, __tail); 1458 return {std::move(__tail), std::move(__lasti)}; 1459 } 1460 else 1461 { 1462 ranges::reverse(__first, __middle); 1463 return {std::move(__first), std::move(__lasti)}; 1464 } 1465 } 1466 else 1467 { 1468 auto __first2 = __middle; 1469 do 1470 { 1471 ranges::iter_swap(__first, __first2); 1472 ++__first; 1473 ++__first2; 1474 if (__first == __middle) 1475 __middle = __first2; 1476 } while (__first2 != __last); 1477 1478 auto __ret = __first; 1479 1480 __first2 = __middle; 1481 1482 while (__first2 != __last) 1483 { 1484 ranges::iter_swap(__first, __first2); 1485 ++__first; 1486 ++__first2; 1487 if (__first == __middle) 1488 __middle = __first2; 1489 else if (__first2 == __last) 1490 __first2 = __middle; 1491 } 1492 return {std::move(__ret), std::move(__lasti)}; 1493 } 1494 } 1495 1496 template
1497 requires permutable
> 1498 constexpr borrowed_subrange_t<_Range> 1499 operator()(_Range&& __r, iterator_t<_Range> __middle) const 1500 { 1501 return (*this)(ranges::begin(__r), std::move(__middle), 1502 ranges::end(__r)); 1503 } 1504 }; 1505 1506 inline constexpr __rotate_fn rotate{}; 1507 1508 template
1509 using rotate_copy_result = in_out_result<_Iter, _Out>; 1510 1511 struct __rotate_copy_fn 1512 { 1513 template
_Sent, 1514 weakly_incrementable _Out> 1515 requires indirectly_copyable<_Iter, _Out> 1516 constexpr rotate_copy_result<_Iter, _Out> 1517 operator()(_Iter __first, _Iter __middle, _Sent __last, 1518 _Out __result) const 1519 { 1520 auto __copy1 = ranges::copy(__middle, 1521 std::move(__last), 1522 std::move(__result)); 1523 auto __copy2 = ranges::copy(std::move(__first), 1524 std::move(__middle), 1525 std::move(__copy1.out)); 1526 return { std::move(__copy1.in), std::move(__copy2.out) }; 1527 } 1528 1529 template
1530 requires indirectly_copyable
, _Out> 1531 constexpr rotate_copy_result
, _Out> 1532 operator()(_Range&& __r, iterator_t<_Range> __middle, _Out __result) const 1533 { 1534 return (*this)(ranges::begin(__r), std::move(__middle), 1535 ranges::end(__r), std::move(__result)); 1536 } 1537 }; 1538 1539 inline constexpr __rotate_copy_fn rotate_copy{}; 1540 1541 struct __sample_fn 1542 { 1543 template
_Sent, 1544 weakly_incrementable _Out, typename _Gen> 1545 requires (forward_iterator<_Iter> || random_access_iterator<_Out>) 1546 && indirectly_copyable<_Iter, _Out> 1547 && uniform_random_bit_generator
> 1548 _Out 1549 operator()(_Iter __first, _Sent __last, _Out __out, 1550 iter_difference_t<_Iter> __n, _Gen&& __g) const 1551 { 1552 if constexpr (forward_iterator<_Iter>) 1553 { 1554 // FIXME: Forwarding to std::sample here requires computing __lasti 1555 // which may take linear time. 1556 auto __lasti = ranges::next(__first, __last); 1557 return _GLIBCXX_STD_A:: 1558 sample(std::move(__first), std::move(__lasti), std::move(__out), 1559 __n, std::forward<_Gen>(__g)); 1560 } 1561 else 1562 { 1563 using __distrib_type 1564 = uniform_int_distribution
>; 1565 using __param_type = typename __distrib_type::param_type; 1566 __distrib_type __d{}; 1567 iter_difference_t<_Iter> __sample_sz = 0; 1568 while (__first != __last && __sample_sz != __n) 1569 { 1570 __out[__sample_sz++] = *__first; 1571 ++__first; 1572 } 1573 for (auto __pop_sz = __sample_sz; __first != __last; 1574 ++__first, (void) ++__pop_sz) 1575 { 1576 const auto __k = __d(__g, __param_type{0, __pop_sz}); 1577 if (__k < __n) 1578 __out[__k] = *__first; 1579 } 1580 return __out + __sample_sz; 1581 } 1582 } 1583 1584 template
1585 requires (forward_range<_Range> || random_access_iterator<_Out>) 1586 && indirectly_copyable
, _Out> 1587 && uniform_random_bit_generator
> 1588 _Out 1589 operator()(_Range&& __r, _Out __out, 1590 range_difference_t<_Range> __n, _Gen&& __g) const 1591 { 1592 return (*this)(ranges::begin(__r), ranges::end(__r), 1593 std::move(__out), __n, 1594 std::forward<_Gen>(__g)); 1595 } 1596 }; 1597 1598 inline constexpr __sample_fn sample{}; 1599 1600 #ifdef _GLIBCXX_USE_C99_STDINT_TR1 1601 struct __shuffle_fn 1602 { 1603 template
_Sent, 1604 typename _Gen> 1605 requires permutable<_Iter> 1606 && uniform_random_bit_generator
> 1607 _Iter 1608 operator()(_Iter __first, _Sent __last, _Gen&& __g) const 1609 { 1610 auto __lasti = ranges::next(__first, __last); 1611 std::shuffle(std::move(__first), __lasti, std::forward<_Gen>(__g)); 1612 return __lasti; 1613 } 1614 1615 template
1616 requires permutable
> 1617 && uniform_random_bit_generator
> 1618 borrowed_iterator_t<_Range> 1619 operator()(_Range&& __r, _Gen&& __g) const 1620 { 1621 return (*this)(ranges::begin(__r), ranges::end(__r), 1622 std::forward<_Gen>(__g)); 1623 } 1624 }; 1625 1626 inline constexpr __shuffle_fn shuffle{}; 1627 #endif 1628 1629 struct __push_heap_fn 1630 { 1631 template
_Sent, 1632 typename _Comp = ranges::less, typename _Proj = identity> 1633 requires sortable<_Iter, _Comp, _Proj> 1634 constexpr _Iter 1635 operator()(_Iter __first, _Sent __last, 1636 _Comp __comp = {}, _Proj __proj = {}) const 1637 { 1638 auto __lasti = ranges::next(__first, __last); 1639 std::push_heap(__first, __lasti, 1640 __detail::__make_comp_proj(__comp, __proj)); 1641 return __lasti; 1642 } 1643 1644 template
1646 requires sortable
, _Comp, _Proj> 1647 constexpr borrowed_iterator_t<_Range> 1648 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1649 { 1650 return (*this)(ranges::begin(__r), ranges::end(__r), 1651 std::move(__comp), std::move(__proj)); 1652 } 1653 }; 1654 1655 inline constexpr __push_heap_fn push_heap{}; 1656 1657 struct __pop_heap_fn 1658 { 1659 template
_Sent, 1660 typename _Comp = ranges::less, typename _Proj = identity> 1661 requires sortable<_Iter, _Comp, _Proj> 1662 constexpr _Iter 1663 operator()(_Iter __first, _Sent __last, 1664 _Comp __comp = {}, _Proj __proj = {}) const 1665 { 1666 auto __lasti = ranges::next(__first, __last); 1667 std::pop_heap(__first, __lasti, 1668 __detail::__make_comp_proj(__comp, __proj)); 1669 return __lasti; 1670 } 1671 1672 template
1674 requires sortable
, _Comp, _Proj> 1675 constexpr borrowed_iterator_t<_Range> 1676 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1677 { 1678 return (*this)(ranges::begin(__r), ranges::end(__r), 1679 std::move(__comp), std::move(__proj)); 1680 } 1681 }; 1682 1683 inline constexpr __pop_heap_fn pop_heap{}; 1684 1685 struct __make_heap_fn 1686 { 1687 template
_Sent, 1688 typename _Comp = ranges::less, typename _Proj = identity> 1689 requires sortable<_Iter, _Comp, _Proj> 1690 constexpr _Iter 1691 operator()(_Iter __first, _Sent __last, 1692 _Comp __comp = {}, _Proj __proj = {}) const 1693 { 1694 auto __lasti = ranges::next(__first, __last); 1695 std::make_heap(__first, __lasti, 1696 __detail::__make_comp_proj(__comp, __proj)); 1697 return __lasti; 1698 } 1699 1700 template
1702 requires sortable
, _Comp, _Proj> 1703 constexpr borrowed_iterator_t<_Range> 1704 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1705 { 1706 return (*this)(ranges::begin(__r), ranges::end(__r), 1707 std::move(__comp), std::move(__proj)); 1708 } 1709 }; 1710 1711 inline constexpr __make_heap_fn make_heap{}; 1712 1713 struct __sort_heap_fn 1714 { 1715 template
_Sent, 1716 typename _Comp = ranges::less, typename _Proj = identity> 1717 requires sortable<_Iter, _Comp, _Proj> 1718 constexpr _Iter 1719 operator()(_Iter __first, _Sent __last, 1720 _Comp __comp = {}, _Proj __proj = {}) const 1721 { 1722 auto __lasti = ranges::next(__first, __last); 1723 std::sort_heap(__first, __lasti, 1724 __detail::__make_comp_proj(__comp, __proj)); 1725 return __lasti; 1726 } 1727 1728 template
1730 requires sortable
, _Comp, _Proj> 1731 constexpr borrowed_iterator_t<_Range> 1732 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1733 { 1734 return (*this)(ranges::begin(__r), ranges::end(__r), 1735 std::move(__comp), std::move(__proj)); 1736 } 1737 }; 1738 1739 inline constexpr __sort_heap_fn sort_heap{}; 1740 1741 struct __is_heap_until_fn 1742 { 1743 template
_Sent, 1744 typename _Proj = identity, 1745 indirect_strict_weak_order
> 1746 _Comp = ranges::less> 1747 constexpr _Iter 1748 operator()(_Iter __first, _Sent __last, 1749 _Comp __comp = {}, _Proj __proj = {}) const 1750 { 1751 iter_difference_t<_Iter> __n = ranges::distance(__first, __last); 1752 iter_difference_t<_Iter> __parent = 0, __child = 1; 1753 for (; __child < __n; ++__child) 1754 if (std::__invoke(__comp, 1755 std::__invoke(__proj, *(__first + __parent)), 1756 std::__invoke(__proj, *(__first + __child)))) 1757 return __first + __child; 1758 else if ((__child & 1) == 0) 1759 ++__parent; 1760 1761 return __first + __n; 1762 } 1763 1764 template
, _Proj>> 1767 _Comp = ranges::less> 1768 constexpr borrowed_iterator_t<_Range> 1769 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1770 { 1771 return (*this)(ranges::begin(__r), ranges::end(__r), 1772 std::move(__comp), std::move(__proj)); 1773 } 1774 }; 1775 1776 inline constexpr __is_heap_until_fn is_heap_until{}; 1777 1778 struct __is_heap_fn 1779 { 1780 template
_Sent, 1781 typename _Proj = identity, 1782 indirect_strict_weak_order
> 1783 _Comp = ranges::less> 1784 constexpr bool 1785 operator()(_Iter __first, _Sent __last, 1786 _Comp __comp = {}, _Proj __proj = {}) const 1787 { 1788 return (__last 1789 == ranges::is_heap_until(__first, __last, 1790 std::move(__comp), 1791 std::move(__proj))); 1792 } 1793 1794 template
, _Proj>> 1797 _Comp = ranges::less> 1798 constexpr bool 1799 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1800 { 1801 return (*this)(ranges::begin(__r), ranges::end(__r), 1802 std::move(__comp), std::move(__proj)); 1803 } 1804 }; 1805 1806 inline constexpr __is_heap_fn is_heap{}; 1807 1808 struct __sort_fn 1809 { 1810 template
_Sent, 1811 typename _Comp = ranges::less, typename _Proj = identity> 1812 requires sortable<_Iter, _Comp, _Proj> 1813 constexpr _Iter 1814 operator()(_Iter __first, _Sent __last, 1815 _Comp __comp = {}, _Proj __proj = {}) const 1816 { 1817 auto __lasti = ranges::next(__first, __last); 1818 _GLIBCXX_STD_A::sort(std::move(__first), __lasti, 1819 __detail::__make_comp_proj(__comp, __proj)); 1820 return __lasti; 1821 } 1822 1823 template
1825 requires sortable
, _Comp, _Proj> 1826 constexpr borrowed_iterator_t<_Range> 1827 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1828 { 1829 return (*this)(ranges::begin(__r), ranges::end(__r), 1830 std::move(__comp), std::move(__proj)); 1831 } 1832 }; 1833 1834 inline constexpr __sort_fn sort{}; 1835 1836 struct __stable_sort_fn 1837 { 1838 template
_Sent, 1839 typename _Comp = ranges::less, typename _Proj = identity> 1840 requires sortable<_Iter, _Comp, _Proj> 1841 _Iter 1842 operator()(_Iter __first, _Sent __last, 1843 _Comp __comp = {}, _Proj __proj = {}) const 1844 { 1845 auto __lasti = ranges::next(__first, __last); 1846 std::stable_sort(std::move(__first), __lasti, 1847 __detail::__make_comp_proj(__comp, __proj)); 1848 return __lasti; 1849 } 1850 1851 template
1853 requires sortable
, _Comp, _Proj> 1854 borrowed_iterator_t<_Range> 1855 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 1856 { 1857 return (*this)(ranges::begin(__r), ranges::end(__r), 1858 std::move(__comp), std::move(__proj)); 1859 } 1860 }; 1861 1862 inline constexpr __stable_sort_fn stable_sort{}; 1863 1864 struct __partial_sort_fn 1865 { 1866 template
_Sent, 1867 typename _Comp = ranges::less, typename _Proj = identity> 1868 requires sortable<_Iter, _Comp, _Proj> 1869 constexpr _Iter 1870 operator()(_Iter __first, _Iter __middle, _Sent __last, 1871 _Comp __comp = {}, _Proj __proj = {}) const 1872 { 1873 if (__first == __middle) 1874 return ranges::next(__first, __last); 1875 1876 ranges::make_heap(__first, __middle, __comp, __proj); 1877 auto __i = __middle; 1878 for (; __i != __last; ++__i) 1879 if (std::__invoke(__comp, 1880 std::__invoke(__proj, *__i), 1881 std::__invoke(__proj, *__first))) 1882 { 1883 ranges::pop_heap(__first, __middle, __comp, __proj); 1884 ranges::iter_swap(__middle-1, __i); 1885 ranges::push_heap(__first, __middle, __comp, __proj); 1886 } 1887 ranges::sort_heap(__first, __middle, __comp, __proj); 1888 1889 return __i; 1890 } 1891 1892 template
1894 requires sortable
, _Comp, _Proj> 1895 constexpr borrowed_iterator_t<_Range> 1896 operator()(_Range&& __r, iterator_t<_Range> __middle, 1897 _Comp __comp = {}, _Proj __proj = {}) const 1898 { 1899 return (*this)(ranges::begin(__r), std::move(__middle), 1900 ranges::end(__r), 1901 std::move(__comp), std::move(__proj)); 1902 } 1903 }; 1904 1905 inline constexpr __partial_sort_fn partial_sort{}; 1906 1907 template
1908 using partial_sort_copy_result = in_out_result<_Iter, _Out>; 1909 1910 struct __partial_sort_copy_fn 1911 { 1912 template
_Sent1, 1913 random_access_iterator _Iter2, sentinel_for<_Iter2> _Sent2, 1914 typename _Comp = ranges::less, 1915 typename _Proj1 = identity, typename _Proj2 = identity> 1916 requires indirectly_copyable<_Iter1, _Iter2> 1917 && sortable<_Iter2, _Comp, _Proj2> 1918 && indirect_strict_weak_order<_Comp, 1919 projected<_Iter1, _Proj1>, 1920 projected<_Iter2, _Proj2>> 1921 constexpr partial_sort_copy_result<_Iter1, _Iter2> 1922 operator()(_Iter1 __first, _Sent1 __last, 1923 _Iter2 __result_first, _Sent2 __result_last, 1924 _Comp __comp = {}, 1925 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 1926 { 1927 if (__result_first == __result_last) 1928 { 1929 // TODO: Eliminating the variable __lasti triggers an ICE. 1930 auto __lasti = ranges::next(std::move(__first), 1931 std::move(__last)); 1932 return {std::move(__lasti), std::move(__result_first)}; 1933 } 1934 1935 auto __result_real_last = __result_first; 1936 while (__first != __last && __result_real_last != __result_last) 1937 { 1938 *__result_real_last = *__first; 1939 ++__result_real_last; 1940 ++__first; 1941 } 1942 1943 ranges::make_heap(__result_first, __result_real_last, __comp, __proj2); 1944 for (; __first != __last; ++__first) 1945 if (std::__invoke(__comp, 1946 std::__invoke(__proj1, *__first), 1947 std::__invoke(__proj2, *__result_first))) 1948 { 1949 ranges::pop_heap(__result_first, __result_real_last, 1950 __comp, __proj2); 1951 *(__result_real_last-1) = *__first; 1952 ranges::push_heap(__result_first, __result_real_last, 1953 __comp, __proj2); 1954 } 1955 ranges::sort_heap(__result_first, __result_real_last, __comp, __proj2); 1956 1957 return {std::move(__first), std::move(__result_real_last)}; 1958 } 1959 1960 template
1963 requires indirectly_copyable
, iterator_t<_Range2>> 1964 && sortable
, _Comp, _Proj2> 1965 && indirect_strict_weak_order<_Comp, 1966 projected
, _Proj1>, 1967 projected
, _Proj2>> 1968 constexpr partial_sort_copy_result
, 1969 borrowed_iterator_t<_Range2>> 1970 operator()(_Range1&& __r, _Range2&& __out, _Comp __comp = {}, 1971 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const 1972 { 1973 return (*this)(ranges::begin(__r), ranges::end(__r), 1974 ranges::begin(__out), ranges::end(__out), 1975 std::move(__comp), 1976 std::move(__proj1), std::move(__proj2)); 1977 } 1978 }; 1979 1980 inline constexpr __partial_sort_copy_fn partial_sort_copy{}; 1981 1982 struct __is_sorted_until_fn 1983 { 1984 template
_Sent, 1985 typename _Proj = identity, 1986 indirect_strict_weak_order
> 1987 _Comp = ranges::less> 1988 constexpr _Iter 1989 operator()(_Iter __first, _Sent __last, 1990 _Comp __comp = {}, _Proj __proj = {}) const 1991 { 1992 if (__first == __last) 1993 return __first; 1994 1995 auto __next = __first; 1996 for (++__next; __next != __last; __first = __next, (void)++__next) 1997 if (std::__invoke(__comp, 1998 std::__invoke(__proj, *__next), 1999 std::__invoke(__proj, *__first))) 2000 return __next; 2001 return __next; 2002 } 2003 2004 template
, _Proj>> 2006 _Comp = ranges::less> 2007 constexpr borrowed_iterator_t<_Range> 2008 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 2009 { 2010 return (*this)(ranges::begin(__r), ranges::end(__r), 2011 std::move(__comp), std::move(__proj)); 2012 } 2013 }; 2014 2015 inline constexpr __is_sorted_until_fn is_sorted_until{}; 2016 2017 struct __is_sorted_fn 2018 { 2019 template
_Sent, 2020 typename _Proj = identity, 2021 indirect_strict_weak_order
> 2022 _Comp = ranges::less> 2023 constexpr bool 2024 operator()(_Iter __first, _Sent __last, 2025 _Comp __comp = {}, _Proj __proj = {}) const 2026 { 2027 if (__first == __last) 2028 return true; 2029 2030 auto __next = __first; 2031 for (++__next; __next != __last; __first = __next, (void)++__next) 2032 if (std::__invoke(__comp, 2033 std::__invoke(__proj, *__next), 2034 std::__invoke(__proj, *__first))) 2035 return false; 2036 return true; 2037 } 2038 2039 template
, _Proj>> 2041 _Comp = ranges::less> 2042 constexpr bool 2043 operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const 2044 { 2045 return (*this)(ranges::begin(__r), ranges::end(__r), 2046 std::move(__comp), std::move(__proj)); 2047 } 2048 }; 2049 2050 inline constexpr __is_sorted_fn is_sorted{}; 2051 2052 struct __nth_element_fn 2053 { 2054 template
_Sent, 2055 typename _Comp = ranges::less, typename _Proj = identity> 2056 requires sortable<_Iter, _Comp, _Proj> 2057 constexpr _Iter 2058 operator()(_Iter __first, _Iter __nth, _Sent __last, 2059 _Comp __comp = {}, _Proj __proj = {}) const 2060 { 2061 auto __lasti = ranges::next(__first, __last); 2062 _GLIBCXX_STD_A::nth_element(std::move(__first), std::move(__nth), 2063 __lasti, 2064 __detail::__make_comp_proj(__comp, __proj)); 2065 return __lasti; 2066 } 2067 2068 template
2070 requires sortable
, _Comp, _Proj> 2071 constexpr borrowed_iterator_t<_Range> 2072 operator()(_Range&& __r, iterator_t<_Range> __nth, 2073 _Comp __comp = {}, _Proj __proj = {}) const 2074 { 2075 return (*this)(ranges::begin(__r), std::move(__nth), 2076 ranges::end(__r), std::move(__comp), std::move(__proj)); 2077 } 2078 }; 2079 2080 inline constexpr __nth_element_fn nth_element{}; 2081 2082 struct __lower_bound_fn 2083 { 2084 template
_Sent, 2085 typename _Tp, typename _Proj = identity, 2086 indirect_strict_weak_order
> 2087 _Comp = ranges::less> 2088 constexpr _Iter 2089 operator()(_Iter __first, _Sent __last, 2090 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const 2091 { 2092 auto __len = ranges::distance(__first, __last); 2093 2094 while (__len > 0) 2095 { 2096 auto __half = __len / 2; 2097 auto __middle = __first; 2098 ranges::advance(__middle, __half); 2099 if (std::__invoke(__comp, std::__invoke(__proj, *__middle), __value)) 2100 { 2101 __first = __middle; 2102 ++__first; 2103 __len = __len - __half - 1; 2104 } 2105 else 2106 __len = __half; 2107 } 2108 return __first; 2109 } 2110 2111 template
, _Proj>> 2114 _Comp = ranges::less> 2115 constexpr borrowed_iterator_t<_Range> 2116 operator()(_Range&& __r, 2117 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const 2118 { 2119 return (*this)(ranges::begin(__r), ranges::end(__r), 2120 __value, std::move(__comp), std::move(__proj)); 2121 } 2122 }; 2123 2124 inline constexpr __lower_bound_fn lower_bound{}; 2125 2126 struct __upper_bound_fn 2127 { 2128 template
_Sent, 2129 typename _Tp, typename _Proj = identity, 2130 indirect_strict_weak_order
> 2131 _Comp = ranges::less> 2132 constexpr _Iter 2133 operator()(_Iter __first, _Sent __last, 2134 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const 2135 { 2136 auto __len = ranges::distance(__first, __last); 2137 2138 while (__len > 0) 2139 { 2140 auto __half = __len / 2; 2141 auto __middle = __first; 2142 ranges::advance(__middle, __half); 2143 if (std::__invoke(__comp, __value, std::__invoke(__proj, *__middle))) 2144 __len = __half; 2145 else 2146 { 2147 __first = __middle; 2148 ++__first; 2149 __len = __len - __half - 1; 2150 } 2151 } 2152 return __first; 2153 } 2154 2155 template
, _Proj>> 2158 _Comp = ranges::less> 2159 constexpr borrowed_iterator_t<_Range> 2160 operator()(_Range&& __r, 2161 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const 2162 { 2163 return (*this)(ranges::begin(__r), ranges::end(__r), 2164 __value, std::move(__comp), std::move(__proj)); 2165 } 2166 }; 2167 2168 inline constexpr __upper_bound_fn upper_bound{}; 2169 2170 struct __equal_range_fn 2171 { 2172 template
_Sent, 2173 typename _Tp, typename _Proj = identity, 2174 indirect_strict_weak_order
> 2175 _Comp = ranges::less> 2176 constexpr subrange<_Iter> 2177 operator()(_Iter __first, _Sent __last, 2178 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const 2179 { 2180 auto __len = ranges::distance(__first, __last); 2181 2182 while (__len > 0) 2183 { 2184 auto __half = __len / 2; 2185 auto __middle = __first; 2186 ranges::advance(__middle, __half); 2187 if (std::__invoke(__comp, 2188 std::__invoke(__proj, *__middle), 2189 __value)) 2190 { 2191 __first = __middle; 2192 ++__first; 2193 __len = __len - __half - 1; 2194 } 2195 else if (std::__invoke(__comp, 2196 __value, 2197 std::__invoke(__proj, *__middle))) 2198 __len = __half; 2199 else 2200 { 2201 auto __left 2202 = ranges::lower_bound(__first, __middle, 2203 __value, __comp, __proj); 2204 ranges::advance(__first, __len); 2205 auto __right 2206 = ranges::upper_bound(++__middle, __first, 2207 __value, __comp, __proj); 2208 return {__left, __right}; 2209 } 2210 } 2211 return {__first, __first}; 2212 } 2213 2214 template
, _Proj>> 2218 _Comp = ranges::less> 2219 constexpr borrowed_subrange_t<_Range> 2220 operator()(_Range&& __r, const _Tp& __value, 2221 _Comp __comp = {}, _Proj __proj = {}) const 2222 { 2223 return (*this)(ranges::begin(__r), ranges::end(__r), 2224 __value, std::move(__comp), std::move(__proj)); 2225 } 2226 }; 2227 2228 inline constexpr __equal_range_fn equal_range{}; 2229 2230 struct __binary_search_fn 2231 { 2232 template
_Sent, 2233 typename _Tp, typename _Proj = identity, 2234 indirect_strict_weak_order
> 2235 _Comp = ranges::less> 2236 constexpr bool 2237 operator()(_Iter __first, _Sent __last, 2238 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const 2239 { 2240 auto __i = ranges::lower_bound(__first, __last, __value, __comp, __proj); 2241 if (__i == __last) 2242 return false; 2243 return !(bool)std::__invoke(__comp, __value, 2244 std::__invoke(__proj, *__i)); 2245 } 2246 2247 template
, _Proj>> 2251 _Comp = ranges::less> 2252 constexpr bool 2253 operator()(_Range&& __r, const _Tp& __value, _Comp __comp = {}, 2254 _Proj __proj = {}) const 2255 { 2256 return (*this)(ranges::begin(__r), ranges::end(__r), 2257 __value, std::move(__comp), std::move(__proj)); 2258 } 2259 }; 2260 2261 inline constexpr __binary_search_fn binary_search{}; 2262 2263 struct __is_partitioned_fn 2264 { 2265 template
_Sent, 2266 typename _Proj = identity, 2267 indirect_unary_predicate
> _Pred> 2268 constexpr bool 2269 operator()(_Iter __first, _Sent __last, 2270 _Pred __pred, _Proj __proj = {}) const 2271 { 2272 __first = ranges::find_if_not(std::move(__first), __last, 2273 __pred, __proj); 2274 if (__first == __last) 2275 return true; 2276 ++__first; 2277 return ranges::none_of(std::move(__first), std::move(__last), 2278 std::move(__pred), std::move(__proj)); 2279 } 2280 2281 template
, _Proj>> 2283 _Pred> 2284 constexpr bool 2285 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 2286 { 2287 return (*this)(ranges::begin(__r), ranges::end(__r), 2288 std::move(__pred), std::move(__proj)); 2289 } 2290 }; 2291 2292 inline constexpr __is_partitioned_fn is_partitioned{}; 2293 2294 struct __partition_fn 2295 { 2296 template
_Sent, 2297 typename _Proj = identity, 2298 indirect_unary_predicate
> _Pred> 2299 constexpr subrange<_Iter> 2300 operator()(_Iter __first, _Sent __last, 2301 _Pred __pred, _Proj __proj = {}) const 2302 { 2303 if constexpr (bidirectional_iterator<_Iter>) 2304 { 2305 auto __lasti = ranges::next(__first, __last); 2306 auto __tail = __lasti; 2307 for (;;) 2308 { 2309 for (;;) 2310 if (__first == __tail) 2311 return {std::move(__first), std::move(__lasti)}; 2312 else if (std::__invoke(__pred, 2313 std::__invoke(__proj, *__first))) 2314 ++__first; 2315 else 2316 break; 2317 --__tail; 2318 for (;;) 2319 if (__first == __tail) 2320 return {std::move(__first), std::move(__lasti)}; 2321 else if (!(bool)std::__invoke(__pred, 2322 std::__invoke(__proj, *__tail))) 2323 --__tail; 2324 else 2325 break; 2326 ranges::iter_swap(__first, __tail); 2327 ++__first; 2328 } 2329 } 2330 else 2331 { 2332 if (__first == __last) 2333 return {__first, __first}; 2334 2335 while (std::__invoke(__pred, std::__invoke(__proj, *__first))) 2336 if (++__first == __last) 2337 return {__first, __first}; 2338 2339 auto __next = __first; 2340 while (++__next != __last) 2341 if (std::__invoke(__pred, std::__invoke(__proj, *__next))) 2342 { 2343 ranges::iter_swap(__first, __next); 2344 ++__first; 2345 } 2346 2347 return {std::move(__first), std::move(__next)}; 2348 } 2349 } 2350 2351 template
, _Proj>> 2353 _Pred> 2354 requires permutable
> 2355 constexpr borrowed_subrange_t<_Range> 2356 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 2357 { 2358 return (*this)(ranges::begin(__r), ranges::end(__r), 2359 std::move(__pred), std::move(__proj)); 2360 } 2361 }; 2362 2363 inline constexpr __partition_fn partition{}; 2364 2365 struct __stable_partition_fn 2366 { 2367 template
_Sent, 2368 typename _Proj = identity, 2369 indirect_unary_predicate
> _Pred> 2370 requires permutable<_Iter> 2371 subrange<_Iter> 2372 operator()(_Iter __first, _Sent __last, 2373 _Pred __pred, _Proj __proj = {}) const 2374 { 2375 auto __lasti = ranges::next(__first, __last); 2376 auto __middle 2377 = std::stable_partition(std::move(__first), __lasti, 2378 __detail::__make_pred_proj(__pred, __proj)); 2379 return {std::move(__middle), std::move(__lasti)}; 2380 } 2381 2382 template
, _Proj>> 2384 _Pred> 2385 requires permutable
> 2386 borrowed_subrange_t<_Range> 2387 operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const 2388 { 2389 return (*this)(ranges::begin(__r), ranges::end(__r), 2390 std::move(__pred), std::move(__proj)); 2391 } 2392 }; 2393 2394 inline constexpr __stable_partition_fn stable_partition{}; 2395 2396 template
2397 struct in_out_out_result 2398 { 2399 [[no_unique_address]] _Iter in; 2400 [[no_unique_address]] _Out1 out1; 2401 [[no_unique_address]] _Out2 out2; 2402 2403 template
2404 requires convertible_to
2405 && convertible_to
2406 && convertible_to
2407 constexpr 2408 operator in_out_out_result<_IIter, _OOut1, _OOut2>() const & 2409 { return {in, out1, out2}; } 2410 2411 template
2412 requires convertible_to<_Iter, _IIter> 2413 && convertible_to<_Out1, _OOut1> 2414 && convertible_to<_Out2, _OOut2> 2415 constexpr 2416 operator in_out_out_result<_IIter, _OOut1, _OOut2>() && 2417 { return {std::move(in), std::move(out1), std::move(out2)}; } 2418 }; 2419 2420 template
2421 using partition_copy_result = in_out_out_result<_Iter, _Out1, _Out2>; 2422 2423 struct __partition_copy_fn 2424 { 2425 template
_Sent, 2426 weakly_incrementable _Out1, weakly_incrementable _Out2, 2427 typename _Proj = identity, 2428 indirect_unary_predicate
> _Pred> 2429 requires indirectly_copyable<_Iter, _Out1> 2430 && indirectly_copyable<_Iter, _Out2> 2431 constexpr partition_copy_result<_Iter, _Out1, _Out2> 2432 operator()(_Iter __first, _Sent __last, 2433 _Out1 __out_true, _Out2 __out_false, 2434 _Pred __pred, _Proj __proj = {}) const 2435 { 2436 for (; __first != __last; ++__first) 2437 if (std::__invoke(__pred, std::__invoke(__proj, *__first))) 2438 { 2439 *__out_true = *__first; 2440 ++__out_true; 2441 } 2442 else 2443 { 2444 *__out_false = *__first; 2445 ++__out_false; 2446 } 2447 2448 return {std::move(__first), 2449 std::move(__out_true), std::move(__out_false)}; 2450 } 2451 2452 template
, _Proj>> 2456 _Pred> 2457 requires indirectly_copyable
, _Out1> 2458 && indirectly_copyable
, _Out2> 2459 constexpr partition_copy_result
, _Out1, _Out2> 2460 operator()(_Range&& __r, _Out1 __out_true, _Out2 __out_false, 2461 _Pred __pred, _Proj __proj = {}) const 2462 { 2463 return (*this)(ranges::begin(__r), ranges::end(__r), 2464 std::move(__out_true), std::move(__out_false), 2465 std::move(__pred), std::move(__proj)); 2466 } 2467 }; 2468 2469 inline constexpr __partition_copy_fn partition_copy{}; 2470 2471 struct __partition_point_fn 2472 { 2473 template
_Sent, 2474 typename _Proj = identity, 2475 indirect_unary_predicate
> _Pred> 2476 constexpr _Iter 2477 operator()(_Iter __first, _Sent __last, 2478 _Pred __pred, _Proj __proj = {}) const 2479 { 2480 auto __len = ranges::distance(__first, __last); 2481 2482 while (__len > 0) 2483 { 2484 auto __half = __len / 2; 2485 auto __middle = __first; 2486 ranges::advance(__middle, __half); 2487 if (std::__invoke(__pred, std::__invoke(__proj, *__middle))) 2488 { 2489 __first = __middle; 2490 ++__first; 2491 __len = __len - __half - 1; 2492 } 2493 else 2494 __len = __half; 2495 } 2496 return __first; 2497 } 2498 2499 template