Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/ranges
1 // <ranges> -*- C++ -*- 2 3 // Copyright (C) 2019-2025 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 // <http://www.gnu.org/licenses/>. 24 25 /** @file include/ranges 26 * This is a Standard C++ Library header. 27 * @ingroup concepts 28 */ 29 30 #ifndef _GLIBCXX_RANGES 31 #define _GLIBCXX_RANGES 1 32 33 #if __cplusplus > 201703L 34 35 #ifdef _GLIBCXX_SYSHDR 36 #pragma GCC system_header 37 #endif 38 39 #include <concepts> 40 41 #if __cpp_lib_concepts 42 43 #include <compare> 44 #include <initializer_list> 45 #include <iterator> 46 #include <optional> 47 #include <span> 48 #include <string_view> 49 #include <tuple> 50 #if __cplusplus > 202002L 51 #include <utility> 52 #include <variant> 53 #endif 54 #include <bits/ranges_util.h> 55 #include <bits/refwrap.h> 56 57 #define __glibcxx_want_algorithm_default_value_type 58 #define __glibcxx_want_ranges 59 #define __glibcxx_want_ranges_as_const 60 #define __glibcxx_want_ranges_as_rvalue 61 #define __glibcxx_want_ranges_cache_latest 62 #define __glibcxx_want_ranges_cartesian_product 63 #define __glibcxx_want_ranges_concat 64 #define __glibcxx_want_ranges_chunk 65 #define __glibcxx_want_ranges_chunk_by 66 #define __glibcxx_want_ranges_enumerate 67 #define __glibcxx_want_ranges_join_with 68 #define __glibcxx_want_ranges_repeat 69 #define __glibcxx_want_ranges_slide 70 #define __glibcxx_want_ranges_stride 71 #define __glibcxx_want_ranges_to_container 72 #define __glibcxx_want_ranges_to_input 73 #define __glibcxx_want_ranges_zip 74 #include <bits/version.h> 75 76 #ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine 77 # include <bits/elements_of.h> 78 #endif 79 80 /** 81 * @defgroup ranges Ranges 82 * 83 * Components for dealing with ranges of elements. 84 */ 85 86 namespace std _GLIBCXX_VISIBILITY(default) 87 { 88 _GLIBCXX_BEGIN_NAMESPACE_VERSION 89 namespace ranges 90 { 91 // [range.access] customization point objects 92 // [range.req] range and view concepts 93 // [range.dangling] dangling iterator handling 94 // Defined in <bits/ranges_base.h> 95 96 // [view.interface] View interface 97 // [range.subrange] Sub-ranges 98 // Defined in <bits/ranges_util.h> 99 100 // C++20 24.6 [range.factories] Range factories 101 102 /// A view that contains no elements. 103 template<typename _Tp> requires is_object_v<_Tp> 104 class empty_view 105 : public view_interface<empty_view<_Tp>> 106 { 107 public: 108 static constexpr _Tp* begin() noexcept { return nullptr; } 109 static constexpr _Tp* end() noexcept { return nullptr; } 110 static constexpr _Tp* data() noexcept { return nullptr; } 111 static constexpr size_t size() noexcept { return 0; } 112 static constexpr bool empty() noexcept { return true; } 113 }; 114 115 template<typename _Tp> 116 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true; 117 118 namespace __detail 119 { 120 #if __cpp_lib_ranges >= 202207L // C++ >= 23 121 // P2494R2 Relaxing range adaptors to allow for move only types 122 template<typename _Tp> 123 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>; 124 #else 125 template<typename _Tp> 126 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>; 127 #endif 128 129 template<__boxable _Tp> 130 struct __box : std::optional<_Tp> 131 { 132 using std::optional<_Tp>::optional; 133 134 constexpr 135 __box() 136 noexcept(is_nothrow_default_constructible_v<_Tp>) 137 requires default_initializable<_Tp> 138 : std::optional<_Tp>{std::in_place} 139 { } 140 141 __box(const __box&) = default; 142 __box(__box&&) = default; 143 144 using std::optional<_Tp>::operator=; 145 146 // _GLIBCXX_RESOLVE_LIB_DEFECTS 147 // 3477. Simplify constraints for semiregular-box 148 // 3572. copyable-box should be fully constexpr 149 constexpr __box& 150 operator=(const __box& __that) 151 noexcept(is_nothrow_copy_constructible_v<_Tp>) 152 requires (!copyable<_Tp>) && copy_constructible<_Tp> 153 { 154 if (this != std::__addressof(__that)) 155 { 156 if ((bool)__that) 157 this->emplace(*__that); 158 else 159 this->reset(); 160 } 161 return *this; 162 } 163 164 constexpr __box& 165 operator=(__box&& __that) 166 noexcept(is_nothrow_move_constructible_v<_Tp>) 167 requires (!movable<_Tp>) 168 { 169 if (this != std::__addressof(__that)) 170 { 171 if ((bool)__that) 172 this->emplace(std::move(*__that)); 173 else 174 this->reset(); 175 } 176 return *this; 177 } 178 }; 179 180 template<typename _Tp> 181 concept __boxable_copyable 182 = copy_constructible<_Tp> 183 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp> 184 && is_nothrow_copy_constructible_v<_Tp>)); 185 template<typename _Tp> 186 concept __boxable_movable 187 = (!copy_constructible<_Tp>) 188 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>); 189 190 // For types which are already copyable (or since C++23, movable) 191 // this specialization of the box wrapper stores the object directly 192 // without going through std::optional. It provides just the subset of 193 // the primary template's API that we currently use. 194 template<__boxable _Tp> 195 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp> 196 struct __box<_Tp> 197 { 198 private: 199 [[no_unique_address]] _Tp _M_value = _Tp(); 200 201 public: 202 __box() requires default_initializable<_Tp> = default; 203 204 constexpr explicit 205 __box(const _Tp& __t) 206 noexcept(is_nothrow_copy_constructible_v<_Tp>) 207 requires copy_constructible<_Tp> 208 : _M_value(__t) 209 { } 210 211 constexpr explicit 212 __box(_Tp&& __t) 213 noexcept(is_nothrow_move_constructible_v<_Tp>) 214 : _M_value(std::move(__t)) 215 { } 216 217 template<typename... _Args> 218 requires constructible_from<_Tp, _Args...> 219 constexpr explicit 220 __box(in_place_t, _Args&&... __args) 221 noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 222 : _M_value(std::forward<_Args>(__args)...) 223 { } 224 225 __box(const __box&) = default; 226 __box(__box&&) = default; 227 __box& operator=(const __box&) requires copyable<_Tp> = default; 228 __box& operator=(__box&&) requires movable<_Tp> = default; 229 230 // When _Tp is nothrow_copy_constructible but not copy_assignable, 231 // copy assignment is implemented via destroy-then-copy-construct. 232 constexpr __box& 233 operator=(const __box& __that) noexcept 234 requires (!copyable<_Tp>) && copy_constructible<_Tp> 235 { 236 static_assert(is_nothrow_copy_constructible_v<_Tp>); 237 if (this != std::__addressof(__that)) 238 { 239 _M_value.~_Tp(); 240 std::construct_at(std::__addressof(_M_value), *__that); 241 } 242 return *this; 243 } 244 245 // Likewise for move assignment. 246 constexpr __box& 247 operator=(__box&& __that) noexcept 248 requires (!movable<_Tp>) 249 { 250 static_assert(is_nothrow_move_constructible_v<_Tp>); 251 if (this != std::__addressof(__that)) 252 { 253 _M_value.~_Tp(); 254 std::construct_at(std::__addressof(_M_value), std::move(*__that)); 255 } 256 return *this; 257 } 258 259 constexpr bool 260 has_value() const noexcept 261 { return true; }; 262 263 constexpr _Tp& 264 operator*() & noexcept 265 { return _M_value; } 266 267 constexpr const _Tp& 268 operator*() const & noexcept 269 { return _M_value; } 270 271 constexpr _Tp&& 272 operator*() && noexcept 273 { return std::move(_M_value); } 274 275 constexpr const _Tp&& 276 operator*() const && noexcept 277 { return std::move(_M_value); } 278 279 constexpr _Tp* 280 operator->() noexcept 281 { return std::__addressof(_M_value); } 282 283 constexpr const _Tp* 284 operator->() const noexcept 285 { return std::__addressof(_M_value); } 286 }; 287 } // namespace __detail 288 289 /// A view that contains exactly one element. 290 #if __cpp_lib_ranges >= 202207L // C++ >= 23 291 template<move_constructible _Tp> 292 #else 293 template<copy_constructible _Tp> 294 #endif 295 requires is_object_v<_Tp> 296 class single_view : public view_interface<single_view<_Tp>> 297 { 298 public: 299 single_view() requires default_initializable<_Tp> = default; 300 301 constexpr explicit 302 single_view(const _Tp& __t) 303 noexcept(is_nothrow_copy_constructible_v<_Tp>) 304 requires copy_constructible<_Tp> 305 : _M_value(__t) 306 { } 307 308 constexpr explicit 309 single_view(_Tp&& __t) 310 noexcept(is_nothrow_move_constructible_v<_Tp>) 311 : _M_value(std::move(__t)) 312 { } 313 314 // _GLIBCXX_RESOLVE_LIB_DEFECTS 315 // 3428. single_view's in place constructor should be explicit 316 template<typename... _Args> 317 requires constructible_from<_Tp, _Args...> 318 constexpr explicit 319 single_view(in_place_t, _Args&&... __args) 320 noexcept(is_nothrow_constructible_v<_Tp, _Args...>) 321 : _M_value{in_place, std::forward<_Args>(__args)...} 322 { } 323 324 constexpr _Tp* 325 begin() noexcept 326 { return data(); } 327 328 constexpr const _Tp* 329 begin() const noexcept 330 { return data(); } 331 332 constexpr _Tp* 333 end() noexcept 334 { return data() + 1; } 335 336 constexpr const _Tp* 337 end() const noexcept 338 { return data() + 1; } 339 340 // _GLIBCXX_RESOLVE_LIB_DEFECTS 341 // 4035. single_view should provide empty 342 static constexpr bool 343 empty() noexcept 344 { return false; } 345 346 static constexpr size_t 347 size() noexcept 348 { return 1; } 349 350 constexpr _Tp* 351 data() noexcept 352 { return _M_value.operator->(); } 353 354 constexpr const _Tp* 355 data() const noexcept 356 { return _M_value.operator->(); } 357 358 private: 359 [[no_unique_address]] __detail::__box<_Tp> _M_value; 360 }; 361 362 template<typename _Tp> 363 single_view(_Tp) -> single_view<_Tp>; 364 365 namespace __detail 366 { 367 template<typename _Wp> 368 constexpr auto __to_signed_like(_Wp __w) noexcept 369 { 370 if constexpr (!integral<_Wp>) 371 return iter_difference_t<_Wp>(); 372 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp)) 373 return iter_difference_t<_Wp>(__w); 374 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp)) 375 return ptrdiff_t(__w); 376 else if constexpr (sizeof(long long) > sizeof(_Wp)) 377 return (long long)(__w); 378 #ifdef __SIZEOF_INT128__ 379 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp)) 380 return __int128(__w); 381 #endif 382 else 383 return __max_diff_type(__w); 384 } 385 386 template<typename _Wp> 387 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>())); 388 389 template<typename _It> 390 concept __decrementable = incrementable<_It> 391 && requires(_It __i) 392 { 393 { --__i } -> same_as<_It&>; 394 { __i-- } -> same_as<_It>; 395 }; 396 397 template<typename _It> 398 concept __advanceable = __decrementable<_It> && totally_ordered<_It> 399 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n) 400 { 401 { __i += __n } -> same_as<_It&>; 402 { __i -= __n } -> same_as<_It&>; 403 _It(__j + __n); 404 _It(__n + __j); 405 _It(__j - __n); 406 { __j - __j } -> convertible_to<__iota_diff_t<_It>>; 407 }; 408 409 template<typename _Winc> 410 struct __iota_view_iter_cat 411 { }; 412 413 template<incrementable _Winc> 414 struct __iota_view_iter_cat<_Winc> 415 { using iterator_category = input_iterator_tag; }; 416 } // namespace __detail 417 418 template<weakly_incrementable _Winc, 419 semiregular _Bound = unreachable_sentinel_t> 420 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound> 421 && copyable<_Winc> 422 class iota_view : public view_interface<iota_view<_Winc, _Bound>> 423 { 424 private: 425 struct _Sentinel; 426 427 struct _Iterator : __detail::__iota_view_iter_cat<_Winc> 428 { 429 private: 430 static auto 431 _S_iter_concept() 432 { 433 using namespace __detail; 434 if constexpr (__advanceable<_Winc>) 435 return random_access_iterator_tag{}; 436 else if constexpr (__decrementable<_Winc>) 437 return bidirectional_iterator_tag{}; 438 else if constexpr (incrementable<_Winc>) 439 return forward_iterator_tag{}; 440 else 441 return input_iterator_tag{}; 442 } 443 444 public: 445 using iterator_concept = decltype(_S_iter_concept()); 446 // iterator_category defined in __iota_view_iter_cat 447 using value_type = _Winc; 448 using difference_type = __detail::__iota_diff_t<_Winc>; 449 450 _Iterator() requires default_initializable<_Winc> = default; 451 452 constexpr explicit 453 _Iterator(_Winc __value) 454 : _M_value(__value) { } 455 456 constexpr _Winc 457 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>) 458 { return _M_value; } 459 460 constexpr _Iterator& 461 operator++() 462 { 463 ++_M_value; 464 return *this; 465 } 466 467 constexpr void 468 operator++(int) 469 { ++*this; } 470 471 constexpr _Iterator 472 operator++(int) requires incrementable<_Winc> 473 { 474 auto __tmp = *this; 475 ++*this; 476 return __tmp; 477 } 478 479 constexpr _Iterator& 480 operator--() requires __detail::__decrementable<_Winc> 481 { 482 --_M_value; 483 return *this; 484 } 485 486 constexpr _Iterator 487 operator--(int) requires __detail::__decrementable<_Winc> 488 { 489 auto __tmp = *this; 490 --*this; 491 return __tmp; 492 } 493 494 constexpr _Iterator& 495 operator+=(difference_type __n) requires __detail::__advanceable<_Winc> 496 { 497 using __detail::__is_integer_like; 498 using __detail::__is_signed_integer_like; 499 if constexpr (__is_integer_like<_Winc> 500 && !__is_signed_integer_like<_Winc>) 501 { 502 if (__n >= difference_type(0)) 503 _M_value += static_cast<_Winc>(__n); 504 else 505 _M_value -= static_cast<_Winc>(-__n); 506 } 507 else 508 _M_value += __n; 509 return *this; 510 } 511 512 constexpr _Iterator& 513 operator-=(difference_type __n) requires __detail::__advanceable<_Winc> 514 { 515 using __detail::__is_integer_like; 516 using __detail::__is_signed_integer_like; 517 if constexpr (__is_integer_like<_Winc> 518 && !__is_signed_integer_like<_Winc>) 519 { 520 if (__n >= difference_type(0)) 521 _M_value -= static_cast<_Winc>(__n); 522 else 523 _M_value += static_cast<_Winc>(-__n); 524 } 525 else 526 _M_value -= __n; 527 return *this; 528 } 529 530 constexpr _Winc 531 operator[](difference_type __n) const 532 requires __detail::__advanceable<_Winc> 533 { return _Winc(_M_value + __n); } 534 535 friend constexpr bool 536 operator==(const _Iterator& __x, const _Iterator& __y) 537 requires equality_comparable<_Winc> 538 { return __x._M_value == __y._M_value; } 539 540 friend constexpr bool 541 operator<(const _Iterator& __x, const _Iterator& __y) 542 requires totally_ordered<_Winc> 543 { return __x._M_value < __y._M_value; } 544 545 friend constexpr bool 546 operator>(const _Iterator& __x, const _Iterator& __y) 547 requires totally_ordered<_Winc> 548 { return __y < __x; } 549 550 friend constexpr bool 551 operator<=(const _Iterator& __x, const _Iterator& __y) 552 requires totally_ordered<_Winc> 553 { return !(__y < __x); } 554 555 friend constexpr bool 556 operator>=(const _Iterator& __x, const _Iterator& __y) 557 requires totally_ordered<_Winc> 558 { return !(__x < __y); } 559 560 #ifdef __cpp_lib_three_way_comparison 561 friend constexpr auto 562 operator<=>(const _Iterator& __x, const _Iterator& __y) 563 requires totally_ordered<_Winc> && three_way_comparable<_Winc> 564 { return __x._M_value <=> __y._M_value; } 565 #endif 566 567 friend constexpr _Iterator 568 operator+(_Iterator __i, difference_type __n) 569 requires __detail::__advanceable<_Winc> 570 { 571 __i += __n; 572 return __i; 573 } 574 575 friend constexpr _Iterator 576 operator+(difference_type __n, _Iterator __i) 577 requires __detail::__advanceable<_Winc> 578 { return __i += __n; } 579 580 friend constexpr _Iterator 581 operator-(_Iterator __i, difference_type __n) 582 requires __detail::__advanceable<_Winc> 583 { 584 __i -= __n; 585 return __i; 586 } 587 588 friend constexpr difference_type 589 operator-(const _Iterator& __x, const _Iterator& __y) 590 requires __detail::__advanceable<_Winc> 591 { 592 using __detail::__is_integer_like; 593 using __detail::__is_signed_integer_like; 594 using _Dt = difference_type; 595 if constexpr (__is_integer_like<_Winc>) 596 { 597 if constexpr (__is_signed_integer_like<_Winc>) 598 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value)); 599 else 600 return (__y._M_value > __x._M_value) 601 ? _Dt(-_Dt(__y._M_value - __x._M_value)) 602 : _Dt(__x._M_value - __y._M_value); 603 } 604 else 605 return __x._M_value - __y._M_value; 606 } 607 608 private: 609 _Winc _M_value = _Winc(); 610 611 friend iota_view; 612 friend _Sentinel; 613 }; 614 615 struct _Sentinel 616 { 617 private: 618 constexpr bool 619 _M_equal(const _Iterator& __x) const 620 { return __x._M_value == _M_bound; } 621 622 constexpr auto 623 _M_distance_from(const _Iterator& __x) const 624 { return _M_bound - __x._M_value; } 625 626 _Bound _M_bound = _Bound(); 627 628 public: 629 _Sentinel() = default; 630 631 constexpr explicit 632 _Sentinel(_Bound __bound) 633 : _M_bound(__bound) { } 634 635 friend constexpr bool 636 operator==(const _Iterator& __x, const _Sentinel& __y) 637 { return __y._M_equal(__x); } 638 639 friend constexpr iter_difference_t<_Winc> 640 operator-(const _Iterator& __x, const _Sentinel& __y) 641 requires sized_sentinel_for<_Bound, _Winc> 642 { return -__y._M_distance_from(__x); } 643 644 friend constexpr iter_difference_t<_Winc> 645 operator-(const _Sentinel& __x, const _Iterator& __y) 646 requires sized_sentinel_for<_Bound, _Winc> 647 { return __x._M_distance_from(__y); } 648 649 friend iota_view; 650 }; 651 652 _Winc _M_value = _Winc(); 653 [[no_unique_address]] _Bound _M_bound = _Bound(); 654 655 public: 656 iota_view() requires default_initializable<_Winc> = default; 657 658 constexpr explicit 659 iota_view(_Winc __value) 660 : _M_value(__value) 661 { } 662 663 constexpr 664 iota_view(type_identity_t<_Winc> __value, 665 type_identity_t<_Bound> __bound) 666 : _M_value(__value), _M_bound(__bound) 667 { 668 if constexpr (totally_ordered_with<_Winc, _Bound>) 669 __glibcxx_assert( bool(__value <= __bound) ); 670 } 671 672 constexpr 673 iota_view(_Iterator __first, _Iterator __last) 674 requires same_as<_Winc, _Bound> 675 : iota_view(__first._M_value, __last._M_value) 676 { } 677 678 constexpr 679 iota_view(_Iterator __first, unreachable_sentinel_t __last) 680 requires same_as<_Bound, unreachable_sentinel_t> 681 : iota_view(__first._M_value, __last) 682 { } 683 684 constexpr 685 iota_view(_Iterator __first, _Sentinel __last) 686 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>) 687 : iota_view(__first._M_value, __last._M_bound) 688 { } 689 690 constexpr _Iterator 691 begin() const { return _Iterator{_M_value}; } 692 693 constexpr auto 694 end() const 695 { 696 if constexpr (same_as<_Bound, unreachable_sentinel_t>) 697 return unreachable_sentinel; 698 else 699 return _Sentinel{_M_bound}; 700 } 701 702 constexpr _Iterator 703 end() const requires same_as<_Winc, _Bound> 704 { return _Iterator{_M_bound}; } 705 706 // _GLIBCXX_RESOLVE_LIB_DEFECTS 707 // 4001. iota_view should provide empty 708 constexpr bool 709 empty() const 710 { return _M_value == _M_bound; } 711 712 constexpr auto 713 size() const 714 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>) 715 || (integral<_Winc> && integral<_Bound>) 716 || sized_sentinel_for<_Bound, _Winc> 717 { 718 using __detail::__is_integer_like; 719 using __detail::__to_unsigned_like; 720 if constexpr (integral<_Winc> && integral<_Bound>) 721 { 722 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>; 723 return _Up(_M_bound) - _Up(_M_value); 724 } 725 else if constexpr (__is_integer_like<_Winc>) 726 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value); 727 else 728 return __to_unsigned_like(_M_bound - _M_value); 729 } 730 }; 731 732 template<typename _Winc, typename _Bound> 733 requires (!__detail::__is_integer_like<_Winc> 734 || !__detail::__is_integer_like<_Bound> 735 || (__detail::__is_signed_integer_like<_Winc> 736 == __detail::__is_signed_integer_like<_Bound>)) 737 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>; 738 739 template<typename _Winc, typename _Bound> 740 inline constexpr bool 741 enable_borrowed_range<iota_view<_Winc, _Bound>> = true; 742 743 namespace views 744 { 745 template<typename _Tp> 746 inline constexpr empty_view<_Tp> empty{}; 747 748 namespace __detail 749 { 750 template<typename _Tp> 751 concept __can_single_view 752 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); }; 753 } // namespace __detail 754 755 struct _Single 756 { 757 template<__detail::__can_single_view _Tp> 758 constexpr auto 759 operator() [[nodiscard]] (_Tp&& __e) const 760 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)))) 761 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); } 762 }; 763 764 inline constexpr _Single single{}; 765 766 namespace __detail 767 { 768 template<typename... _Args> 769 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); }; 770 } // namespace __detail 771 772 struct _Iota 773 { 774 template<__detail::__can_iota_view _Tp> 775 constexpr auto 776 operator() [[nodiscard]] (_Tp&& __e) const 777 { return iota_view(std::forward<_Tp>(__e)); } 778 779 template<typename _Tp, typename _Up> 780 requires __detail::__can_iota_view<_Tp, _Up> 781 constexpr auto 782 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const 783 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); } 784 }; 785 786 inline constexpr _Iota iota{}; 787 } // namespace views 788 789 #if _GLIBCXX_HOSTED 790 namespace __detail 791 { 792 template<typename _Val, typename _CharT, typename _Traits> 793 concept __stream_extractable 794 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; }; 795 } // namespace __detail 796 797 template<movable _Val, typename _CharT, 798 typename _Traits = char_traits<_CharT>> 799 requires default_initializable<_Val> 800 && __detail::__stream_extractable<_Val, _CharT, _Traits> 801 class basic_istream_view 802 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>> 803 { 804 public: 805 constexpr explicit 806 basic_istream_view(basic_istream<_CharT, _Traits>& __stream) 807 : _M_stream(std::__addressof(__stream)) 808 { } 809 810 constexpr auto 811 begin() 812 { 813 *_M_stream >> _M_object; 814 return _Iterator{this}; 815 } 816 817 constexpr default_sentinel_t 818 end() const noexcept 819 { return default_sentinel; } 820 821 private: 822 basic_istream<_CharT, _Traits>* _M_stream; 823 _Val _M_object = _Val(); 824 825 struct _Iterator 826 { 827 public: 828 using iterator_concept = input_iterator_tag; 829 using difference_type = ptrdiff_t; 830 using value_type = _Val; 831 832 constexpr explicit 833 _Iterator(basic_istream_view* __parent) noexcept 834 : _M_parent(__parent) 835 { } 836 837 _Iterator(const _Iterator&) = delete; 838 _Iterator(_Iterator&&) = default; 839 _Iterator& operator=(const _Iterator&) = delete; 840 _Iterator& operator=(_Iterator&&) = default; 841 842 _Iterator& 843 operator++() 844 { 845 *_M_parent->_M_stream >> _M_parent->_M_object; 846 return *this; 847 } 848 849 void 850 operator++(int) 851 { ++*this; } 852 853 _Val& 854 operator*() const 855 { return _M_parent->_M_object; } 856 857 friend bool 858 operator==(const _Iterator& __x, default_sentinel_t) 859 { return __x._M_at_end(); } 860 861 private: 862 basic_istream_view* _M_parent; 863 864 bool 865 _M_at_end() const 866 { return !*_M_parent->_M_stream; } 867 }; 868 869 friend _Iterator; 870 }; 871 872 template<typename _Val> 873 using istream_view = basic_istream_view<_Val, char>; 874 875 template<typename _Val> 876 using wistream_view = basic_istream_view<_Val, wchar_t>; 877 878 namespace views 879 { 880 namespace __detail 881 { 882 template<typename _Tp, typename _Up> 883 concept __can_istream_view = requires (_Up __e) { 884 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e); 885 }; 886 } // namespace __detail 887 888 template<typename _Tp> 889 struct _Istream 890 { 891 template<typename _CharT, typename _Traits> 892 constexpr auto 893 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const 894 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>> 895 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); } 896 }; 897 898 template<typename _Tp> 899 inline constexpr _Istream<_Tp> istream; 900 } 901 #endif // HOSTED 902 903 // C++20 24.7 [range.adaptors] Range adaptors 904 905 namespace __detail 906 { 907 template<typename _Tp, int _Disc> 908 struct _Absent { }; 909 910 // Alias for a type that is conditionally present 911 // (and is an empty type otherwise). 912 // Data members using this alias should use [[no_unique_address]] so that 913 // they take no space when not needed. 914 // The optional template parameter _Disc is for discriminating two otherwise 915 // equivalent absent types so that even they can overlap. 916 template<bool _Present, typename _Tp, int _Disc = 0> 917 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>; 918 919 // Alias for a type that is conditionally const. 920 template<bool _Const, typename _Tp> 921 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>; 922 923 } // namespace __detail 924 925 // Shorthand for __detail::__maybe_const_t. 926 using __detail::__maybe_const_t; 927 928 namespace views::__adaptor 929 { 930 // True if the range adaptor _Adaptor can be applied with _Args. 931 template<typename _Adaptor, typename... _Args> 932 concept __adaptor_invocable 933 = requires { std::declval<_Adaptor>()(declval<_Args>()...); }; 934 935 // True if the range adaptor non-closure _Adaptor can be partially applied 936 // with _Args. 937 template<typename _Adaptor, typename... _Args> 938 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1) 939 && (sizeof...(_Args) == _Adaptor::_S_arity - 1) 940 && (constructible_from<decay_t<_Args>, _Args> && ...); 941 942 template<typename _Adaptor, typename... _Args> 943 struct _Partial; 944 945 template<typename _Lhs, typename _Rhs> 946 struct _Pipe; 947 948 // The base class of every range adaptor closure. 949 // 950 // The derived class should define the optional static data member 951 // _S_has_simple_call_op to true if the behavior of this adaptor is 952 // independent of the constness/value category of the adaptor object. 953 template<typename _Derived> 954 struct _RangeAdaptorClosure; 955 956 template<typename _Tp, typename _Up> 957 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>) 958 void __is_range_adaptor_closure_fn 959 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined 960 961 template<typename _Tp> 962 concept __is_range_adaptor_closure 963 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); }; 964 965 #pragma GCC diagnostic push 966 #pragma GCC diagnostic ignored "-Wdangling-reference" 967 // range | adaptor is equivalent to adaptor(range). 968 template<typename _Self, typename _Range> 969 requires __is_range_adaptor_closure<_Self> 970 && __adaptor_invocable<_Self, _Range> 971 constexpr auto 972 operator|(_Range&& __r, _Self&& __self) 973 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); } 974 975 // Compose the adaptors __lhs and __rhs into a pipeline, returning 976 // another range adaptor closure object. 977 template<typename _Lhs, typename _Rhs> 978 requires __is_range_adaptor_closure<_Lhs> 979 && __is_range_adaptor_closure<_Rhs> 980 constexpr auto 981 operator|(_Lhs&& __lhs, _Rhs&& __rhs) 982 { 983 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs), 984 std::forward<_Rhs>(__rhs)}; 985 } 986 #pragma GCC diagnostic pop 987 988 template<typename _Derived> 989 struct _RangeAdaptorClosure 990 { 991 // In non-modules compilation ADL finds these operators either way and 992 // the friend declarations are redundant. But with the std module these 993 // friend declarations enable ADL to find these operators without having 994 // to export them. 995 template<typename _Self, typename _Range> 996 requires __is_range_adaptor_closure<_Self> 997 && __adaptor_invocable<_Self, _Range> 998 friend constexpr auto 999 operator|(_Range&& __r, _Self&& __self); 1000 1001 template<typename _Lhs, typename _Rhs> 1002 requires __is_range_adaptor_closure<_Lhs> 1003 && __is_range_adaptor_closure<_Rhs> 1004 friend constexpr auto 1005 operator|(_Lhs&& __lhs, _Rhs&& __rhs); 1006 }; 1007 1008 // The base class of every range adaptor non-closure. 1009 // 1010 // The static data member _Derived::_S_arity must contain the total number of 1011 // arguments that the adaptor takes, and the class _Derived must introduce 1012 // _RangeAdaptor::operator() into the class scope via a using-declaration. 1013 // 1014 // The optional static data member _Derived::_S_has_simple_extra_args should 1015 // be defined to true if the behavior of this adaptor is independent of the 1016 // constness/value category of the extra arguments. This data member could 1017 // also be defined as a variable template parameterized by the types of the 1018 // extra arguments. 1019 template<typename _Derived> 1020 struct _RangeAdaptor 1021 { 1022 // Partially apply the arguments __args to the range adaptor _Derived, 1023 // returning a range adaptor closure object. 1024 template<typename... _Args> 1025 requires __adaptor_partial_app_viable<_Derived, _Args...> 1026 constexpr auto 1027 operator()(_Args&&... __args) const 1028 { 1029 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...}; 1030 } 1031 }; 1032 1033 // True if the range adaptor closure _Adaptor has a simple operator(), i.e. 1034 // one that's not overloaded according to constness or value category of the 1035 // _Adaptor object. 1036 template<typename _Adaptor> 1037 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op; 1038 1039 // True if the behavior of the range adaptor non-closure _Adaptor is 1040 // independent of the value category of its extra arguments _Args. 1041 template<typename _Adaptor, typename... _Args> 1042 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args 1043 || _Adaptor::template _S_has_simple_extra_args<_Args...>; 1044 1045 // A range adaptor closure that represents partial application of 1046 // the range adaptor _Adaptor with arguments _Args. 1047 template<typename _Adaptor, typename... _Args> 1048 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>> 1049 { 1050 tuple<_Args...> _M_args; 1051 1052 // First parameter is to ensure this constructor is never used 1053 // instead of the copy/move constructor. 1054 template<typename... _Ts> 1055 constexpr 1056 _Partial(int, _Ts&&... __args) 1057 : _M_args(std::forward<_Ts>(__args)...) 1058 { } 1059 1060 // Invoke _Adaptor with arguments __r, _M_args... according to the 1061 // value category of this _Partial object. 1062 #if __cpp_explicit_this_parameter 1063 template<typename _Self, typename _Range> 1064 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...> 1065 constexpr auto 1066 operator()(this _Self&& __self, _Range&& __r) 1067 { 1068 auto __forwarder = [&__r] (auto&&... __args) { 1069 return _Adaptor{}(std::forward<_Range>(__r), 1070 std::forward<decltype(__args)>(__args)...); 1071 }; 1072 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args); 1073 } 1074 #else 1075 template<typename _Range> 1076 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...> 1077 constexpr auto 1078 operator()(_Range&& __r) const & 1079 { 1080 auto __forwarder = [&__r] (const auto&... __args) { 1081 return _Adaptor{}(std::forward<_Range>(__r), __args...); 1082 }; 1083 return std::apply(__forwarder, _M_args); 1084 } 1085 1086 template<typename _Range> 1087 requires __adaptor_invocable<_Adaptor, _Range, _Args...> 1088 constexpr auto 1089 operator()(_Range&& __r) && 1090 { 1091 auto __forwarder = [&__r] (auto&... __args) { 1092 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...); 1093 }; 1094 return std::apply(__forwarder, _M_args); 1095 } 1096 1097 template<typename _Range> 1098 constexpr auto 1099 operator()(_Range&& __r) const && = delete; 1100 #endif 1101 }; 1102 1103 // A lightweight specialization of the above primary template for 1104 // the common case where _Adaptor accepts a single extra argument. 1105 template<typename _Adaptor, typename _Arg> 1106 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>> 1107 { 1108 _Arg _M_arg; 1109 1110 template<typename _Tp> 1111 constexpr 1112 _Partial(int, _Tp&& __arg) 1113 : _M_arg(std::forward<_Tp>(__arg)) 1114 { } 1115 1116 #if __cpp_explicit_this_parameter 1117 template<typename _Self, typename _Range> 1118 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>> 1119 constexpr auto 1120 operator()(this _Self&& __self, _Range&& __r) 1121 { 1122 return _Adaptor{}(std::forward<_Range>(__r), 1123 __like_t<_Self, _Partial>(__self)._M_arg); 1124 } 1125 #else 1126 template<typename _Range> 1127 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&> 1128 constexpr auto 1129 operator()(_Range&& __r) const & 1130 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); } 1131 1132 template<typename _Range> 1133 requires __adaptor_invocable<_Adaptor, _Range, _Arg> 1134 constexpr auto 1135 operator()(_Range&& __r) && 1136 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); } 1137 1138 template<typename _Range> 1139 constexpr auto 1140 operator()(_Range&& __r) const && = delete; 1141 #endif 1142 }; 1143 1144 // Partial specialization of the primary template for the case where the extra 1145 // arguments of the adaptor can always be safely and efficiently forwarded by 1146 // const reference. This lets us get away with a single operator() overload, 1147 // which makes overload resolution failure diagnostics more concise. 1148 template<typename _Adaptor, typename... _Args> 1149 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...> 1150 && (is_trivially_copy_constructible_v<_Args> && ...) 1151 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>> 1152 { 1153 tuple<_Args...> _M_args; 1154 1155 template<typename... _Ts> 1156 constexpr 1157 _Partial(int, _Ts&&... __args) 1158 : _M_args(std::forward<_Ts>(__args)...) 1159 { } 1160 1161 // Invoke _Adaptor with arguments __r, const _M_args&... regardless 1162 // of the value category of this _Partial object. 1163 template<typename _Range> 1164 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...> 1165 constexpr auto 1166 operator()(_Range&& __r) const 1167 { 1168 auto __forwarder = [&__r] (const auto&... __args) { 1169 return _Adaptor{}(std::forward<_Range>(__r), __args...); 1170 }; 1171 return std::apply(__forwarder, _M_args); 1172 } 1173 1174 static constexpr bool _S_has_simple_call_op = true; 1175 }; 1176 1177 // A lightweight specialization of the above template for the common case 1178 // where _Adaptor accepts a single extra argument. 1179 template<typename _Adaptor, typename _Arg> 1180 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg> 1181 && is_trivially_copy_constructible_v<_Arg> 1182 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>> 1183 { 1184 _Arg _M_arg; 1185 1186 template<typename _Tp> 1187 constexpr 1188 _Partial(int, _Tp&& __arg) 1189 : _M_arg(std::forward<_Tp>(__arg)) 1190 { } 1191 1192 template<typename _Range> 1193 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&> 1194 constexpr auto 1195 operator()(_Range&& __r) const 1196 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); } 1197 1198 static constexpr bool _S_has_simple_call_op = true; 1199 }; 1200 1201 template<typename _Lhs, typename _Rhs, typename _Range> 1202 concept __pipe_invocable 1203 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); }; 1204 1205 // A range adaptor closure that represents composition of the range 1206 // adaptor closures _Lhs and _Rhs. 1207 template<typename _Lhs, typename _Rhs> 1208 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>> 1209 { 1210 [[no_unique_address]] _Lhs _M_lhs; 1211 [[no_unique_address]] _Rhs _M_rhs; 1212 1213 template<typename _Tp, typename _Up> 1214 constexpr 1215 _Pipe(_Tp&& __lhs, _Up&& __rhs) 1216 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs)) 1217 { } 1218 1219 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this 1220 // range adaptor closure object. 1221 #if __cpp_explicit_this_parameter 1222 template<typename _Self, typename _Range> 1223 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range> 1224 constexpr auto 1225 operator()(this _Self&& __self, _Range&& __r) 1226 { 1227 return (__like_t<_Self, _Pipe>(__self)._M_rhs 1228 (__like_t<_Self, _Pipe>(__self)._M_lhs 1229 (std::forward<_Range>(__r)))); 1230 } 1231 #else 1232 template<typename _Range> 1233 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range> 1234 constexpr auto 1235 operator()(_Range&& __r) const & 1236 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); } 1237 1238 template<typename _Range> 1239 requires __pipe_invocable<_Lhs, _Rhs, _Range> 1240 constexpr auto 1241 operator()(_Range&& __r) && 1242 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); } 1243 1244 template<typename _Range> 1245 constexpr auto 1246 operator()(_Range&& __r) const && = delete; 1247 #endif 1248 }; 1249 1250 // A partial specialization of the above primary template for the case where 1251 // both adaptor operands have a simple operator(). This in turn lets us 1252 // implement composition using a single simple operator(), which makes 1253 // overload resolution failure diagnostics more concise. 1254 template<typename _Lhs, typename _Rhs> 1255 requires __closure_has_simple_call_op<_Lhs> 1256 && __closure_has_simple_call_op<_Rhs> 1257 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>> 1258 { 1259 [[no_unique_address]] _Lhs _M_lhs; 1260 [[no_unique_address]] _Rhs _M_rhs; 1261 1262 template<typename _Tp, typename _Up> 1263 constexpr 1264 _Pipe(_Tp&& __lhs, _Up&& __rhs) 1265 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs)) 1266 { } 1267 1268 template<typename _Range> 1269 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range> 1270 constexpr auto 1271 operator()(_Range&& __r) const 1272 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); } 1273 1274 static constexpr bool _S_has_simple_call_op = true; 1275 }; 1276 } // namespace views::__adaptor 1277 1278 #if __cpp_lib_ranges >= 202202L 1279 // P2387R3 Pipe support for user-defined range adaptors 1280 template<typename _Derived> 1281 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> 1282 class range_adaptor_closure 1283 : public views::__adaptor::_RangeAdaptorClosure<_Derived> 1284 { }; 1285 #endif 1286 1287 template<range _Range> requires is_object_v<_Range> 1288 class ref_view : public view_interface<ref_view<_Range>> 1289 { 1290 private: 1291 _Range* _M_r; 1292 1293 static void _S_fun(_Range&); // not defined 1294 static void _S_fun(_Range&&) = delete; 1295 1296 public: 1297 template<__detail::__different_from<ref_view> _Tp> 1298 requires convertible_to<_Tp, _Range&> 1299 && requires { _S_fun(declval<_Tp>()); } 1300 constexpr 1301 ref_view(_Tp&& __t) 1302 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>()))) 1303 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t)))) 1304 { } 1305 1306 constexpr _Range& 1307 base() const 1308 { return *_M_r; } 1309 1310 constexpr iterator_t<_Range> 1311 begin() const 1312 { return ranges::begin(*_M_r); } 1313 1314 constexpr sentinel_t<_Range> 1315 end() const 1316 { return ranges::end(*_M_r); } 1317 1318 constexpr bool 1319 empty() const requires requires { ranges::empty(*_M_r); } 1320 { return ranges::empty(*_M_r); } 1321 1322 constexpr auto 1323 size() const requires sized_range<_Range> 1324 { return ranges::size(*_M_r); } 1325 1326 constexpr auto 1327 data() const requires contiguous_range<_Range> 1328 { return ranges::data(*_M_r); } 1329 }; 1330 1331 template<typename _Range> 1332 ref_view(_Range&) -> ref_view<_Range>; 1333 1334 template<typename _Tp> 1335 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true; 1336 1337 template<range _Range> 1338 requires movable<_Range> 1339 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>) 1340 class owning_view : public view_interface<owning_view<_Range>> 1341 { 1342 private: 1343 _Range _M_r = _Range(); 1344 1345 public: 1346 owning_view() requires default_initializable<_Range> = default; 1347 1348 constexpr 1349 owning_view(_Range&& __t) 1350 noexcept(is_nothrow_move_constructible_v<_Range>) 1351 : _M_r(std::move(__t)) 1352 { } 1353 1354 owning_view(owning_view&&) = default; 1355 owning_view& operator=(owning_view&&) = default; 1356 1357 constexpr _Range& 1358 base() & noexcept 1359 { return _M_r; } 1360 1361 constexpr const _Range& 1362 base() const& noexcept 1363 { return _M_r; } 1364 1365 constexpr _Range&& 1366 base() && noexcept 1367 { return std::move(_M_r); } 1368 1369 constexpr const _Range&& 1370 base() const&& noexcept 1371 { return std::move(_M_r); } 1372 1373 constexpr iterator_t<_Range> 1374 begin() 1375 { return ranges::begin(_M_r); } 1376 1377 constexpr sentinel_t<_Range> 1378 end() 1379 { return ranges::end(_M_r); } 1380 1381 constexpr auto 1382 begin() const requires range<const _Range> 1383 { return ranges::begin(_M_r); } 1384 1385 constexpr auto 1386 end() const requires range<const _Range> 1387 { return ranges::end(_M_r); } 1388 1389 constexpr bool 1390 empty() requires requires { ranges::empty(_M_r); } 1391 { return ranges::empty(_M_r); } 1392 1393 constexpr bool 1394 empty() const requires requires { ranges::empty(_M_r); } 1395 { return ranges::empty(_M_r); } 1396 1397 constexpr auto 1398 size() requires sized_range<_Range> 1399 { return ranges::size(_M_r); } 1400 1401 constexpr auto 1402 size() const requires sized_range<const _Range> 1403 { return ranges::size(_M_r); } 1404 1405 constexpr auto 1406 data() requires contiguous_range<_Range> 1407 { return ranges::data(_M_r); } 1408 1409 constexpr auto 1410 data() const requires contiguous_range<const _Range> 1411 { return ranges::data(_M_r); } 1412 }; 1413 1414 template<typename _Tp> 1415 inline constexpr bool enable_borrowed_range<owning_view<_Tp>> 1416 = enable_borrowed_range<_Tp>; 1417 1418 namespace views 1419 { 1420 namespace __detail 1421 { 1422 template<typename _Range> 1423 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; }; 1424 1425 template<typename _Range> 1426 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; }; 1427 } // namespace __detail 1428 1429 struct _All : __adaptor::_RangeAdaptorClosure<_All> 1430 { 1431 template<typename _Range> 1432 static constexpr bool 1433 _S_noexcept() 1434 { 1435 if constexpr (view<decay_t<_Range>>) 1436 return is_nothrow_constructible_v<decay_t<_Range>, _Range>; 1437 else if constexpr (__detail::__can_ref_view<_Range>) 1438 return true; 1439 else 1440 return noexcept(owning_view{std::declval<_Range>()}); 1441 } 1442 1443 template<viewable_range _Range> 1444 requires view<decay_t<_Range>> 1445 || __detail::__can_ref_view<_Range> 1446 || __detail::__can_owning_view<_Range> 1447 constexpr auto 1448 operator() [[nodiscard]] (_Range&& __r) const 1449 noexcept(_S_noexcept<_Range>()) 1450 { 1451 if constexpr (view<decay_t<_Range>>) 1452 return std::forward<_Range>(__r); 1453 else if constexpr (__detail::__can_ref_view<_Range>) 1454 return ref_view{std::forward<_Range>(__r)}; 1455 else 1456 return owning_view{std::forward<_Range>(__r)}; 1457 } 1458 1459 static constexpr bool _S_has_simple_call_op = true; 1460 }; 1461 1462 inline constexpr _All all; 1463 1464 template<viewable_range _Range> 1465 using all_t = decltype(all(std::declval<_Range>())); 1466 } // namespace views 1467 1468 namespace __detail 1469 { 1470 template<typename _Tp> 1471 struct __non_propagating_cache 1472 { 1473 // When _Tp is not an object type (e.g. is a reference type), we make 1474 // __non_propagating_cache<_Tp> empty rather than ill-formed so that 1475 // users can easily conditionally declare data members with this type 1476 // (such as join_view::_M_inner). 1477 }; 1478 1479 template<typename _Tp> 1480 requires is_object_v<_Tp> 1481 struct __non_propagating_cache<_Tp> 1482 : protected _Optional_base<_Tp> 1483 { 1484 __non_propagating_cache() = default; 1485 1486 constexpr 1487 __non_propagating_cache(const __non_propagating_cache&) noexcept 1488 { } 1489 1490 constexpr 1491 __non_propagating_cache(__non_propagating_cache&& __other) noexcept 1492 { __other._M_reset(); } 1493 1494 constexpr __non_propagating_cache& 1495 operator=(const __non_propagating_cache& __other) noexcept 1496 { 1497 if (std::__addressof(__other) != this) 1498 this->_M_reset(); 1499 return *this; 1500 } 1501 1502 constexpr __non_propagating_cache& 1503 operator=(__non_propagating_cache&& __other) noexcept 1504 { 1505 this->_M_reset(); 1506 __other._M_reset(); 1507 return *this; 1508 } 1509 1510 constexpr __non_propagating_cache& 1511 operator=(_Tp __val) 1512 { 1513 this->_M_reset(); 1514 this->_M_payload._M_construct(std::move(__val)); 1515 return *this; 1516 } 1517 1518 constexpr explicit 1519 operator bool() const noexcept 1520 { return this->_M_is_engaged(); } 1521 1522 constexpr _Tp& 1523 operator*() noexcept 1524 { return this->_M_get(); } 1525 1526 constexpr const _Tp& 1527 operator*() const noexcept 1528 { return this->_M_get(); } 1529 1530 template<typename _Iter> 1531 constexpr _Tp& 1532 _M_emplace_deref(const _Iter& __i) 1533 { 1534 this->_M_reset(); 1535 auto __f = [] (auto& __x) { return *__x; }; 1536 this->_M_payload._M_apply(_Optional_func{__f}, __i); 1537 return this->_M_get(); 1538 } 1539 1540 using _Optional_base<_Tp>::_M_reset; 1541 }; 1542 1543 template<range _Range> 1544 struct _CachedPosition 1545 { 1546 constexpr bool 1547 _M_has_value() const 1548 { return false; } 1549 1550 constexpr iterator_t<_Range> 1551 _M_get(const _Range&) const 1552 { 1553 __glibcxx_assert(false); 1554 __builtin_unreachable(); 1555 } 1556 1557 constexpr void 1558 _M_set(const _Range&, const iterator_t<_Range>&) const 1559 { } 1560 }; 1561 1562 template<forward_range _Range> 1563 struct _CachedPosition<_Range> 1564 : protected __non_propagating_cache<iterator_t<_Range>> 1565 { 1566 constexpr bool 1567 _M_has_value() const 1568 { return this->_M_is_engaged(); } 1569 1570 constexpr iterator_t<_Range> 1571 _M_get(const _Range&) const 1572 { 1573 __glibcxx_assert(_M_has_value()); 1574 return **this; 1575 } 1576 1577 constexpr void 1578 _M_set(const _Range&, const iterator_t<_Range>& __it) 1579 { 1580 __glibcxx_assert(!_M_has_value()); 1581 std::construct_at(std::__addressof(this->_M_payload._M_payload), 1582 in_place, __it); 1583 this->_M_payload._M_engaged = true; 1584 } 1585 }; 1586 1587 template<random_access_range _Range> 1588 requires (sizeof(range_difference_t<_Range>) 1589 <= sizeof(iterator_t<_Range>)) 1590 struct _CachedPosition<_Range> 1591 { 1592 private: 1593 range_difference_t<_Range> _M_offset = -1; 1594 1595 public: 1596 _CachedPosition() = default; 1597 1598 constexpr 1599 _CachedPosition(const _CachedPosition&) = default; 1600 1601 constexpr 1602 _CachedPosition(_CachedPosition&& __other) noexcept 1603 { *this = std::move(__other); } 1604 1605 constexpr _CachedPosition& 1606 operator=(const _CachedPosition&) = default; 1607 1608 constexpr _CachedPosition& 1609 operator=(_CachedPosition&& __other) noexcept 1610 { 1611 // Propagate the cached offset, but invalidate the source. 1612 _M_offset = __other._M_offset; 1613 __other._M_offset = -1; 1614 return *this; 1615 } 1616 1617 constexpr bool 1618 _M_has_value() const 1619 { return _M_offset >= 0; } 1620 1621 constexpr iterator_t<_Range> 1622 _M_get(_Range& __r) const 1623 { 1624 __glibcxx_assert(_M_has_value()); 1625 return ranges::begin(__r) + _M_offset; 1626 } 1627 1628 constexpr void 1629 _M_set(_Range& __r, const iterator_t<_Range>& __it) 1630 { 1631 __glibcxx_assert(!_M_has_value()); 1632 _M_offset = __it - ranges::begin(__r); 1633 } 1634 }; 1635 } // namespace __detail 1636 1637 namespace __detail 1638 { 1639 template<typename _Base> 1640 struct __filter_view_iter_cat 1641 { }; 1642 1643 template<forward_range _Base> 1644 struct __filter_view_iter_cat<_Base> 1645 { 1646 private: 1647 static auto 1648 _S_iter_cat() 1649 { 1650 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 1651 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>) 1652 return bidirectional_iterator_tag{}; 1653 else if constexpr (derived_from<_Cat, forward_iterator_tag>) 1654 return forward_iterator_tag{}; 1655 else 1656 return _Cat{}; 1657 } 1658 public: 1659 using iterator_category = decltype(_S_iter_cat()); 1660 }; 1661 } // namespace __detail 1662 1663 template<input_range _Vp, 1664 indirect_unary_predicate<iterator_t<_Vp>> _Pred> 1665 requires view<_Vp> && is_object_v<_Pred> 1666 class filter_view : public view_interface<filter_view<_Vp, _Pred>> 1667 { 1668 private: 1669 struct _Sentinel; 1670 1671 struct _Iterator : __detail::__filter_view_iter_cat<_Vp> 1672 { 1673 private: 1674 static constexpr auto 1675 _S_iter_concept() 1676 { 1677 if constexpr (bidirectional_range<_Vp>) 1678 return bidirectional_iterator_tag{}; 1679 else if constexpr (forward_range<_Vp>) 1680 return forward_iterator_tag{}; 1681 else 1682 return input_iterator_tag{}; 1683 } 1684 1685 friend filter_view; 1686 1687 using _Vp_iter = iterator_t<_Vp>; 1688 1689 _Vp_iter _M_current = _Vp_iter(); 1690 filter_view* _M_parent = nullptr; 1691 1692 public: 1693 using iterator_concept = decltype(_S_iter_concept()); 1694 // iterator_category defined in __filter_view_iter_cat 1695 using value_type = range_value_t<_Vp>; 1696 using difference_type = range_difference_t<_Vp>; 1697 1698 _Iterator() requires default_initializable<_Vp_iter> = default; 1699 1700 constexpr 1701 _Iterator(filter_view* __parent, _Vp_iter __current) 1702 : _M_current(std::move(__current)), 1703 _M_parent(__parent) 1704 { } 1705 1706 constexpr const _Vp_iter& 1707 base() const & noexcept 1708 { return _M_current; } 1709 1710 constexpr _Vp_iter 1711 base() && 1712 { return std::move(_M_current); } 1713 1714 constexpr range_reference_t<_Vp> 1715 operator*() const 1716 { return *_M_current; } 1717 1718 constexpr _Vp_iter 1719 operator->() const 1720 requires __detail::__has_arrow<_Vp_iter> 1721 && copyable<_Vp_iter> 1722 { return _M_current; } 1723 1724 constexpr _Iterator& 1725 operator++() 1726 { 1727 _M_current = ranges::find_if(std::move(++_M_current), 1728 ranges::end(_M_parent->_M_base), 1729 std::ref(*_M_parent->_M_pred)); 1730 return *this; 1731 } 1732 1733 constexpr void 1734 operator++(int) 1735 { ++*this; } 1736 1737 constexpr _Iterator 1738 operator++(int) requires forward_range<_Vp> 1739 { 1740 auto __tmp = *this; 1741 ++*this; 1742 return __tmp; 1743 } 1744 1745 constexpr _Iterator& 1746 operator--() requires bidirectional_range<_Vp> 1747 { 1748 do 1749 --_M_current; 1750 while (!std::__invoke(*_M_parent->_M_pred, *_M_current)); 1751 return *this; 1752 } 1753 1754 constexpr _Iterator 1755 operator--(int) requires bidirectional_range<_Vp> 1756 { 1757 auto __tmp = *this; 1758 --*this; 1759 return __tmp; 1760 } 1761 1762 friend constexpr bool 1763 operator==(const _Iterator& __x, const _Iterator& __y) 1764 requires equality_comparable<_Vp_iter> 1765 { return __x._M_current == __y._M_current; } 1766 1767 friend constexpr range_rvalue_reference_t<_Vp> 1768 iter_move(const _Iterator& __i) 1769 noexcept(noexcept(ranges::iter_move(__i._M_current))) 1770 { return ranges::iter_move(__i._M_current); } 1771 1772 friend constexpr void 1773 iter_swap(const _Iterator& __x, const _Iterator& __y) 1774 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current))) 1775 requires indirectly_swappable<_Vp_iter> 1776 { ranges::iter_swap(__x._M_current, __y._M_current); } 1777 }; 1778 1779 struct _Sentinel 1780 { 1781 private: 1782 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>(); 1783 1784 constexpr bool 1785 __equal(const _Iterator& __i) const 1786 { return __i._M_current == _M_end; } 1787 1788 public: 1789 _Sentinel() = default; 1790 1791 constexpr explicit 1792 _Sentinel(filter_view* __parent) 1793 : _M_end(ranges::end(__parent->_M_base)) 1794 { } 1795 1796 constexpr sentinel_t<_Vp> 1797 base() const 1798 { return _M_end; } 1799 1800 friend constexpr bool 1801 operator==(const _Iterator& __x, const _Sentinel& __y) 1802 { return __y.__equal(__x); } 1803 }; 1804 1805 _Vp _M_base = _Vp(); 1806 [[no_unique_address]] __detail::__box<_Pred> _M_pred; 1807 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin; 1808 1809 public: 1810 filter_view() requires (default_initializable<_Vp> 1811 && default_initializable<_Pred>) 1812 = default; 1813 1814 constexpr 1815 filter_view(_Vp __base, _Pred __pred) 1816 : _M_base(std::move(__base)), _M_pred(std::move(__pred)) 1817 { } 1818 1819 constexpr _Vp 1820 base() const& requires copy_constructible<_Vp> 1821 { return _M_base; } 1822 1823 constexpr _Vp 1824 base() && 1825 { return std::move(_M_base); } 1826 1827 constexpr const _Pred& 1828 pred() const 1829 { return *_M_pred; } 1830 1831 constexpr _Iterator 1832 begin() 1833 { 1834 if (_M_cached_begin._M_has_value()) 1835 return {this, _M_cached_begin._M_get(_M_base)}; 1836 1837 __glibcxx_assert(_M_pred.has_value()); 1838 auto __it = ranges::find_if(ranges::begin(_M_base), 1839 ranges::end(_M_base), 1840 std::ref(*_M_pred)); 1841 _M_cached_begin._M_set(_M_base, __it); 1842 return {this, std::move(__it)}; 1843 } 1844 1845 constexpr auto 1846 end() 1847 { 1848 if constexpr (common_range<_Vp>) 1849 return _Iterator{this, ranges::end(_M_base)}; 1850 else 1851 return _Sentinel{this}; 1852 } 1853 }; 1854 1855 template<typename _Range, typename _Pred> 1856 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>; 1857 1858 namespace views 1859 { 1860 namespace __detail 1861 { 1862 template<typename _Range, typename _Pred> 1863 concept __can_filter_view 1864 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); }; 1865 } // namespace __detail 1866 1867 struct _Filter : __adaptor::_RangeAdaptor<_Filter> 1868 { 1869 template<viewable_range _Range, typename _Pred> 1870 requires __detail::__can_filter_view<_Range, _Pred> 1871 constexpr auto 1872 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const 1873 { 1874 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p)); 1875 } 1876 1877 using _RangeAdaptor<_Filter>::operator(); 1878 static constexpr int _S_arity = 2; 1879 static constexpr bool _S_has_simple_extra_args = true; 1880 }; 1881 1882 inline constexpr _Filter filter; 1883 } // namespace views 1884 1885 #if __cpp_lib_ranges >= 202207L // C++ >= 23 1886 template<input_range _Vp, move_constructible _Fp> 1887 #else 1888 template<input_range _Vp, copy_constructible _Fp> 1889 #endif 1890 requires view<_Vp> && is_object_v<_Fp> 1891 && regular_invocable<_Fp&, range_reference_t<_Vp>> 1892 && std::__detail::__can_reference<invoke_result_t<_Fp&, 1893 range_reference_t<_Vp>>> 1894 class transform_view : public view_interface<transform_view<_Vp, _Fp>> 1895 { 1896 private: 1897 template<bool _Const> 1898 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 1899 1900 template<bool _Const> 1901 struct __iter_cat 1902 { }; 1903 1904 template<bool _Const> 1905 requires forward_range<_Base<_Const>> 1906 struct __iter_cat<_Const> 1907 { 1908 private: 1909 static auto 1910 _S_iter_cat() 1911 { 1912 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1913 // 3564. transform_view::iterator<true>::value_type and 1914 // iterator_category should use const F& 1915 using _Base = transform_view::_Base<_Const>; 1916 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&, 1917 range_reference_t<_Base>>; 1918 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1919 // 3798. Rvalue reference and iterator_category 1920 if constexpr (is_reference_v<_Res>) 1921 { 1922 using _Cat 1923 = typename iterator_traits<iterator_t<_Base>>::iterator_category; 1924 if constexpr (derived_from<_Cat, contiguous_iterator_tag>) 1925 return random_access_iterator_tag{}; 1926 else 1927 return _Cat{}; 1928 } 1929 else 1930 return input_iterator_tag{}; 1931 } 1932 public: 1933 using iterator_category = decltype(_S_iter_cat()); 1934 }; 1935 1936 template<bool _Const> 1937 struct _Sentinel; 1938 1939 template<bool _Const> 1940 struct _Iterator : __iter_cat<_Const> 1941 { 1942 private: 1943 using _Parent = __detail::__maybe_const_t<_Const, transform_view>; 1944 using _Base = transform_view::_Base<_Const>; 1945 1946 static auto 1947 _S_iter_concept() 1948 { 1949 if constexpr (random_access_range<_Base>) 1950 return random_access_iterator_tag{}; 1951 else if constexpr (bidirectional_range<_Base>) 1952 return bidirectional_iterator_tag{}; 1953 else if constexpr (forward_range<_Base>) 1954 return forward_iterator_tag{}; 1955 else 1956 return input_iterator_tag{}; 1957 } 1958 1959 using _Base_iter = iterator_t<_Base>; 1960 1961 _Base_iter _M_current = _Base_iter(); 1962 _Parent* _M_parent = nullptr; 1963 1964 public: 1965 using iterator_concept = decltype(_S_iter_concept()); 1966 // iterator_category defined in __transform_view_iter_cat 1967 using value_type 1968 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&, 1969 range_reference_t<_Base>>>; 1970 using difference_type = range_difference_t<_Base>; 1971 1972 _Iterator() requires default_initializable<_Base_iter> = default; 1973 1974 constexpr 1975 _Iterator(_Parent* __parent, _Base_iter __current) 1976 : _M_current(std::move(__current)), 1977 _M_parent(__parent) 1978 { } 1979 1980 constexpr 1981 _Iterator(_Iterator<!_Const> __i) 1982 requires _Const 1983 && convertible_to<iterator_t<_Vp>, _Base_iter> 1984 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent) 1985 { } 1986 1987 constexpr const _Base_iter& 1988 base() const & noexcept 1989 { return _M_current; } 1990 1991 constexpr _Base_iter 1992 base() && 1993 { return std::move(_M_current); } 1994 1995 constexpr decltype(auto) 1996 operator*() const 1997 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current))) 1998 { return std::__invoke(*_M_parent->_M_fun, *_M_current); } 1999 2000 constexpr _Iterator& 2001 operator++() 2002 { 2003 ++_M_current; 2004 return *this; 2005 } 2006 2007 constexpr void 2008 operator++(int) 2009 { ++_M_current; } 2010 2011 constexpr _Iterator 2012 operator++(int) requires forward_range<_Base> 2013 { 2014 auto __tmp = *this; 2015 ++*this; 2016 return __tmp; 2017 } 2018 2019 constexpr _Iterator& 2020 operator--() requires bidirectional_range<_Base> 2021 { 2022 --_M_current; 2023 return *this; 2024 } 2025 2026 constexpr _Iterator 2027 operator--(int) requires bidirectional_range<_Base> 2028 { 2029 auto __tmp = *this; 2030 --*this; 2031 return __tmp; 2032 } 2033 2034 constexpr _Iterator& 2035 operator+=(difference_type __n) requires random_access_range<_Base> 2036 { 2037 _M_current += __n; 2038 return *this; 2039 } 2040 2041 constexpr _Iterator& 2042 operator-=(difference_type __n) requires random_access_range<_Base> 2043 { 2044 _M_current -= __n; 2045 return *this; 2046 } 2047 2048 constexpr decltype(auto) 2049 operator[](difference_type __n) const 2050 requires random_access_range<_Base> 2051 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); } 2052 2053 friend constexpr bool 2054 operator==(const _Iterator& __x, const _Iterator& __y) 2055 requires equality_comparable<_Base_iter> 2056 { return __x._M_current == __y._M_current; } 2057 2058 friend constexpr bool 2059 operator<(const _Iterator& __x, const _Iterator& __y) 2060 requires random_access_range<_Base> 2061 { return __x._M_current < __y._M_current; } 2062 2063 friend constexpr bool 2064 operator>(const _Iterator& __x, const _Iterator& __y) 2065 requires random_access_range<_Base> 2066 { return __y < __x; } 2067 2068 friend constexpr bool 2069 operator<=(const _Iterator& __x, const _Iterator& __y) 2070 requires random_access_range<_Base> 2071 { return !(__y < __x); } 2072 2073 friend constexpr bool 2074 operator>=(const _Iterator& __x, const _Iterator& __y) 2075 requires random_access_range<_Base> 2076 { return !(__x < __y); } 2077 2078 #ifdef __cpp_lib_three_way_comparison 2079 friend constexpr auto 2080 operator<=>(const _Iterator& __x, const _Iterator& __y) 2081 requires random_access_range<_Base> 2082 && three_way_comparable<_Base_iter> 2083 { return __x._M_current <=> __y._M_current; } 2084 #endif 2085 2086 friend constexpr _Iterator 2087 operator+(_Iterator __i, difference_type __n) 2088 requires random_access_range<_Base> 2089 { return {__i._M_parent, __i._M_current + __n}; } 2090 2091 friend constexpr _Iterator 2092 operator+(difference_type __n, _Iterator __i) 2093 requires random_access_range<_Base> 2094 { return {__i._M_parent, __i._M_current + __n}; } 2095 2096 friend constexpr _Iterator 2097 operator-(_Iterator __i, difference_type __n) 2098 requires random_access_range<_Base> 2099 { return {__i._M_parent, __i._M_current - __n}; } 2100 2101 // _GLIBCXX_RESOLVE_LIB_DEFECTS 2102 // 3483. transform_view::iterator's difference is overconstrained 2103 friend constexpr difference_type 2104 operator-(const _Iterator& __x, const _Iterator& __y) 2105 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 2106 { return __x._M_current - __y._M_current; } 2107 2108 friend constexpr decltype(auto) 2109 iter_move(const _Iterator& __i) noexcept(noexcept(*__i)) 2110 { 2111 if constexpr (is_lvalue_reference_v<decltype(*__i)>) 2112 return std::move(*__i); 2113 else 2114 return *__i; 2115 } 2116 2117 friend _Iterator<!_Const>; 2118 template<bool> friend struct _Sentinel; 2119 }; 2120 2121 template<bool _Const> 2122 struct _Sentinel 2123 { 2124 private: 2125 using _Parent = __detail::__maybe_const_t<_Const, transform_view>; 2126 using _Base = transform_view::_Base<_Const>; 2127 2128 template<bool _Const2> 2129 constexpr auto 2130 __distance_from(const _Iterator<_Const2>& __i) const 2131 { return _M_end - __i._M_current; } 2132 2133 template<bool _Const2> 2134 constexpr bool 2135 __equal(const _Iterator<_Const2>& __i) const 2136 { return __i._M_current == _M_end; } 2137 2138 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 2139 2140 public: 2141 _Sentinel() = default; 2142 2143 constexpr explicit 2144 _Sentinel(sentinel_t<_Base> __end) 2145 : _M_end(__end) 2146 { } 2147 2148 constexpr 2149 _Sentinel(_Sentinel<!_Const> __i) 2150 requires _Const 2151 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 2152 : _M_end(std::move(__i._M_end)) 2153 { } 2154 2155 constexpr sentinel_t<_Base> 2156 base() const 2157 { return _M_end; } 2158 2159 template<bool _Const2> 2160 requires sentinel_for<sentinel_t<_Base>, 2161 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>> 2162 friend constexpr bool 2163 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y) 2164 { return __y.__equal(__x); } 2165 2166 template<bool _Const2, 2167 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 2168 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 2169 friend constexpr range_difference_t<_Base2> 2170 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y) 2171 { return -__y.__distance_from(__x); } 2172 2173 template<bool _Const2, 2174 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 2175 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 2176 friend constexpr range_difference_t<_Base2> 2177 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x) 2178 { return __y.__distance_from(__x); } 2179 2180 friend _Sentinel<!_Const>; 2181 }; 2182 2183 _Vp _M_base = _Vp(); 2184 [[no_unique_address]] __detail::__box<_Fp> _M_fun; 2185 2186 public: 2187 transform_view() requires (default_initializable<_Vp> 2188 && default_initializable<_Fp>) 2189 = default; 2190 2191 constexpr 2192 transform_view(_Vp __base, _Fp __fun) 2193 : _M_base(std::move(__base)), _M_fun(std::move(__fun)) 2194 { } 2195 2196 constexpr _Vp 2197 base() const& requires copy_constructible<_Vp> 2198 { return _M_base ; } 2199 2200 constexpr _Vp 2201 base() && 2202 { return std::move(_M_base); } 2203 2204 constexpr _Iterator<false> 2205 begin() 2206 { return _Iterator<false>{this, ranges::begin(_M_base)}; } 2207 2208 constexpr _Iterator<true> 2209 begin() const 2210 requires range<const _Vp> 2211 && regular_invocable<const _Fp&, range_reference_t<const _Vp>> 2212 { return _Iterator<true>{this, ranges::begin(_M_base)}; } 2213 2214 constexpr _Sentinel<false> 2215 end() 2216 { return _Sentinel<false>{ranges::end(_M_base)}; } 2217 2218 constexpr _Iterator<false> 2219 end() requires common_range<_Vp> 2220 { return _Iterator<false>{this, ranges::end(_M_base)}; } 2221 2222 constexpr _Sentinel<true> 2223 end() const 2224 requires range<const _Vp> 2225 && regular_invocable<const _Fp&, range_reference_t<const _Vp>> 2226 { return _Sentinel<true>{ranges::end(_M_base)}; } 2227 2228 constexpr _Iterator<true> 2229 end() const 2230 requires common_range<const _Vp> 2231 && regular_invocable<const _Fp&, range_reference_t<const _Vp>> 2232 { return _Iterator<true>{this, ranges::end(_M_base)}; } 2233 2234 constexpr auto 2235 size() requires sized_range<_Vp> 2236 { return ranges::size(_M_base); } 2237 2238 constexpr auto 2239 size() const requires sized_range<const _Vp> 2240 { return ranges::size(_M_base); } 2241 }; 2242 2243 template<typename _Range, typename _Fp> 2244 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>; 2245 2246 namespace views 2247 { 2248 namespace __detail 2249 { 2250 template<typename _Range, typename _Fp> 2251 concept __can_transform_view 2252 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); }; 2253 } // namespace __detail 2254 2255 struct _Transform : __adaptor::_RangeAdaptor<_Transform> 2256 { 2257 template<viewable_range _Range, typename _Fp> 2258 requires __detail::__can_transform_view<_Range, _Fp> 2259 constexpr auto 2260 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const 2261 { 2262 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f)); 2263 } 2264 2265 using _RangeAdaptor<_Transform>::operator(); 2266 static constexpr int _S_arity = 2; 2267 static constexpr bool _S_has_simple_extra_args = true; 2268 }; 2269 2270 inline constexpr _Transform transform; 2271 } // namespace views 2272 2273 template<view _Vp> 2274 class take_view : public view_interface<take_view<_Vp>> 2275 { 2276 private: 2277 template<bool _Const> 2278 using _CI = counted_iterator< 2279 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>; 2280 2281 template<bool _Const> 2282 struct _Sentinel 2283 { 2284 private: 2285 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 2286 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 2287 2288 public: 2289 _Sentinel() = default; 2290 2291 constexpr explicit 2292 _Sentinel(sentinel_t<_Base> __end) 2293 : _M_end(__end) 2294 { } 2295 2296 constexpr 2297 _Sentinel(_Sentinel<!_Const> __s) 2298 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 2299 : _M_end(std::move(__s._M_end)) 2300 { } 2301 2302 constexpr sentinel_t<_Base> 2303 base() const 2304 { return _M_end; } 2305 2306 friend constexpr bool 2307 operator==(const _CI<_Const>& __y, const _Sentinel& __x) 2308 { return __y.count() == 0 || __y.base() == __x._M_end; } 2309 2310 template<bool _OtherConst = !_Const, 2311 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>> 2312 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 2313 friend constexpr bool 2314 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x) 2315 { return __y.count() == 0 || __y.base() == __x._M_end; } 2316 2317 friend _Sentinel<!_Const>; 2318 }; 2319 2320 _Vp _M_base = _Vp(); 2321 range_difference_t<_Vp> _M_count = 0; 2322 2323 public: 2324 take_view() requires default_initializable<_Vp> = default; 2325 2326 constexpr 2327 take_view(_Vp __base, range_difference_t<_Vp> __count) 2328 : _M_base(std::move(__base)), _M_count(std::move(__count)) 2329 { } 2330 2331 constexpr _Vp 2332 base() const& requires copy_constructible<_Vp> 2333 { return _M_base; } 2334 2335 constexpr _Vp 2336 base() && 2337 { return std::move(_M_base); } 2338 2339 constexpr auto 2340 begin() requires (!__detail::__simple_view<_Vp>) 2341 { 2342 if constexpr (sized_range<_Vp>) 2343 { 2344 if constexpr (random_access_range<_Vp>) 2345 return ranges::begin(_M_base); 2346 else 2347 { 2348 auto __sz = size(); 2349 return counted_iterator(ranges::begin(_M_base), __sz); 2350 } 2351 } 2352 else 2353 return counted_iterator(ranges::begin(_M_base), _M_count); 2354 } 2355 2356 constexpr auto 2357 begin() const requires range<const _Vp> 2358 { 2359 if constexpr (sized_range<const _Vp>) 2360 { 2361 if constexpr (random_access_range<const _Vp>) 2362 return ranges::begin(_M_base); 2363 else 2364 { 2365 auto __sz = size(); 2366 return counted_iterator(ranges::begin(_M_base), __sz); 2367 } 2368 } 2369 else 2370 return counted_iterator(ranges::begin(_M_base), _M_count); 2371 } 2372 2373 constexpr auto 2374 end() requires (!__detail::__simple_view<_Vp>) 2375 { 2376 if constexpr (sized_range<_Vp>) 2377 { 2378 if constexpr (random_access_range<_Vp>) 2379 return ranges::begin(_M_base) + size(); 2380 else 2381 return default_sentinel; 2382 } 2383 else 2384 return _Sentinel<false>{ranges::end(_M_base)}; 2385 } 2386 2387 constexpr auto 2388 end() const requires range<const _Vp> 2389 { 2390 if constexpr (sized_range<const _Vp>) 2391 { 2392 if constexpr (random_access_range<const _Vp>) 2393 return ranges::begin(_M_base) + size(); 2394 else 2395 return default_sentinel; 2396 } 2397 else 2398 return _Sentinel<true>{ranges::end(_M_base)}; 2399 } 2400 2401 constexpr auto 2402 size() requires sized_range<_Vp> 2403 { 2404 auto __n = ranges::size(_M_base); 2405 return std::min(__n, static_cast<decltype(__n)>(_M_count)); 2406 } 2407 2408 constexpr auto 2409 size() const requires sized_range<const _Vp> 2410 { 2411 auto __n = ranges::size(_M_base); 2412 return std::min(__n, static_cast<decltype(__n)>(_M_count)); 2413 } 2414 }; 2415 2416 // _GLIBCXX_RESOLVE_LIB_DEFECTS 2417 // 3447. Deduction guides for take_view and drop_view have different 2418 // constraints 2419 template<typename _Range> 2420 take_view(_Range&&, range_difference_t<_Range>) 2421 -> take_view<views::all_t<_Range>>; 2422 2423 template<typename _Tp> 2424 inline constexpr bool enable_borrowed_range<take_view<_Tp>> 2425 = enable_borrowed_range<_Tp>; 2426 2427 namespace views 2428 { 2429 namespace __detail 2430 { 2431 template<typename _Range> 2432 inline constexpr bool __is_empty_view = false; 2433 2434 template<typename _Tp> 2435 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true; 2436 2437 template<typename _Range> 2438 inline constexpr bool __is_basic_string_view = false; 2439 2440 template<typename _CharT, typename _Traits> 2441 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>> 2442 = true; 2443 2444 using ranges::__detail::__is_subrange; 2445 2446 template<typename _Range> 2447 inline constexpr bool __is_iota_view = false; 2448 2449 template<typename _Winc, typename _Bound> 2450 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true; 2451 2452 template<typename _Range> 2453 inline constexpr bool __is_repeat_view = false; 2454 2455 template<typename _Range> 2456 constexpr auto 2457 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later 2458 2459 template<typename _Range, typename _Dp> 2460 concept __can_take_view 2461 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); }; 2462 } // namespace __detail 2463 2464 struct _Take : __adaptor::_RangeAdaptor<_Take> 2465 { 2466 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>> 2467 requires __detail::__can_take_view<_Range, _Dp> 2468 constexpr auto 2469 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const 2470 { 2471 using _Tp = remove_cvref_t<_Range>; 2472 if constexpr (__detail::__is_empty_view<_Tp>) 2473 return _Tp(); 2474 else if constexpr (random_access_range<_Tp> 2475 && sized_range<_Tp> 2476 && (std::__detail::__is_span<_Tp> 2477 || __detail::__is_basic_string_view<_Tp> 2478 || __detail::__is_subrange<_Tp> 2479 || __detail::__is_iota_view<_Tp>)) 2480 { 2481 __n = std::min<_Dp>(ranges::distance(__r), __n); 2482 auto __begin = ranges::begin(__r); 2483 auto __end = __begin + __n; 2484 if constexpr (std::__detail::__is_span<_Tp>) 2485 return span<typename _Tp::element_type>(__begin, __end); 2486 else if constexpr (__detail::__is_basic_string_view<_Tp>) 2487 return _Tp(__begin, __end); 2488 else if constexpr (__detail::__is_subrange<_Tp>) 2489 return subrange<iterator_t<_Tp>>(__begin, __end); 2490 else 2491 return iota_view(*__begin, *__end); 2492 } 2493 else if constexpr (__detail::__is_repeat_view<_Tp>) 2494 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n); 2495 else 2496 return take_view(std::forward<_Range>(__r), __n); 2497 } 2498 2499 using _RangeAdaptor<_Take>::operator(); 2500 static constexpr int _S_arity = 2; 2501 // The count argument of views::take is not always simple -- it can be 2502 // e.g. a move-only class that's implicitly convertible to the difference 2503 // type. But an integer-like count argument is surely simple. 2504 template<typename _Tp> 2505 static constexpr bool _S_has_simple_extra_args 2506 = ranges::__detail::__is_integer_like<_Tp>; 2507 }; 2508 2509 inline constexpr _Take take; 2510 } // namespace views 2511 2512 template<view _Vp, typename _Pred> 2513 requires input_range<_Vp> && is_object_v<_Pred> 2514 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>> 2515 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>> 2516 { 2517 template<bool _Const> 2518 struct _Sentinel 2519 { 2520 private: 2521 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 2522 2523 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 2524 const _Pred* _M_pred = nullptr; 2525 2526 public: 2527 _Sentinel() = default; 2528 2529 constexpr explicit 2530 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred) 2531 : _M_end(__end), _M_pred(__pred) 2532 { } 2533 2534 constexpr 2535 _Sentinel(_Sentinel<!_Const> __s) 2536 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 2537 : _M_end(__s._M_end), _M_pred(__s._M_pred) 2538 { } 2539 2540 constexpr sentinel_t<_Base> 2541 base() const { return _M_end; } 2542 2543 friend constexpr bool 2544 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y) 2545 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); } 2546 2547 template<bool _OtherConst = !_Const, 2548 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>> 2549 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 2550 friend constexpr bool 2551 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y) 2552 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); } 2553 2554 friend _Sentinel<!_Const>; 2555 }; 2556 2557 _Vp _M_base = _Vp(); 2558 [[no_unique_address]] __detail::__box<_Pred> _M_pred; 2559 2560 public: 2561 take_while_view() requires (default_initializable<_Vp> 2562 && default_initializable<_Pred>) 2563 = default; 2564 2565 constexpr 2566 take_while_view(_Vp __base, _Pred __pred) 2567 : _M_base(std::move(__base)), _M_pred(std::move(__pred)) 2568 { } 2569 2570 constexpr _Vp 2571 base() const& requires copy_constructible<_Vp> 2572 { return _M_base; } 2573 2574 constexpr _Vp 2575 base() && 2576 { return std::move(_M_base); } 2577 2578 constexpr const _Pred& 2579 pred() const 2580 { return *_M_pred; } 2581 2582 constexpr auto 2583 begin() requires (!__detail::__simple_view<_Vp>) 2584 { return ranges::begin(_M_base); } 2585 2586 constexpr auto 2587 begin() const requires range<const _Vp> 2588 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>> 2589 { return ranges::begin(_M_base); } 2590 2591 constexpr auto 2592 end() requires (!__detail::__simple_view<_Vp>) 2593 { return _Sentinel<false>(ranges::end(_M_base), 2594 std::__addressof(*_M_pred)); } 2595 2596 constexpr auto 2597 end() const requires range<const _Vp> 2598 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>> 2599 { return _Sentinel<true>(ranges::end(_M_base), 2600 std::__addressof(*_M_pred)); } 2601 }; 2602 2603 template<typename _Range, typename _Pred> 2604 take_while_view(_Range&&, _Pred) 2605 -> take_while_view<views::all_t<_Range>, _Pred>; 2606 2607 namespace views 2608 { 2609 namespace __detail 2610 { 2611 template<typename _Range, typename _Pred> 2612 concept __can_take_while_view 2613 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); }; 2614 } // namespace __detail 2615 2616 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile> 2617 { 2618 template<viewable_range _Range, typename _Pred> 2619 requires __detail::__can_take_while_view<_Range, _Pred> 2620 constexpr auto 2621 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const 2622 { 2623 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p)); 2624 } 2625 2626 using _RangeAdaptor<_TakeWhile>::operator(); 2627 static constexpr int _S_arity = 2; 2628 static constexpr bool _S_has_simple_extra_args = true; 2629 }; 2630 2631 inline constexpr _TakeWhile take_while; 2632 } // namespace views 2633 2634 template<view _Vp> 2635 class drop_view : public view_interface<drop_view<_Vp>> 2636 { 2637 private: 2638 _Vp _M_base = _Vp(); 2639 range_difference_t<_Vp> _M_count = 0; 2640 2641 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies 2642 // both random_access_range and sized_range. Otherwise, cache its result. 2643 static constexpr bool _S_needs_cached_begin 2644 = !(random_access_range<const _Vp> && sized_range<const _Vp>); 2645 [[no_unique_address]] 2646 __detail::__maybe_present_t<_S_needs_cached_begin, 2647 __detail::_CachedPosition<_Vp>> 2648 _M_cached_begin; 2649 2650 public: 2651 drop_view() requires default_initializable<_Vp> = default; 2652 2653 constexpr 2654 drop_view(_Vp __base, range_difference_t<_Vp> __count) 2655 : _M_base(std::move(__base)), _M_count(__count) 2656 { __glibcxx_assert(__count >= 0); } 2657 2658 constexpr _Vp 2659 base() const& requires copy_constructible<_Vp> 2660 { return _M_base; } 2661 2662 constexpr _Vp 2663 base() && 2664 { return std::move(_M_base); } 2665 2666 // This overload is disabled for simple views with constant-time begin(). 2667 constexpr auto 2668 begin() 2669 requires (!(__detail::__simple_view<_Vp> 2670 && random_access_range<const _Vp> 2671 && sized_range<const _Vp>)) 2672 { 2673 if constexpr (_S_needs_cached_begin) 2674 if (_M_cached_begin._M_has_value()) 2675 return _M_cached_begin._M_get(_M_base); 2676 2677 auto __it = ranges::next(ranges::begin(_M_base), 2678 _M_count, ranges::end(_M_base)); 2679 if constexpr (_S_needs_cached_begin) 2680 _M_cached_begin._M_set(_M_base, __it); 2681 return __it; 2682 } 2683 2684 // _GLIBCXX_RESOLVE_LIB_DEFECTS 2685 // 3482. drop_view's const begin should additionally require sized_range 2686 constexpr auto 2687 begin() const 2688 requires random_access_range<const _Vp> && sized_range<const _Vp> 2689 { 2690 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base), 2691 _M_count); 2692 } 2693 2694 constexpr auto 2695 end() requires (!__detail::__simple_view<_Vp>) 2696 { return ranges::end(_M_base); } 2697 2698 constexpr auto 2699 end() const requires range<const _Vp> 2700 { return ranges::end(_M_base); } 2701 2702 constexpr auto 2703 size() requires sized_range<_Vp> 2704 { 2705 const auto __s = ranges::size(_M_base); 2706 const auto __c = static_cast<decltype(__s)>(_M_count); 2707 return __s < __c ? 0 : __s - __c; 2708 } 2709 2710 constexpr auto 2711 size() const requires sized_range<const _Vp> 2712 { 2713 const auto __s = ranges::size(_M_base); 2714 const auto __c = static_cast<decltype(__s)>(_M_count); 2715 return __s < __c ? 0 : __s - __c; 2716 } 2717 }; 2718 2719 template<typename _Range> 2720 drop_view(_Range&&, range_difference_t<_Range>) 2721 -> drop_view<views::all_t<_Range>>; 2722 2723 template<typename _Tp> 2724 inline constexpr bool enable_borrowed_range<drop_view<_Tp>> 2725 = enable_borrowed_range<_Tp>; 2726 2727 namespace views 2728 { 2729 namespace __detail 2730 { 2731 template<typename _Range> 2732 constexpr auto 2733 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later 2734 2735 template<typename _Range, typename _Dp> 2736 concept __can_drop_view 2737 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); }; 2738 } // namespace __detail 2739 2740 struct _Drop : __adaptor::_RangeAdaptor<_Drop> 2741 { 2742 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>> 2743 requires __detail::__can_drop_view<_Range, _Dp> 2744 constexpr auto 2745 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const 2746 { 2747 using _Tp = remove_cvref_t<_Range>; 2748 if constexpr (__detail::__is_empty_view<_Tp>) 2749 return _Tp(); 2750 else if constexpr (random_access_range<_Tp> 2751 && sized_range<_Tp> 2752 && (std::__detail::__is_span<_Tp> 2753 || __detail::__is_basic_string_view<_Tp> 2754 || __detail::__is_iota_view<_Tp> 2755 || __detail::__is_subrange<_Tp>)) 2756 { 2757 __n = std::min<_Dp>(ranges::distance(__r), __n); 2758 auto __begin = ranges::begin(__r) + __n; 2759 auto __end = ranges::end(__r); 2760 if constexpr (std::__detail::__is_span<_Tp>) 2761 return span<typename _Tp::element_type>(__begin, __end); 2762 else if constexpr (__detail::__is_subrange<_Tp>) 2763 { 2764 if constexpr (_Tp::_S_store_size) 2765 { 2766 using ranges::__detail::__to_unsigned_like; 2767 auto __m = ranges::distance(__r) - __n; 2768 return _Tp(__begin, __end, __to_unsigned_like(__m)); 2769 } 2770 else 2771 return _Tp(__begin, __end); 2772 } 2773 else 2774 return _Tp(__begin, __end); 2775 } 2776 else if constexpr (__detail::__is_repeat_view<_Tp>) 2777 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n); 2778 else 2779 return drop_view(std::forward<_Range>(__r), __n); 2780 } 2781 2782 using _RangeAdaptor<_Drop>::operator(); 2783 static constexpr int _S_arity = 2; 2784 template<typename _Tp> 2785 static constexpr bool _S_has_simple_extra_args 2786 = _Take::_S_has_simple_extra_args<_Tp>; 2787 }; 2788 2789 inline constexpr _Drop drop; 2790 } // namespace views 2791 2792 template<view _Vp, typename _Pred> 2793 requires input_range<_Vp> && is_object_v<_Pred> 2794 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>> 2795 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>> 2796 { 2797 private: 2798 _Vp _M_base = _Vp(); 2799 [[no_unique_address]] __detail::__box<_Pred> _M_pred; 2800 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin; 2801 2802 public: 2803 drop_while_view() requires (default_initializable<_Vp> 2804 && default_initializable<_Pred>) 2805 = default; 2806 2807 constexpr 2808 drop_while_view(_Vp __base, _Pred __pred) 2809 : _M_base(std::move(__base)), _M_pred(std::move(__pred)) 2810 { } 2811 2812 constexpr _Vp 2813 base() const& requires copy_constructible<_Vp> 2814 { return _M_base; } 2815 2816 constexpr _Vp 2817 base() && 2818 { return std::move(_M_base); } 2819 2820 constexpr const _Pred& 2821 pred() const 2822 { return *_M_pred; } 2823 2824 constexpr auto 2825 begin() 2826 { 2827 if (_M_cached_begin._M_has_value()) 2828 return _M_cached_begin._M_get(_M_base); 2829 2830 __glibcxx_assert(_M_pred.has_value()); 2831 auto __it = ranges::find_if_not(ranges::begin(_M_base), 2832 ranges::end(_M_base), 2833 std::cref(*_M_pred)); 2834 _M_cached_begin._M_set(_M_base, __it); 2835 return __it; 2836 } 2837 2838 constexpr auto 2839 end() 2840 { return ranges::end(_M_base); } 2841 }; 2842 2843 template<typename _Range, typename _Pred> 2844 drop_while_view(_Range&&, _Pred) 2845 -> drop_while_view<views::all_t<_Range>, _Pred>; 2846 2847 template<typename _Tp, typename _Pred> 2848 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>> 2849 = enable_borrowed_range<_Tp>; 2850 2851 namespace views 2852 { 2853 namespace __detail 2854 { 2855 template<typename _Range, typename _Pred> 2856 concept __can_drop_while_view 2857 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); }; 2858 } // namespace __detail 2859 2860 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile> 2861 { 2862 template<viewable_range _Range, typename _Pred> 2863 requires __detail::__can_drop_while_view<_Range, _Pred> 2864 constexpr auto 2865 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const 2866 { 2867 return drop_while_view(std::forward<_Range>(__r), 2868 std::forward<_Pred>(__p)); 2869 } 2870 2871 using _RangeAdaptor<_DropWhile>::operator(); 2872 static constexpr int _S_arity = 2; 2873 static constexpr bool _S_has_simple_extra_args = true; 2874 }; 2875 2876 inline constexpr _DropWhile drop_while; 2877 } // namespace views 2878 2879 namespace __detail 2880 { 2881 template<typename _Tp> 2882 constexpr _Tp& 2883 __as_lvalue(_Tp&& __t) 2884 { return static_cast<_Tp&>(__t); } 2885 } // namespace __detail 2886 2887 template<input_range _Vp> 2888 requires view<_Vp> && input_range<range_reference_t<_Vp>> 2889 class join_view : public view_interface<join_view<_Vp>> 2890 { 2891 private: 2892 using _InnerRange = range_reference_t<_Vp>; 2893 2894 template<bool _Const> 2895 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 2896 2897 template<bool _Const> 2898 using _Outer_iter = iterator_t<_Base<_Const>>; 2899 2900 template<bool _Const> 2901 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>; 2902 2903 template<bool _Const> 2904 static constexpr bool _S_ref_is_glvalue 2905 = is_reference_v<range_reference_t<_Base<_Const>>>; 2906 2907 template<bool _Const> 2908 struct __iter_cat 2909 { }; 2910 2911 template<bool _Const> 2912 requires _S_ref_is_glvalue<_Const> 2913 && forward_range<_Base<_Const>> 2914 && forward_range<range_reference_t<_Base<_Const>>> 2915 struct __iter_cat<_Const> 2916 { 2917 private: 2918 static constexpr auto 2919 _S_iter_cat() 2920 { 2921 using _Outer_iter = join_view::_Outer_iter<_Const>; 2922 using _Inner_iter = join_view::_Inner_iter<_Const>; 2923 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category; 2924 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category; 2925 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag> 2926 && derived_from<_InnerCat, bidirectional_iterator_tag> 2927 && common_range<range_reference_t<_Base<_Const>>>) 2928 return bidirectional_iterator_tag{}; 2929 else if constexpr (derived_from<_OuterCat, forward_iterator_tag> 2930 && derived_from<_InnerCat, forward_iterator_tag>) 2931 return forward_iterator_tag{}; 2932 else 2933 return input_iterator_tag{}; 2934 } 2935 public: 2936 using iterator_category = decltype(_S_iter_cat()); 2937 }; 2938 2939 template<bool _Const> 2940 struct _Sentinel; 2941 2942 template<bool _Const> 2943 struct _Iterator : __iter_cat<_Const> 2944 { 2945 private: 2946 using _Parent = __detail::__maybe_const_t<_Const, join_view>; 2947 using _Base = join_view::_Base<_Const>; 2948 2949 friend join_view; 2950 2951 static constexpr bool _S_ref_is_glvalue 2952 = join_view::_S_ref_is_glvalue<_Const>; 2953 2954 constexpr void 2955 _M_satisfy() 2956 { 2957 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& { 2958 if constexpr (_S_ref_is_glvalue) 2959 return *__x; 2960 else 2961 return _M_parent->_M_inner._M_emplace_deref(__x); 2962 }; 2963 2964 _Outer_iter& __outer = _M_get_outer(); 2965 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer) 2966 { 2967 auto&& __inner = __update_inner(__outer); 2968 _M_inner = ranges::begin(__inner); 2969 if (_M_inner != ranges::end(__inner)) 2970 return; 2971 } 2972 2973 if constexpr (_S_ref_is_glvalue) 2974 _M_inner.reset(); 2975 } 2976 2977 static constexpr auto 2978 _S_iter_concept() 2979 { 2980 if constexpr (_S_ref_is_glvalue 2981 && bidirectional_range<_Base> 2982 && bidirectional_range<range_reference_t<_Base>> 2983 && common_range<range_reference_t<_Base>>) 2984 return bidirectional_iterator_tag{}; 2985 else if constexpr (_S_ref_is_glvalue 2986 && forward_range<_Base> 2987 && forward_range<range_reference_t<_Base>>) 2988 return forward_iterator_tag{}; 2989 else 2990 return input_iterator_tag{}; 2991 } 2992 2993 using _Outer_iter = join_view::_Outer_iter<_Const>; 2994 using _Inner_iter = join_view::_Inner_iter<_Const>; 2995 2996 constexpr _Outer_iter& 2997 _M_get_outer() 2998 { 2999 if constexpr (forward_range<_Base>) 3000 return _M_outer; 3001 else 3002 return *_M_parent->_M_outer; 3003 } 3004 3005 constexpr const _Outer_iter& 3006 _M_get_outer() const 3007 { 3008 if constexpr (forward_range<_Base>) 3009 return _M_outer; 3010 else 3011 return *_M_parent->_M_outer; 3012 } 3013 3014 constexpr 3015 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base> 3016 : _M_outer(std::move(__outer)), _M_parent(__parent) 3017 { _M_satisfy(); } 3018 3019 constexpr explicit 3020 _Iterator(_Parent* __parent) requires (!forward_range<_Base>) 3021 : _M_parent(__parent) 3022 { _M_satisfy(); } 3023 3024 [[no_unique_address]] 3025 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer 3026 = decltype(_M_outer)(); 3027 optional<_Inner_iter> _M_inner; 3028 _Parent* _M_parent = nullptr; 3029 3030 public: 3031 using iterator_concept = decltype(_S_iter_concept()); 3032 // iterator_category defined in __join_view_iter_cat 3033 using value_type = range_value_t<range_reference_t<_Base>>; 3034 using difference_type 3035 = common_type_t<range_difference_t<_Base>, 3036 range_difference_t<range_reference_t<_Base>>>; 3037 3038 _Iterator() = default; 3039 3040 constexpr 3041 _Iterator(_Iterator<!_Const> __i) 3042 requires _Const 3043 && convertible_to<iterator_t<_Vp>, _Outer_iter> 3044 && convertible_to<iterator_t<_InnerRange>, _Inner_iter> 3045 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)), 3046 _M_parent(__i._M_parent) 3047 { } 3048 3049 constexpr decltype(auto) 3050 operator*() const 3051 { return **_M_inner; } 3052 3053 // _GLIBCXX_RESOLVE_LIB_DEFECTS 3054 // 3500. join_view::iterator::operator->() is bogus 3055 constexpr _Inner_iter 3056 operator->() const 3057 requires __detail::__has_arrow<_Inner_iter> 3058 && copyable<_Inner_iter> 3059 { return *_M_inner; } 3060 3061 constexpr _Iterator& 3062 operator++() 3063 { 3064 auto&& __inner_range = [this] () -> auto&& { 3065 if constexpr (_S_ref_is_glvalue) 3066 return *_M_get_outer(); 3067 else 3068 return *_M_parent->_M_inner; 3069 }(); 3070 if (++*_M_inner == ranges::end(__inner_range)) 3071 { 3072 ++_M_get_outer(); 3073 _M_satisfy(); 3074 } 3075 return *this; 3076 } 3077 3078 constexpr void 3079 operator++(int) 3080 { ++*this; } 3081 3082 constexpr _Iterator 3083 operator++(int) 3084 requires _S_ref_is_glvalue && forward_range<_Base> 3085 && forward_range<range_reference_t<_Base>> 3086 { 3087 auto __tmp = *this; 3088 ++*this; 3089 return __tmp; 3090 } 3091 3092 constexpr _Iterator& 3093 operator--() 3094 requires _S_ref_is_glvalue && bidirectional_range<_Base> 3095 && bidirectional_range<range_reference_t<_Base>> 3096 && common_range<range_reference_t<_Base>> 3097 { 3098 if (_M_outer == ranges::end(_M_parent->_M_base)) 3099 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer)); 3100 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer))) 3101 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer)); 3102 --*_M_inner; 3103 return *this; 3104 } 3105 3106 constexpr _Iterator 3107 operator--(int) 3108 requires _S_ref_is_glvalue && bidirectional_range<_Base> 3109 && bidirectional_range<range_reference_t<_Base>> 3110 && common_range<range_reference_t<_Base>> 3111 { 3112 auto __tmp = *this; 3113 --*this; 3114 return __tmp; 3115 } 3116 3117 friend constexpr bool 3118 operator==(const _Iterator& __x, const _Iterator& __y) 3119 requires _S_ref_is_glvalue 3120 && forward_range<_Base> 3121 && equality_comparable<_Inner_iter> 3122 { 3123 return (__x._M_outer == __y._M_outer 3124 && __x._M_inner == __y._M_inner); 3125 } 3126 3127 friend constexpr decltype(auto) 3128 iter_move(const _Iterator& __i) 3129 noexcept(noexcept(ranges::iter_move(*__i._M_inner))) 3130 { return ranges::iter_move(*__i._M_inner); } 3131 3132 friend constexpr void 3133 iter_swap(const _Iterator& __x, const _Iterator& __y) 3134 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner))) 3135 requires indirectly_swappable<_Inner_iter> 3136 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); } 3137 3138 friend _Iterator<!_Const>; 3139 template<bool> friend struct _Sentinel; 3140 }; 3141 3142 template<bool _Const> 3143 struct _Sentinel 3144 { 3145 private: 3146 using _Parent = __detail::__maybe_const_t<_Const, join_view>; 3147 using _Base = join_view::_Base<_Const>; 3148 3149 template<bool _Const2> 3150 constexpr bool 3151 __equal(const _Iterator<_Const2>& __i) const 3152 { return __i._M_get_outer() == _M_end; } 3153 3154 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 3155 3156 public: 3157 _Sentinel() = default; 3158 3159 constexpr explicit 3160 _Sentinel(_Parent* __parent) 3161 : _M_end(ranges::end(__parent->_M_base)) 3162 { } 3163 3164 constexpr 3165 _Sentinel(_Sentinel<!_Const> __s) 3166 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 3167 : _M_end(std::move(__s._M_end)) 3168 { } 3169 3170 template<bool _Const2> 3171 requires sentinel_for<sentinel_t<_Base>, 3172 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>> 3173 friend constexpr bool 3174 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y) 3175 { return __y.__equal(__x); } 3176 3177 friend _Sentinel<!_Const>; 3178 }; 3179 3180 _Vp _M_base = _Vp(); 3181 [[no_unique_address]] 3182 __detail::__maybe_present_t<!forward_range<_Vp>, 3183 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer; 3184 [[no_unique_address]] 3185 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner; 3186 3187 public: 3188 join_view() requires default_initializable<_Vp> = default; 3189 3190 constexpr explicit 3191 join_view(_Vp __base) 3192 : _M_base(std::move(__base)) 3193 { } 3194 3195 constexpr _Vp 3196 base() const& requires copy_constructible<_Vp> 3197 { return _M_base; } 3198 3199 constexpr _Vp 3200 base() && 3201 { return std::move(_M_base); } 3202 3203 constexpr auto 3204 begin() 3205 { 3206 if constexpr (forward_range<_Vp>) 3207 { 3208 constexpr bool __use_const 3209 = (__detail::__simple_view<_Vp> 3210 && is_reference_v<range_reference_t<_Vp>>); 3211 return _Iterator<__use_const>{this, ranges::begin(_M_base)}; 3212 } 3213 else 3214 { 3215 _M_outer = ranges::begin(_M_base); 3216 return _Iterator<false>{this}; 3217 } 3218 } 3219 3220 constexpr auto 3221 begin() const 3222 requires forward_range<const _Vp> 3223 && is_reference_v<range_reference_t<const _Vp>> 3224 && input_range<range_reference_t<const _Vp>> 3225 { 3226 return _Iterator<true>{this, ranges::begin(_M_base)}; 3227 } 3228 3229 constexpr auto 3230 end() 3231 { 3232 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange> 3233 && forward_range<_InnerRange> 3234 && common_range<_Vp> && common_range<_InnerRange>) 3235 return _Iterator<__detail::__simple_view<_Vp>>{this, 3236 ranges::end(_M_base)}; 3237 else 3238 return _Sentinel<__detail::__simple_view<_Vp>>{this}; 3239 } 3240 3241 constexpr auto 3242 end() const 3243 requires forward_range<const _Vp> 3244 && is_reference_v<range_reference_t<const _Vp>> 3245 && input_range<range_reference_t<const _Vp>> 3246 { 3247 if constexpr (is_reference_v<range_reference_t<const _Vp>> 3248 && forward_range<range_reference_t<const _Vp>> 3249 && common_range<const _Vp> 3250 && common_range<range_reference_t<const _Vp>>) 3251 return _Iterator<true>{this, ranges::end(_M_base)}; 3252 else 3253 return _Sentinel<true>{this}; 3254 } 3255 }; 3256 3257 template<typename _Range> 3258 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>; 3259 3260 namespace views 3261 { 3262 namespace __detail 3263 { 3264 template<typename _Range> 3265 concept __can_join_view 3266 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; }; 3267 } // namespace __detail 3268 3269 struct _Join : __adaptor::_RangeAdaptorClosure<_Join> 3270 { 3271 template<viewable_range _Range> 3272 requires __detail::__can_join_view<_Range> 3273 constexpr auto 3274 operator() [[nodiscard]] (_Range&& __r) const 3275 { 3276 // _GLIBCXX_RESOLVE_LIB_DEFECTS 3277 // 3474. Nesting join_views is broken because of CTAD 3278 return join_view<all_t<_Range>>{std::forward<_Range>(__r)}; 3279 } 3280 3281 static constexpr bool _S_has_simple_call_op = true; 3282 }; 3283 3284 inline constexpr _Join join; 3285 } // namespace views 3286 3287 namespace __detail 3288 { 3289 template<auto> 3290 struct __require_constant; 3291 3292 template<typename _Range> 3293 concept __tiny_range = sized_range<_Range> 3294 && requires 3295 { typename __require_constant<remove_reference_t<_Range>::size()>; } 3296 && (remove_reference_t<_Range>::size() <= 1); 3297 3298 template<typename _Base> 3299 struct __lazy_split_view_outer_iter_cat 3300 { }; 3301 3302 template<forward_range _Base> 3303 struct __lazy_split_view_outer_iter_cat<_Base> 3304 { using iterator_category = input_iterator_tag; }; 3305 3306 template<typename _Base> 3307 struct __lazy_split_view_inner_iter_cat 3308 { }; 3309 3310 template<forward_range _Base> 3311 struct __lazy_split_view_inner_iter_cat<_Base> 3312 { 3313 private: 3314 static constexpr auto 3315 _S_iter_cat() 3316 { 3317 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 3318 if constexpr (derived_from<_Cat, forward_iterator_tag>) 3319 return forward_iterator_tag{}; 3320 else 3321 return _Cat{}; 3322 } 3323 public: 3324 using iterator_category = decltype(_S_iter_cat()); 3325 }; 3326 } 3327 3328 template<input_range _Vp, forward_range _Pattern> 3329 requires view<_Vp> && view<_Pattern> 3330 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>, 3331 ranges::equal_to> 3332 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>) 3333 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>> 3334 { 3335 private: 3336 template<bool _Const> 3337 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 3338 3339 template<bool _Const> 3340 struct _InnerIter; 3341 3342 template<bool _Const> 3343 struct _OuterIter 3344 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>> 3345 { 3346 private: 3347 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>; 3348 using _Base = lazy_split_view::_Base<_Const>; 3349 3350 constexpr bool 3351 __at_end() const 3352 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; } 3353 3354 // [range.lazy.split.outer] p1 3355 // Many of the following specifications refer to the notional member 3356 // current of outer-iterator. current is equivalent to current_ if 3357 // V models forward_range, and parent_->current_ otherwise. 3358 constexpr auto& 3359 __current() noexcept 3360 { 3361 if constexpr (forward_range<_Vp>) 3362 return _M_current; 3363 else 3364 return *_M_parent->_M_current; 3365 } 3366 3367 constexpr auto& 3368 __current() const noexcept 3369 { 3370 if constexpr (forward_range<_Vp>) 3371 return _M_current; 3372 else 3373 return *_M_parent->_M_current; 3374 } 3375 3376 _Parent* _M_parent = nullptr; 3377 3378 [[no_unique_address]] 3379 __detail::__maybe_present_t<forward_range<_Vp>, 3380 iterator_t<_Base>> _M_current 3381 = decltype(_M_current)(); 3382 bool _M_trailing_empty = false; 3383 3384 public: 3385 using iterator_concept = __conditional_t<forward_range<_Base>, 3386 forward_iterator_tag, 3387 input_iterator_tag>; 3388 // iterator_category defined in __lazy_split_view_outer_iter_cat 3389 using difference_type = range_difference_t<_Base>; 3390 3391 struct value_type : view_interface<value_type> 3392 { 3393 private: 3394 _OuterIter _M_i = _OuterIter(); 3395 3396 // _GLIBCXX_RESOLVE_LIB_DEFECTS 3397 // 4013. lazy_split_view::outer-iterator::value_type should not 3398 // provide default constructor 3399 constexpr explicit 3400 value_type(_OuterIter __i) 3401 : _M_i(std::move(__i)) 3402 { } 3403 3404 friend _OuterIter; 3405 3406 public: 3407 constexpr _InnerIter<_Const> 3408 begin() const 3409 { return _InnerIter<_Const>{_M_i}; } 3410 3411 constexpr default_sentinel_t 3412 end() const noexcept 3413 { return default_sentinel; } 3414 }; 3415 3416 _OuterIter() = default; 3417 3418 constexpr explicit 3419 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>) 3420 : _M_parent(__parent) 3421 { } 3422 3423 constexpr 3424 _OuterIter(_Parent* __parent, iterator_t<_Base> __current) 3425 requires forward_range<_Base> 3426 : _M_parent(__parent), 3427 _M_current(std::move(__current)) 3428 { } 3429 3430 constexpr 3431 _OuterIter(_OuterIter<!_Const> __i) 3432 requires _Const 3433 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 3434 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)), 3435 _M_trailing_empty(__i._M_trailing_empty) 3436 { } 3437 3438 constexpr value_type 3439 operator*() const 3440 { return value_type{*this}; } 3441 3442 constexpr _OuterIter& 3443 operator++() 3444 { 3445 // _GLIBCXX_RESOLVE_LIB_DEFECTS 3446 // 3505. lazy_split_view::outer-iterator::operator++ misspecified 3447 const auto __end = ranges::end(_M_parent->_M_base); 3448 if (__current() == __end) 3449 { 3450 _M_trailing_empty = false; 3451 return *this; 3452 } 3453 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern}; 3454 if (__pbegin == __pend) 3455 ++__current(); 3456 else if constexpr (__detail::__tiny_range<_Pattern>) 3457 { 3458 __current() = ranges::find(std::move(__current()), __end, 3459 *__pbegin); 3460 if (__current() != __end) 3461 { 3462 ++__current(); 3463 if (__current() == __end) 3464 _M_trailing_empty = true; 3465 } 3466 } 3467 else 3468 do 3469 { 3470 auto [__b, __p] 3471 = ranges::mismatch(__current(), __end, __pbegin, __pend); 3472 if (__p == __pend) 3473 { 3474 __current() = __b; 3475 if (__current() == __end) 3476 _M_trailing_empty = true; 3477 break; 3478 } 3479 } while (++__current() != __end); 3480 return *this; 3481 } 3482 3483 constexpr decltype(auto) 3484 operator++(int) 3485 { 3486 if constexpr (forward_range<_Base>) 3487 { 3488 auto __tmp = *this; 3489 ++*this; 3490 return __tmp; 3491 } 3492 else 3493 ++*this; 3494 } 3495 3496 friend constexpr bool 3497 operator==(const _OuterIter& __x, const _OuterIter& __y) 3498 requires forward_range<_Base> 3499 { 3500 return __x._M_current == __y._M_current 3501 && __x._M_trailing_empty == __y._M_trailing_empty; 3502 } 3503 3504 friend constexpr bool 3505 operator==(const _OuterIter& __x, default_sentinel_t) 3506 { return __x.__at_end(); }; 3507 3508 friend _OuterIter<!_Const>; 3509 friend _InnerIter<_Const>; 3510 }; 3511 3512 template<bool _Const> 3513 struct _InnerIter 3514 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>> 3515 { 3516 private: 3517 using _Base = lazy_split_view::_Base<_Const>; 3518 3519 constexpr bool 3520 __at_end() const 3521 { 3522 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern}; 3523 auto __end = ranges::end(_M_i._M_parent->_M_base); 3524 if constexpr (__detail::__tiny_range<_Pattern>) 3525 { 3526 const auto& __cur = _M_i_current(); 3527 if (__cur == __end) 3528 return true; 3529 if (__pcur == __pend) 3530 return _M_incremented; 3531 return *__cur == *__pcur; 3532 } 3533 else 3534 { 3535 auto __cur = _M_i_current(); 3536 if (__cur == __end) 3537 return true; 3538 if (__pcur == __pend) 3539 return _M_incremented; 3540 do 3541 { 3542 if (*__cur != *__pcur) 3543 return false; 3544 if (++__pcur == __pend) 3545 return true; 3546 } while (++__cur != __end); 3547 return false; 3548 } 3549 } 3550 3551 constexpr auto& 3552 _M_i_current() noexcept 3553 { return _M_i.__current(); } 3554 3555 constexpr auto& 3556 _M_i_current() const noexcept 3557 { return _M_i.__current(); } 3558 3559 _OuterIter<_Const> _M_i = _OuterIter<_Const>(); 3560 bool _M_incremented = false; 3561 3562 public: 3563 using iterator_concept 3564 = typename _OuterIter<_Const>::iterator_concept; 3565 // iterator_category defined in __lazy_split_view_inner_iter_cat 3566 using value_type = range_value_t<_Base>; 3567 using difference_type = range_difference_t<_Base>; 3568 3569 _InnerIter() = default; 3570 3571 constexpr explicit 3572 _InnerIter(_OuterIter<_Const> __i) 3573 : _M_i(std::move(__i)) 3574 { } 3575 3576 constexpr const iterator_t<_Base>& 3577 base() const& noexcept 3578 { return _M_i_current(); } 3579 3580 constexpr iterator_t<_Base> 3581 base() && requires forward_range<_Vp> 3582 { return std::move(_M_i_current()); } 3583 3584 constexpr decltype(auto) 3585 operator*() const 3586 { return *_M_i_current(); } 3587 3588 constexpr _InnerIter& 3589 operator++() 3590 { 3591 _M_incremented = true; 3592 if constexpr (!forward_range<_Base>) 3593 if constexpr (_Pattern::size() == 0) 3594 return *this; 3595 ++_M_i_current(); 3596 return *this; 3597 } 3598 3599 constexpr decltype(auto) 3600 operator++(int) 3601 { 3602 if constexpr (forward_range<_Base>) 3603 { 3604 auto __tmp = *this; 3605 ++*this; 3606 return __tmp; 3607 } 3608 else 3609 ++*this; 3610 } 3611 3612 friend constexpr bool 3613 operator==(const _InnerIter& __x, const _InnerIter& __y) 3614 requires forward_range<_Base> 3615 { return __x._M_i == __y._M_i; } 3616 3617 friend constexpr bool 3618 operator==(const _InnerIter& __x, default_sentinel_t) 3619 { return __x.__at_end(); } 3620 3621 friend constexpr decltype(auto) 3622 iter_move(const _InnerIter& __i) 3623 noexcept(noexcept(ranges::iter_move(__i._M_i_current()))) 3624 { return ranges::iter_move(__i._M_i_current()); } 3625 3626 friend constexpr void 3627 iter_swap(const _InnerIter& __x, const _InnerIter& __y) 3628 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(), 3629 __y._M_i_current()))) 3630 requires indirectly_swappable<iterator_t<_Base>> 3631 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); } 3632 }; 3633 3634 _Vp _M_base = _Vp(); 3635 _Pattern _M_pattern = _Pattern(); 3636 [[no_unique_address]] 3637 __detail::__maybe_present_t<!forward_range<_Vp>, 3638 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current; 3639 3640 3641 public: 3642 lazy_split_view() requires (default_initializable<_Vp> 3643 && default_initializable<_Pattern>) 3644 = default; 3645 3646 constexpr 3647 lazy_split_view(_Vp __base, _Pattern __pattern) 3648 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) 3649 { } 3650 3651 template<input_range _Range> 3652 requires constructible_from<_Vp, views::all_t<_Range>> 3653 && constructible_from<_Pattern, single_view<range_value_t<_Range>>> 3654 constexpr 3655 lazy_split_view(_Range&& __r, range_value_t<_Range> __e) 3656 : _M_base(views::all(std::forward<_Range>(__r))), 3657 _M_pattern(views::single(std::move(__e))) 3658 { } 3659 3660 constexpr _Vp 3661 base() const& requires copy_constructible<_Vp> 3662 { return _M_base; } 3663 3664 constexpr _Vp 3665 base() && 3666 { return std::move(_M_base); } 3667 3668 constexpr auto 3669 begin() 3670 { 3671 if constexpr (forward_range<_Vp>) 3672 { 3673 constexpr bool __simple 3674 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>; 3675 return _OuterIter<__simple>{this, ranges::begin(_M_base)}; 3676 } 3677 else 3678 { 3679 _M_current = ranges::begin(_M_base); 3680 return _OuterIter<false>{this}; 3681 } 3682 } 3683 3684 constexpr auto 3685 begin() const requires forward_range<_Vp> && forward_range<const _Vp> 3686 { 3687 return _OuterIter<true>{this, ranges::begin(_M_base)}; 3688 } 3689 3690 constexpr auto 3691 end() requires forward_range<_Vp> && common_range<_Vp> 3692 { 3693 constexpr bool __simple 3694 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>; 3695 return _OuterIter<__simple>{this, ranges::end(_M_base)}; 3696 } 3697 3698 constexpr auto 3699 end() const 3700 { 3701 if constexpr (forward_range<_Vp> 3702 && forward_range<const _Vp> 3703 && common_range<const _Vp>) 3704 return _OuterIter<true>{this, ranges::end(_M_base)}; 3705 else 3706 return default_sentinel; 3707 } 3708 }; 3709 3710 template<typename _Range, typename _Pattern> 3711 lazy_split_view(_Range&&, _Pattern&&) 3712 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>; 3713 3714 template<input_range _Range> 3715 lazy_split_view(_Range&&, range_value_t<_Range>) 3716 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>; 3717 3718 namespace views 3719 { 3720 namespace __detail 3721 { 3722 template<typename _Range, typename _Pattern> 3723 concept __can_lazy_split_view 3724 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); }; 3725 } // namespace __detail 3726 3727 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit> 3728 { 3729 template<viewable_range _Range, typename _Pattern> 3730 requires __detail::__can_lazy_split_view<_Range, _Pattern> 3731 constexpr auto 3732 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const 3733 { 3734 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f)); 3735 } 3736 3737 using _RangeAdaptor<_LazySplit>::operator(); 3738 static constexpr int _S_arity = 2; 3739 // The pattern argument of views::lazy_split is not always simple -- it can be 3740 // a non-view range, the value category of which affects whether the call 3741 // is well-formed. But a scalar or a view pattern argument is surely 3742 // simple. 3743 template<typename _Pattern> 3744 static constexpr bool _S_has_simple_extra_args 3745 = is_scalar_v<_Pattern> || (view<_Pattern> 3746 && copy_constructible<_Pattern>); 3747 }; 3748 3749 inline constexpr _LazySplit lazy_split; 3750 } // namespace views 3751 3752 template<forward_range _Vp, forward_range _Pattern> 3753 requires view<_Vp> && view<_Pattern> 3754 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>, 3755 ranges::equal_to> 3756 class split_view : public view_interface<split_view<_Vp, _Pattern>> 3757 { 3758 private: 3759 _Vp _M_base = _Vp(); 3760 _Pattern _M_pattern = _Pattern(); 3761 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin; 3762 3763 struct _Iterator; 3764 struct _Sentinel; 3765 3766 public: 3767 split_view() requires (default_initializable<_Vp> 3768 && default_initializable<_Pattern>) 3769 = default; 3770 3771 constexpr 3772 split_view(_Vp __base, _Pattern __pattern) 3773 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) 3774 { } 3775 3776 template<forward_range _Range> 3777 requires constructible_from<_Vp, views::all_t<_Range>> 3778 && constructible_from<_Pattern, single_view<range_value_t<_Range>>> 3779 constexpr 3780 split_view(_Range&& __r, range_value_t<_Range> __e) 3781 : _M_base(views::all(std::forward<_Range>(__r))), 3782 _M_pattern(views::single(std::move(__e))) 3783 { } 3784 3785 constexpr _Vp 3786 base() const& requires copy_constructible<_Vp> 3787 { return _M_base; } 3788 3789 constexpr _Vp 3790 base() && 3791 { return std::move(_M_base); } 3792 3793 constexpr _Iterator 3794 begin() 3795 { 3796 if (!_M_cached_begin) 3797 _M_cached_begin = _M_find_next(ranges::begin(_M_base)); 3798 return {this, ranges::begin(_M_base), *_M_cached_begin}; 3799 } 3800 3801 constexpr auto 3802 end() 3803 { 3804 if constexpr (common_range<_Vp>) 3805 return _Iterator{this, ranges::end(_M_base), {}}; 3806 else 3807 return _Sentinel{this}; 3808 } 3809 3810 constexpr subrange<iterator_t<_Vp>> 3811 _M_find_next(iterator_t<_Vp> __it) 3812 { 3813 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern); 3814 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern)) 3815 { 3816 ++__b; 3817 ++__e; 3818 } 3819 return {__b, __e}; 3820 } 3821 3822 private: 3823 struct _Iterator 3824 { 3825 private: 3826 split_view* _M_parent = nullptr; 3827 iterator_t<_Vp> _M_cur = iterator_t<_Vp>(); 3828 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>(); 3829 bool _M_trailing_empty = false; 3830 3831 friend struct _Sentinel; 3832 3833 public: 3834 using iterator_concept = forward_iterator_tag; 3835 using iterator_category = input_iterator_tag; 3836 using value_type = subrange<iterator_t<_Vp>>; 3837 using difference_type = range_difference_t<_Vp>; 3838 3839 _Iterator() = default; 3840 3841 constexpr 3842 _Iterator(split_view* __parent, 3843 iterator_t<_Vp> __current, 3844 subrange<iterator_t<_Vp>> __next) 3845 : _M_parent(__parent), 3846 _M_cur(std::move(__current)), 3847 _M_next(std::move(__next)) 3848 { } 3849 3850 constexpr iterator_t<_Vp> 3851 base() const 3852 { return _M_cur; } 3853 3854 constexpr value_type 3855 operator*() const 3856 { return {_M_cur, _M_next.begin()}; } 3857 3858 constexpr _Iterator& 3859 operator++() 3860 { 3861 _M_cur = _M_next.begin(); 3862 if (_M_cur != ranges::end(_M_parent->_M_base)) 3863 { 3864 _M_cur = _M_next.end(); 3865 if (_M_cur == ranges::end(_M_parent->_M_base)) 3866 { 3867 _M_trailing_empty = true; 3868 _M_next = {_M_cur, _M_cur}; 3869 } 3870 else 3871 _M_next = _M_parent->_M_find_next(_M_cur); 3872 } 3873 else 3874 _M_trailing_empty = false; 3875 return *this; 3876 } 3877 3878 constexpr _Iterator 3879 operator++(int) 3880 { 3881 auto __tmp = *this; 3882 ++*this; 3883 return __tmp; 3884 } 3885 3886 friend constexpr bool 3887 operator==(const _Iterator& __x, const _Iterator& __y) 3888 { 3889 return __x._M_cur == __y._M_cur 3890 && __x._M_trailing_empty == __y._M_trailing_empty; 3891 } 3892 }; 3893 3894 struct _Sentinel 3895 { 3896 private: 3897 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>(); 3898 3899 constexpr bool 3900 _M_equal(const _Iterator& __x) const 3901 { return __x._M_cur == _M_end && !__x._M_trailing_empty; } 3902 3903 public: 3904 _Sentinel() = default; 3905 3906 constexpr explicit 3907 _Sentinel(split_view* __parent) 3908 : _M_end(ranges::end(__parent->_M_base)) 3909 { } 3910 3911 friend constexpr bool 3912 operator==(const _Iterator& __x, const _Sentinel& __y) 3913 { return __y._M_equal(__x); } 3914 }; 3915 }; 3916 3917 template<typename _Range, typename _Pattern> 3918 split_view(_Range&&, _Pattern&&) 3919 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>; 3920 3921 template<forward_range _Range> 3922 split_view(_Range&&, range_value_t<_Range>) 3923 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>; 3924 3925 namespace views 3926 { 3927 namespace __detail 3928 { 3929 template<typename _Range, typename _Pattern> 3930 concept __can_split_view 3931 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); }; 3932 } // namespace __detail 3933 3934 struct _Split : __adaptor::_RangeAdaptor<_Split> 3935 { 3936 template<viewable_range _Range, typename _Pattern> 3937 requires __detail::__can_split_view<_Range, _Pattern> 3938 constexpr auto 3939 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const 3940 { 3941 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f)); 3942 } 3943 3944 using _RangeAdaptor<_Split>::operator(); 3945 static constexpr int _S_arity = 2; 3946 template<typename _Pattern> 3947 static constexpr bool _S_has_simple_extra_args 3948 = _LazySplit::_S_has_simple_extra_args<_Pattern>; 3949 }; 3950 3951 inline constexpr _Split split; 3952 } // namespace views 3953 3954 namespace views 3955 { 3956 struct _Counted 3957 { 3958 template<input_or_output_iterator _Iter> 3959 constexpr auto 3960 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const 3961 { 3962 if constexpr (contiguous_iterator<_Iter>) 3963 return span(std::to_address(__i), __n); 3964 else if constexpr (random_access_iterator<_Iter>) 3965 return subrange(__i, __i + __n); 3966 else 3967 return subrange(counted_iterator(std::move(__i), __n), 3968 default_sentinel); 3969 } 3970 }; 3971 3972 inline constexpr _Counted counted{}; 3973 } // namespace views 3974 3975 template<view _Vp> 3976 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>> 3977 class common_view : public view_interface<common_view<_Vp>> 3978 { 3979 private: 3980 _Vp _M_base = _Vp(); 3981 3982 public: 3983 common_view() requires default_initializable<_Vp> = default; 3984 3985 constexpr explicit 3986 common_view(_Vp __r) 3987 : _M_base(std::move(__r)) 3988 { } 3989 3990 constexpr _Vp 3991 base() const& requires copy_constructible<_Vp> 3992 { return _M_base; } 3993 3994 constexpr _Vp 3995 base() && 3996 { return std::move(_M_base); } 3997 3998 // _GLIBCXX_RESOLVE_LIB_DEFECTS 3999 // 4012. common_view::begin/end are missing the simple-view check 4000 constexpr auto 4001 begin() requires (!__detail::__simple_view<_Vp>) 4002 { 4003 if constexpr (random_access_range<_Vp> && sized_range<_Vp>) 4004 return ranges::begin(_M_base); 4005 else 4006 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>> 4007 (ranges::begin(_M_base)); 4008 } 4009 4010 constexpr auto 4011 begin() const requires range<const _Vp> 4012 { 4013 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>) 4014 return ranges::begin(_M_base); 4015 else 4016 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>> 4017 (ranges::begin(_M_base)); 4018 } 4019 4020 constexpr auto 4021 end() requires (!__detail::__simple_view<_Vp>) 4022 { 4023 if constexpr (random_access_range<_Vp> && sized_range<_Vp>) 4024 return ranges::begin(_M_base) + ranges::size(_M_base); 4025 else 4026 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>> 4027 (ranges::end(_M_base)); 4028 } 4029 4030 constexpr auto 4031 end() const requires range<const _Vp> 4032 { 4033 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>) 4034 return ranges::begin(_M_base) + ranges::size(_M_base); 4035 else 4036 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>> 4037 (ranges::end(_M_base)); 4038 } 4039 4040 constexpr auto 4041 size() requires sized_range<_Vp> 4042 { return ranges::size(_M_base); } 4043 4044 constexpr auto 4045 size() const requires sized_range<const _Vp> 4046 { return ranges::size(_M_base); } 4047 }; 4048 4049 template<typename _Range> 4050 common_view(_Range&&) -> common_view<views::all_t<_Range>>; 4051 4052 template<typename _Tp> 4053 inline constexpr bool enable_borrowed_range<common_view<_Tp>> 4054 = enable_borrowed_range<_Tp>; 4055 4056 namespace views 4057 { 4058 namespace __detail 4059 { 4060 template<typename _Range> 4061 concept __already_common = common_range<_Range> 4062 && requires { views::all(std::declval<_Range>()); }; 4063 4064 template<typename _Range> 4065 concept __can_common_view 4066 = requires { common_view{std::declval<_Range>()}; }; 4067 } // namespace __detail 4068 4069 struct _Common : __adaptor::_RangeAdaptorClosure<_Common> 4070 { 4071 template<viewable_range _Range> 4072 requires __detail::__already_common<_Range> 4073 || __detail::__can_common_view<_Range> 4074 constexpr auto 4075 operator() [[nodiscard]] (_Range&& __r) const 4076 { 4077 if constexpr (__detail::__already_common<_Range>) 4078 return views::all(std::forward<_Range>(__r)); 4079 else 4080 return common_view{std::forward<_Range>(__r)}; 4081 } 4082 4083 static constexpr bool _S_has_simple_call_op = true; 4084 }; 4085 4086 inline constexpr _Common common; 4087 } // namespace views 4088 4089 template<view _Vp> 4090 requires bidirectional_range<_Vp> 4091 class reverse_view : public view_interface<reverse_view<_Vp>> 4092 { 4093 private: 4094 static constexpr bool _S_needs_cached_begin 4095 = !common_range<_Vp> && !(random_access_range<_Vp> 4096 && sized_sentinel_for<sentinel_t<_Vp>, 4097 iterator_t<_Vp>>); 4098 4099 _Vp _M_base = _Vp(); 4100 [[no_unique_address]] 4101 __detail::__maybe_present_t<_S_needs_cached_begin, 4102 __detail::_CachedPosition<_Vp>> 4103 _M_cached_begin; 4104 4105 public: 4106 reverse_view() requires default_initializable<_Vp> = default; 4107 4108 constexpr explicit 4109 reverse_view(_Vp __r) 4110 : _M_base(std::move(__r)) 4111 { } 4112 4113 constexpr _Vp 4114 base() const& requires copy_constructible<_Vp> 4115 { return _M_base; } 4116 4117 constexpr _Vp 4118 base() && 4119 { return std::move(_M_base); } 4120 4121 constexpr reverse_iterator<iterator_t<_Vp>> 4122 begin() 4123 { 4124 if constexpr (_S_needs_cached_begin) 4125 if (_M_cached_begin._M_has_value()) 4126 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base)); 4127 4128 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base)); 4129 if constexpr (_S_needs_cached_begin) 4130 _M_cached_begin._M_set(_M_base, __it); 4131 return std::make_reverse_iterator(std::move(__it)); 4132 } 4133 4134 constexpr auto 4135 begin() requires common_range<_Vp> 4136 { return std::make_reverse_iterator(ranges::end(_M_base)); } 4137 4138 constexpr auto 4139 begin() const requires common_range<const _Vp> 4140 { return std::make_reverse_iterator(ranges::end(_M_base)); } 4141 4142 constexpr reverse_iterator<iterator_t<_Vp>> 4143 end() 4144 { return std::make_reverse_iterator(ranges::begin(_M_base)); } 4145 4146 constexpr auto 4147 end() const requires common_range<const _Vp> 4148 { return std::make_reverse_iterator(ranges::begin(_M_base)); } 4149 4150 constexpr auto 4151 size() requires sized_range<_Vp> 4152 { return ranges::size(_M_base); } 4153 4154 constexpr auto 4155 size() const requires sized_range<const _Vp> 4156 { return ranges::size(_M_base); } 4157 }; 4158 4159 template<typename _Range> 4160 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>; 4161 4162 template<typename _Tp> 4163 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>> 4164 = enable_borrowed_range<_Tp>; 4165 4166 namespace views 4167 { 4168 namespace __detail 4169 { 4170 template<typename> 4171 inline constexpr bool __is_reversible_subrange = false; 4172 4173 template<typename _Iter, subrange_kind _Kind> 4174 inline constexpr bool 4175 __is_reversible_subrange<subrange<reverse_iterator<_Iter>, 4176 reverse_iterator<_Iter>, 4177 _Kind>> = true; 4178 4179 template<typename> 4180 inline constexpr bool __is_reverse_view = false; 4181 4182 template<typename _Vp> 4183 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true; 4184 4185 template<typename _Range> 4186 concept __can_reverse_view 4187 = requires { reverse_view{std::declval<_Range>()}; }; 4188 } // namespace __detail 4189 4190 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse> 4191 { 4192 template<viewable_range _Range> 4193 requires __detail::__is_reverse_view<remove_cvref_t<_Range>> 4194 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>> 4195 || __detail::__can_reverse_view<_Range> 4196 constexpr auto 4197 operator() [[nodiscard]] (_Range&& __r) const 4198 { 4199 using _Tp = remove_cvref_t<_Range>; 4200 if constexpr (__detail::__is_reverse_view<_Tp>) 4201 return std::forward<_Range>(__r).base(); 4202 else if constexpr (__detail::__is_reversible_subrange<_Tp>) 4203 { 4204 using _Iter = decltype(ranges::begin(__r).base()); 4205 if constexpr (sized_range<_Tp>) 4206 return subrange<_Iter, _Iter, subrange_kind::sized> 4207 {__r.end().base(), __r.begin().base(), __r.size()}; 4208 else 4209 return subrange<_Iter, _Iter, subrange_kind::unsized> 4210 {__r.end().base(), __r.begin().base()}; 4211 } 4212 else 4213 return reverse_view{std::forward<_Range>(__r)}; 4214 } 4215 4216 static constexpr bool _S_has_simple_call_op = true; 4217 }; 4218 4219 inline constexpr _Reverse reverse; 4220 } // namespace views 4221 4222 namespace __detail 4223 { 4224 #if __cpp_lib_tuple_like // >= C++23 4225 template<typename _Tp, size_t _Nm> 4226 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>; 4227 #else 4228 template<typename _Tp, size_t _Nm> 4229 concept __has_tuple_element = requires(_Tp __t) 4230 { 4231 typename tuple_size<_Tp>::type; 4232 requires _Nm < tuple_size_v<_Tp>; 4233 typename tuple_element_t<_Nm, _Tp>; 4234 { std::get<_Nm>(__t) } 4235 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>; 4236 }; 4237 #endif 4238 4239 template<typename _Tp, size_t _Nm> 4240 concept __returnable_element 4241 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>; 4242 } 4243 4244 template<input_range _Vp, size_t _Nm> 4245 requires view<_Vp> 4246 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm> 4247 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>, 4248 _Nm> 4249 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm> 4250 class elements_view : public view_interface<elements_view<_Vp, _Nm>> 4251 { 4252 public: 4253 elements_view() requires default_initializable<_Vp> = default; 4254 4255 constexpr explicit 4256 elements_view(_Vp __base) 4257 : _M_base(std::move(__base)) 4258 { } 4259 4260 constexpr _Vp 4261 base() const& requires copy_constructible<_Vp> 4262 { return _M_base; } 4263 4264 constexpr _Vp 4265 base() && 4266 { return std::move(_M_base); } 4267 4268 constexpr auto 4269 begin() requires (!__detail::__simple_view<_Vp>) 4270 { return _Iterator<false>(ranges::begin(_M_base)); } 4271 4272 constexpr auto 4273 begin() const requires range<const _Vp> 4274 { return _Iterator<true>(ranges::begin(_M_base)); } 4275 4276 constexpr auto 4277 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>) 4278 { return _Sentinel<false>{ranges::end(_M_base)}; } 4279 4280 constexpr auto 4281 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>) 4282 { return _Iterator<false>{ranges::end(_M_base)}; } 4283 4284 constexpr auto 4285 end() const requires range<const _Vp> 4286 { return _Sentinel<true>{ranges::end(_M_base)}; } 4287 4288 constexpr auto 4289 end() const requires common_range<const _Vp> 4290 { return _Iterator<true>{ranges::end(_M_base)}; } 4291 4292 constexpr auto 4293 size() requires sized_range<_Vp> 4294 { return ranges::size(_M_base); } 4295 4296 constexpr auto 4297 size() const requires sized_range<const _Vp> 4298 { return ranges::size(_M_base); } 4299 4300 private: 4301 template<bool _Const> 4302 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 4303 4304 template<bool _Const> 4305 struct __iter_cat 4306 { }; 4307 4308 template<bool _Const> 4309 requires forward_range<_Base<_Const>> 4310 struct __iter_cat<_Const> 4311 { 4312 private: 4313 static auto _S_iter_cat() 4314 { 4315 using _Base = elements_view::_Base<_Const>; 4316 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 4317 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>()))); 4318 if constexpr (!is_lvalue_reference_v<_Res>) 4319 return input_iterator_tag{}; 4320 else if constexpr (derived_from<_Cat, random_access_iterator_tag>) 4321 return random_access_iterator_tag{}; 4322 else 4323 return _Cat{}; 4324 } 4325 public: 4326 using iterator_category = decltype(_S_iter_cat()); 4327 }; 4328 4329 template<bool _Const> 4330 struct _Sentinel; 4331 4332 template<bool _Const> 4333 struct _Iterator : __iter_cat<_Const> 4334 { 4335 private: 4336 using _Base = elements_view::_Base<_Const>; 4337 4338 iterator_t<_Base> _M_current = iterator_t<_Base>(); 4339 4340 static constexpr decltype(auto) 4341 _S_get_element(const iterator_t<_Base>& __i) 4342 { 4343 if constexpr (is_reference_v<range_reference_t<_Base>>) 4344 return std::get<_Nm>(*__i); 4345 else 4346 { 4347 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>; 4348 return static_cast<_Et>(std::get<_Nm>(*__i)); 4349 } 4350 } 4351 4352 static auto 4353 _S_iter_concept() 4354 { 4355 if constexpr (random_access_range<_Base>) 4356 return random_access_iterator_tag{}; 4357 else if constexpr (bidirectional_range<_Base>) 4358 return bidirectional_iterator_tag{}; 4359 else if constexpr (forward_range<_Base>) 4360 return forward_iterator_tag{}; 4361 else 4362 return input_iterator_tag{}; 4363 } 4364 4365 friend _Iterator<!_Const>; 4366 4367 public: 4368 using iterator_concept = decltype(_S_iter_concept()); 4369 // iterator_category defined in elements_view::__iter_cat 4370 using value_type 4371 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>; 4372 using difference_type = range_difference_t<_Base>; 4373 4374 _Iterator() requires default_initializable<iterator_t<_Base>> = default; 4375 4376 constexpr explicit 4377 _Iterator(iterator_t<_Base> __current) 4378 : _M_current(std::move(__current)) 4379 { } 4380 4381 constexpr 4382 _Iterator(_Iterator<!_Const> __i) 4383 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 4384 : _M_current(std::move(__i._M_current)) 4385 { } 4386 4387 constexpr const iterator_t<_Base>& 4388 base() const& noexcept 4389 { return _M_current; } 4390 4391 constexpr iterator_t<_Base> 4392 base() && 4393 { return std::move(_M_current); } 4394 4395 constexpr decltype(auto) 4396 operator*() const 4397 { return _S_get_element(_M_current); } 4398 4399 constexpr _Iterator& 4400 operator++() 4401 { 4402 ++_M_current; 4403 return *this; 4404 } 4405 4406 constexpr void 4407 operator++(int) 4408 { ++_M_current; } 4409 4410 constexpr _Iterator 4411 operator++(int) requires forward_range<_Base> 4412 { 4413 auto __tmp = *this; 4414 ++_M_current; 4415 return __tmp; 4416 } 4417 4418 constexpr _Iterator& 4419 operator--() requires bidirectional_range<_Base> 4420 { 4421 --_M_current; 4422 return *this; 4423 } 4424 4425 constexpr _Iterator 4426 operator--(int) requires bidirectional_range<_Base> 4427 { 4428 auto __tmp = *this; 4429 --_M_current; 4430 return __tmp; 4431 } 4432 4433 constexpr _Iterator& 4434 operator+=(difference_type __n) 4435 requires random_access_range<_Base> 4436 { 4437 _M_current += __n; 4438 return *this; 4439 } 4440 4441 constexpr _Iterator& 4442 operator-=(difference_type __n) 4443 requires random_access_range<_Base> 4444 { 4445 _M_current -= __n; 4446 return *this; 4447 } 4448 4449 constexpr decltype(auto) 4450 operator[](difference_type __n) const 4451 requires random_access_range<_Base> 4452 { return _S_get_element(_M_current + __n); } 4453 4454 friend constexpr bool 4455 operator==(const _Iterator& __x, const _Iterator& __y) 4456 requires equality_comparable<iterator_t<_Base>> 4457 { return __x._M_current == __y._M_current; } 4458 4459 friend constexpr bool 4460 operator<(const _Iterator& __x, const _Iterator& __y) 4461 requires random_access_range<_Base> 4462 { return __x._M_current < __y._M_current; } 4463 4464 friend constexpr bool 4465 operator>(const _Iterator& __x, const _Iterator& __y) 4466 requires random_access_range<_Base> 4467 { return __y._M_current < __x._M_current; } 4468 4469 friend constexpr bool 4470 operator<=(const _Iterator& __x, const _Iterator& __y) 4471 requires random_access_range<_Base> 4472 { return !(__y._M_current > __x._M_current); } 4473 4474 friend constexpr bool 4475 operator>=(const _Iterator& __x, const _Iterator& __y) 4476 requires random_access_range<_Base> 4477 { return !(__x._M_current > __y._M_current); } 4478 4479 #ifdef __cpp_lib_three_way_comparison 4480 friend constexpr auto 4481 operator<=>(const _Iterator& __x, const _Iterator& __y) 4482 requires random_access_range<_Base> 4483 && three_way_comparable<iterator_t<_Base>> 4484 { return __x._M_current <=> __y._M_current; } 4485 #endif 4486 4487 friend constexpr _Iterator 4488 operator+(const _Iterator& __x, difference_type __y) 4489 requires random_access_range<_Base> 4490 { return _Iterator{__x} += __y; } 4491 4492 friend constexpr _Iterator 4493 operator+(difference_type __x, const _Iterator& __y) 4494 requires random_access_range<_Base> 4495 { return __y + __x; } 4496 4497 friend constexpr _Iterator 4498 operator-(const _Iterator& __x, difference_type __y) 4499 requires random_access_range<_Base> 4500 { return _Iterator{__x} -= __y; } 4501 4502 // _GLIBCXX_RESOLVE_LIB_DEFECTS 4503 // 3483. transform_view::iterator's difference is overconstrained 4504 friend constexpr difference_type 4505 operator-(const _Iterator& __x, const _Iterator& __y) 4506 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 4507 { return __x._M_current - __y._M_current; } 4508 4509 template <bool> friend struct _Sentinel; 4510 }; 4511 4512 template<bool _Const> 4513 struct _Sentinel 4514 { 4515 private: 4516 template<bool _Const2> 4517 constexpr bool 4518 _M_equal(const _Iterator<_Const2>& __x) const 4519 { return __x._M_current == _M_end; } 4520 4521 template<bool _Const2> 4522 constexpr auto 4523 _M_distance_from(const _Iterator<_Const2>& __i) const 4524 { return _M_end - __i._M_current; } 4525 4526 using _Base = elements_view::_Base<_Const>; 4527 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 4528 4529 public: 4530 _Sentinel() = default; 4531 4532 constexpr explicit 4533 _Sentinel(sentinel_t<_Base> __end) 4534 : _M_end(std::move(__end)) 4535 { } 4536 4537 constexpr 4538 _Sentinel(_Sentinel<!_Const> __other) 4539 requires _Const 4540 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 4541 : _M_end(std::move(__other._M_end)) 4542 { } 4543 4544 constexpr sentinel_t<_Base> 4545 base() const 4546 { return _M_end; } 4547 4548 template<bool _Const2> 4549 requires sentinel_for<sentinel_t<_Base>, 4550 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>> 4551 friend constexpr bool 4552 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y) 4553 { return __y._M_equal(__x); } 4554 4555 template<bool _Const2, 4556 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 4557 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 4558 friend constexpr range_difference_t<_Base2> 4559 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y) 4560 { return -__y._M_distance_from(__x); } 4561 4562 template<bool _Const2, 4563 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>> 4564 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>> 4565 friend constexpr range_difference_t<_Base2> 4566 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y) 4567 { return __x._M_distance_from(__y); } 4568 4569 friend _Sentinel<!_Const>; 4570 }; 4571 4572 _Vp _M_base = _Vp(); 4573 }; 4574 4575 template<typename _Tp, size_t _Nm> 4576 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>> 4577 = enable_borrowed_range<_Tp>; 4578 4579 // _GLIBCXX_RESOLVE_LIB_DEFECTS 4580 // 3563. keys_view example is broken 4581 template<typename _Range> 4582 using keys_view = elements_view<_Range, 0>; 4583 4584 template<typename _Range> 4585 using values_view = elements_view<_Range, 1>; 4586 4587 namespace views 4588 { 4589 namespace __detail 4590 { 4591 template<size_t _Nm, typename _Range> 4592 concept __can_elements_view 4593 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; }; 4594 } // namespace __detail 4595 4596 template<size_t _Nm> 4597 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>> 4598 { 4599 template<viewable_range _Range> 4600 requires __detail::__can_elements_view<_Nm, _Range> 4601 constexpr auto 4602 operator() [[nodiscard]] (_Range&& __r) const 4603 { 4604 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)}; 4605 } 4606 4607 static constexpr bool _S_has_simple_call_op = true; 4608 }; 4609 4610 template<size_t _Nm> 4611 inline constexpr _Elements<_Nm> elements; 4612 inline constexpr auto keys = elements<0>; 4613 inline constexpr auto values = elements<1>; 4614 } // namespace views 4615 4616 #ifdef __cpp_lib_ranges_zip // C++ >= 23 4617 namespace __detail 4618 { 4619 template<typename... _Rs> 4620 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...)) 4621 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...)) 4622 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...)); 4623 4624 template<typename _Fp, typename _Tuple> 4625 constexpr auto 4626 __tuple_transform(_Fp&& __f, _Tuple&& __tuple) 4627 { 4628 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) { 4629 return tuple<invoke_result_t<_Fp&, _Ts>...> 4630 (std::__invoke(__f, std::forward<_Ts>(__elts))...); 4631 }, std::forward<_Tuple>(__tuple)); 4632 } 4633 4634 template<typename _Fp, typename _Tuple> 4635 constexpr void 4636 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple) 4637 { 4638 std::apply([&]<typename... _Ts>(_Ts&&... __elts) { 4639 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...); 4640 }, std::forward<_Tuple>(__tuple)); 4641 } 4642 } // namespace __detail 4643 4644 template<input_range... _Vs> 4645 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) 4646 class zip_view : public view_interface<zip_view<_Vs...>> 4647 { 4648 tuple<_Vs...> _M_views; 4649 4650 template<bool> class _Iterator; 4651 template<bool> class _Sentinel; 4652 4653 public: 4654 zip_view() = default; 4655 4656 constexpr explicit 4657 zip_view(_Vs... __views) 4658 : _M_views(std::move(__views)...) 4659 { } 4660 4661 constexpr auto 4662 begin() requires (!(__detail::__simple_view<_Vs> && ...)) 4663 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); } 4664 4665 constexpr auto 4666 begin() const requires (range<const _Vs> && ...) 4667 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); } 4668 4669 constexpr auto 4670 end() requires (!(__detail::__simple_view<_Vs> && ...)) 4671 { 4672 if constexpr (!__detail::__zip_is_common<_Vs...>) 4673 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views)); 4674 else if constexpr ((random_access_range<_Vs> && ...)) 4675 return begin() + iter_difference_t<_Iterator<false>>(size()); 4676 else 4677 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views)); 4678 } 4679 4680 constexpr auto 4681 end() const requires (range<const _Vs> && ...) 4682 { 4683 if constexpr (!__detail::__zip_is_common<const _Vs...>) 4684 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views)); 4685 else if constexpr ((random_access_range<const _Vs> && ...)) 4686 return begin() + iter_difference_t<_Iterator<true>>(size()); 4687 else 4688 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views)); 4689 } 4690 4691 constexpr auto 4692 size() requires (sized_range<_Vs> && ...) 4693 { 4694 return std::apply([](auto... sizes) { 4695 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>; 4696 return ranges::min({_CT(sizes)...}); 4697 }, __detail::__tuple_transform(ranges::size, _M_views)); 4698 } 4699 4700 constexpr auto 4701 size() const requires (sized_range<const _Vs> && ...) 4702 { 4703 return std::apply([](auto... sizes) { 4704 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>; 4705 return ranges::min({_CT(sizes)...}); 4706 }, __detail::__tuple_transform(ranges::size, _M_views)); 4707 } 4708 }; 4709 4710 template<typename... _Rs> 4711 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>; 4712 4713 template<typename... _Views> 4714 inline constexpr bool enable_borrowed_range<zip_view<_Views...>> 4715 = (enable_borrowed_range<_Views> && ...); 4716 4717 namespace __detail 4718 { 4719 template<bool _Const, typename... _Vs> 4720 concept __all_random_access 4721 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...); 4722 4723 template<bool _Const, typename... _Vs> 4724 concept __all_bidirectional 4725 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...); 4726 4727 template<bool _Const, typename... _Vs> 4728 concept __all_forward 4729 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...); 4730 4731 template<bool _Const, typename... _Views> 4732 struct __zip_view_iter_cat 4733 { }; 4734 4735 template<bool _Const, typename... _Views> 4736 requires __all_forward<_Const, _Views...> 4737 struct __zip_view_iter_cat<_Const, _Views...> 4738 { using iterator_category = input_iterator_tag; }; 4739 } // namespace __detail 4740 4741 template<input_range... _Vs> 4742 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) 4743 template<bool _Const> 4744 class zip_view<_Vs...>::_Iterator 4745 : public __detail::__zip_view_iter_cat<_Const, _Vs...> 4746 { 4747 #ifdef _GLIBCXX_CLANG // LLVM-61763 workaround 4748 public: 4749 #endif 4750 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current; 4751 4752 constexpr explicit 4753 _Iterator(decltype(_M_current) __current) 4754 : _M_current(std::move(__current)) 4755 { } 4756 4757 static auto 4758 _S_iter_concept() 4759 { 4760 if constexpr (__detail::__all_random_access<_Const, _Vs...>) 4761 return random_access_iterator_tag{}; 4762 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>) 4763 return bidirectional_iterator_tag{}; 4764 else if constexpr (__detail::__all_forward<_Const, _Vs...>) 4765 return forward_iterator_tag{}; 4766 else 4767 return input_iterator_tag{}; 4768 } 4769 4770 #ifndef _GLIBCXX_CLANG // LLVM-61763 workaround 4771 template<move_constructible _Fp, input_range... _Ws> 4772 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp> 4773 && regular_invocable<_Fp&, range_reference_t<_Ws>...> 4774 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>> 4775 friend class zip_transform_view; 4776 #endif 4777 4778 public: 4779 // iterator_category defined in __zip_view_iter_cat 4780 using iterator_concept = decltype(_S_iter_concept()); 4781 using value_type 4782 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>; 4783 using difference_type 4784 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>; 4785 4786 _Iterator() = default; 4787 4788 constexpr 4789 _Iterator(_Iterator<!_Const> __i) 4790 requires _Const 4791 && (convertible_to<iterator_t<_Vs>, 4792 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...) 4793 : _M_current(std::move(__i._M_current)) 4794 { } 4795 4796 constexpr auto 4797 operator*() const 4798 { 4799 auto __f = [](auto& __i) -> decltype(auto) { 4800 return *__i; 4801 }; 4802 return __detail::__tuple_transform(__f, _M_current); 4803 } 4804 4805 constexpr _Iterator& 4806 operator++() 4807 { 4808 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current); 4809 return *this; 4810 } 4811 4812 constexpr void 4813 operator++(int) 4814 { ++*this; } 4815 4816 constexpr _Iterator 4817 operator++(int) 4818 requires __detail::__all_forward<_Const, _Vs...> 4819 { 4820 auto __tmp = *this; 4821 ++*this; 4822 return __tmp; 4823 } 4824 4825 constexpr _Iterator& 4826 operator--() 4827 requires __detail::__all_bidirectional<_Const, _Vs...> 4828 { 4829 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current); 4830 return *this; 4831 } 4832 4833 constexpr _Iterator 4834 operator--(int) 4835 requires __detail::__all_bidirectional<_Const, _Vs...> 4836 { 4837 auto __tmp = *this; 4838 --*this; 4839 return __tmp; 4840 } 4841 4842 constexpr _Iterator& 4843 operator+=(difference_type __x) 4844 requires __detail::__all_random_access<_Const, _Vs...> 4845 { 4846 auto __f = [&]<typename _It>(_It& __i) { 4847 __i += iter_difference_t<_It>(__x); 4848 }; 4849 __detail::__tuple_for_each(__f, _M_current); 4850 return *this; 4851 } 4852 4853 constexpr _Iterator& 4854 operator-=(difference_type __x) 4855 requires __detail::__all_random_access<_Const, _Vs...> 4856 { 4857 auto __f = [&]<typename _It>(_It& __i) { 4858 __i -= iter_difference_t<_It>(__x); 4859 }; 4860 __detail::__tuple_for_each(__f, _M_current); 4861 return *this; 4862 } 4863 4864 constexpr auto 4865 operator[](difference_type __n) const 4866 requires __detail::__all_random_access<_Const, _Vs...> 4867 { 4868 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) { 4869 return __i[iter_difference_t<_It>(__n)]; 4870 }; 4871 return __detail::__tuple_transform(__f, _M_current); 4872 } 4873 4874 friend constexpr bool 4875 operator==(const _Iterator& __x, const _Iterator& __y) 4876 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...) 4877 { 4878 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>) 4879 return __x._M_current == __y._M_current; 4880 else 4881 return [&]<size_t... _Is>(index_sequence<_Is...>) { 4882 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...); 4883 }(make_index_sequence<sizeof...(_Vs)>{}); 4884 } 4885 4886 friend constexpr auto 4887 operator<=>(const _Iterator& __x, const _Iterator& __y) 4888 requires __detail::__all_random_access<_Const, _Vs...> 4889 { return __x._M_current <=> __y._M_current; } 4890 4891 friend constexpr _Iterator 4892 operator+(const _Iterator& __i, difference_type __n) 4893 requires __detail::__all_random_access<_Const, _Vs...> 4894 { 4895 auto __r = __i; 4896 __r += __n; 4897 return __r; 4898 } 4899 4900 friend constexpr _Iterator 4901 operator+(difference_type __n, const _Iterator& __i) 4902 requires __detail::__all_random_access<_Const, _Vs...> 4903 { 4904 auto __r = __i; 4905 __r += __n; 4906 return __r; 4907 } 4908 4909 friend constexpr _Iterator 4910 operator-(const _Iterator& __i, difference_type __n) 4911 requires __detail::__all_random_access<_Const, _Vs...> 4912 { 4913 auto __r = __i; 4914 __r -= __n; 4915 return __r; 4916 } 4917 4918 friend constexpr difference_type 4919 operator-(const _Iterator& __x, const _Iterator& __y) 4920 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>, 4921 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...) 4922 { 4923 return [&]<size_t... _Is>(index_sequence<_Is...>) { 4924 return ranges::min({difference_type(std::get<_Is>(__x._M_current) 4925 - std::get<_Is>(__y._M_current))...}, 4926 ranges::less{}, 4927 [](difference_type __i) { 4928 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i); 4929 }); 4930 }(make_index_sequence<sizeof...(_Vs)>{}); 4931 } 4932 4933 friend constexpr auto 4934 iter_move(const _Iterator& __i) 4935 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); } 4936 4937 friend constexpr void 4938 iter_swap(const _Iterator& __l, const _Iterator& __r) 4939 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...) 4940 { 4941 [&]<size_t... _Is>(index_sequence<_Is...>) { 4942 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...); 4943 }(make_index_sequence<sizeof...(_Vs)>{}); 4944 } 4945 4946 friend class zip_view; 4947 }; 4948 4949 template<input_range... _Vs> 4950 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) 4951 template<bool _Const> 4952 class zip_view<_Vs...>::_Sentinel 4953 { 4954 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end; 4955 4956 constexpr explicit 4957 _Sentinel(decltype(_M_end) __end) 4958 : _M_end(__end) 4959 { } 4960 4961 friend class zip_view; 4962 4963 public: 4964 _Sentinel() = default; 4965 4966 constexpr 4967 _Sentinel(_Sentinel<!_Const> __i) 4968 requires _Const 4969 && (convertible_to<sentinel_t<_Vs>, 4970 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...) 4971 : _M_end(std::move(__i._M_end)) 4972 { } 4973 4974 template<bool _OtherConst> 4975 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>, 4976 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...) 4977 friend constexpr bool 4978 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 4979 { 4980 return [&]<size_t... _Is>(index_sequence<_Is...>) { 4981 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...); 4982 }(make_index_sequence<sizeof...(_Vs)>{}); 4983 } 4984 4985 template<bool _OtherConst> 4986 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>, 4987 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...) 4988 friend constexpr auto 4989 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 4990 { 4991 using _Ret 4992 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>; 4993 return [&]<size_t... _Is>(index_sequence<_Is...>) { 4994 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...}, 4995 ranges::less{}, 4996 [](_Ret __i) { 4997 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i); 4998 }); 4999 }(make_index_sequence<sizeof...(_Vs)>{}); 5000 } 5001 5002 template<bool _OtherConst> 5003 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>, 5004 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...) 5005 friend constexpr auto 5006 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x) 5007 { return -(__x - __y); } 5008 }; 5009 5010 namespace views 5011 { 5012 namespace __detail 5013 { 5014 template<typename... _Ts> 5015 concept __can_zip_view 5016 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); }; 5017 } 5018 5019 struct _Zip 5020 { 5021 template<typename... _Ts> 5022 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>) 5023 constexpr auto 5024 operator() [[nodiscard]] (_Ts&&... __ts) const 5025 { 5026 if constexpr (sizeof...(_Ts) == 0) 5027 return views::empty<tuple<>>; 5028 else 5029 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...); 5030 } 5031 }; 5032 5033 inline constexpr _Zip zip; 5034 } 5035 5036 namespace __detail 5037 { 5038 template<typename _Range, bool _Const> 5039 using __range_iter_cat 5040 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category; 5041 } 5042 5043 template<move_constructible _Fp, input_range... _Vs> 5044 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp> 5045 && regular_invocable<_Fp&, range_reference_t<_Vs>...> 5046 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>> 5047 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>> 5048 { 5049 [[no_unique_address]] __detail::__box<_Fp> _M_fun; 5050 zip_view<_Vs...> _M_zip; 5051 5052 using _InnerView = zip_view<_Vs...>; 5053 5054 template<bool _Const> 5055 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>; 5056 5057 template<bool _Const> 5058 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>; 5059 5060 template<bool _Const> 5061 using _Base = __detail::__maybe_const_t<_Const, _InnerView>; 5062 5063 template<bool _Const> 5064 struct __iter_cat 5065 { }; 5066 5067 template<bool _Const> 5068 requires forward_range<_Base<_Const>> 5069 struct __iter_cat<_Const> 5070 { 5071 private: 5072 static auto 5073 _S_iter_cat() 5074 { 5075 using __detail::__maybe_const_t; 5076 using __detail::__range_iter_cat; 5077 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&, 5078 range_reference_t<__maybe_const_t<_Const, _Vs>>...>; 5079 // _GLIBCXX_RESOLVE_LIB_DEFECTS 5080 // 3798. Rvalue reference and iterator_category 5081 if constexpr (!is_reference_v<_Res>) 5082 return input_iterator_tag{}; 5083 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>, 5084 random_access_iterator_tag> && ...)) 5085 return random_access_iterator_tag{}; 5086 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>, 5087 bidirectional_iterator_tag> && ...)) 5088 return bidirectional_iterator_tag{}; 5089 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>, 5090 forward_iterator_tag> && ...)) 5091 return forward_iterator_tag{}; 5092 else 5093 return input_iterator_tag{}; 5094 } 5095 public: 5096 using iterator_category = decltype(_S_iter_cat()); 5097 }; 5098 5099 template<bool> class _Iterator; 5100 template<bool> class _Sentinel; 5101 5102 public: 5103 zip_transform_view() = default; 5104 5105 constexpr explicit 5106 zip_transform_view(_Fp __fun, _Vs... __views) 5107 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...) 5108 { } 5109 5110 constexpr auto 5111 begin() 5112 { return _Iterator<false>(*this, _M_zip.begin()); } 5113 5114 constexpr auto 5115 begin() const 5116 requires range<const _InnerView> 5117 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...> 5118 { return _Iterator<true>(*this, _M_zip.begin()); } 5119 5120 constexpr auto 5121 end() 5122 { 5123 if constexpr (common_range<_InnerView>) 5124 return _Iterator<false>(*this, _M_zip.end()); 5125 else 5126 return _Sentinel<false>(_M_zip.end()); 5127 } 5128 5129 constexpr auto 5130 end() const 5131 requires range<const _InnerView> 5132 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...> 5133 { 5134 if constexpr (common_range<const _InnerView>) 5135 return _Iterator<true>(*this, _M_zip.end()); 5136 else 5137 return _Sentinel<true>(_M_zip.end()); 5138 } 5139 5140 constexpr auto 5141 size() requires sized_range<_InnerView> 5142 { return _M_zip.size(); } 5143 5144 constexpr auto 5145 size() const requires sized_range<const _InnerView> 5146 { return _M_zip.size(); } 5147 }; 5148 5149 template<class _Fp, class... Rs> 5150 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>; 5151 5152 template<move_constructible _Fp, input_range... _Vs> 5153 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp> 5154 && regular_invocable<_Fp&, range_reference_t<_Vs>...> 5155 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>> 5156 template<bool _Const> 5157 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const> 5158 { 5159 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>; 5160 5161 _Parent* _M_parent = nullptr; 5162 __ziperator<_Const> _M_inner; 5163 5164 constexpr 5165 _Iterator(_Parent& __parent, __ziperator<_Const> __inner) 5166 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner)) 5167 { } 5168 5169 friend class zip_transform_view; 5170 5171 public: 5172 // iterator_category defined in zip_transform_view::__iter_cat 5173 using iterator_concept = typename __ziperator<_Const>::iterator_concept; 5174 using value_type 5175 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&, 5176 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>; 5177 using difference_type = range_difference_t<_Base<_Const>>; 5178 5179 _Iterator() = default; 5180 5181 constexpr 5182 _Iterator(_Iterator<!_Const> __i) 5183 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>> 5184 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner)) 5185 { } 5186 5187 constexpr decltype(auto) 5188 operator*() const 5189 { 5190 return std::apply([&](const auto&... __iters) -> decltype(auto) { 5191 return std::__invoke(*_M_parent->_M_fun, *__iters...); 5192 }, _M_inner._M_current); 5193 } 5194 5195 constexpr _Iterator& 5196 operator++() 5197 { 5198 ++_M_inner; 5199 return *this; 5200 } 5201 5202 constexpr void 5203 operator++(int) 5204 { ++*this; } 5205 5206 constexpr _Iterator 5207 operator++(int) requires forward_range<_Base<_Const>> 5208 { 5209 auto __tmp = *this; 5210 ++*this; 5211 return __tmp; 5212 } 5213 5214 constexpr _Iterator& 5215 operator--() requires bidirectional_range<_Base<_Const>> 5216 { 5217 --_M_inner; 5218 return *this; 5219 } 5220 5221 constexpr _Iterator 5222 operator--(int) requires bidirectional_range<_Base<_Const>> 5223 { 5224 auto __tmp = *this; 5225 --*this; 5226 return __tmp; 5227 } 5228 5229 constexpr _Iterator& 5230 operator+=(difference_type __x) requires random_access_range<_Base<_Const>> 5231 { 5232 _M_inner += __x; 5233 return *this; 5234 } 5235 5236 constexpr _Iterator& 5237 operator-=(difference_type __x) requires random_access_range<_Base<_Const>> 5238 { 5239 _M_inner -= __x; 5240 return *this; 5241 } 5242 5243 constexpr decltype(auto) 5244 operator[](difference_type __n) const requires random_access_range<_Base<_Const>> 5245 { 5246 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) { 5247 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...); 5248 }, _M_inner._M_current); 5249 } 5250 5251 friend constexpr bool 5252 operator==(const _Iterator& __x, const _Iterator& __y) 5253 requires equality_comparable<__ziperator<_Const>> 5254 { return __x._M_inner == __y._M_inner; } 5255 5256 friend constexpr auto 5257 operator<=>(const _Iterator& __x, const _Iterator& __y) 5258 requires random_access_range<_Base<_Const>> 5259 { return __x._M_inner <=> __y._M_inner; } 5260 5261 friend constexpr _Iterator 5262 operator+(const _Iterator& __i, difference_type __n) 5263 requires random_access_range<_Base<_Const>> 5264 { return _Iterator(*__i._M_parent, __i._M_inner + __n); } 5265 5266 friend constexpr _Iterator 5267 operator+(difference_type __n, const _Iterator& __i) 5268 requires random_access_range<_Base<_Const>> 5269 { return _Iterator(*__i._M_parent, __i._M_inner + __n); } 5270 5271 friend constexpr _Iterator 5272 operator-(const _Iterator& __i, difference_type __n) 5273 requires random_access_range<_Base<_Const>> 5274 { return _Iterator(*__i._M_parent, __i._M_inner - __n); } 5275 5276 friend constexpr difference_type 5277 operator-(const _Iterator& __x, const _Iterator& __y) 5278 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>> 5279 { return __x._M_inner - __y._M_inner; } 5280 }; 5281 5282 template<move_constructible _Fp, input_range... _Vs> 5283 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp> 5284 && regular_invocable<_Fp&, range_reference_t<_Vs>...> 5285 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>> 5286 template<bool _Const> 5287 class zip_transform_view<_Fp, _Vs...>::_Sentinel 5288 { 5289 __zentinel<_Const> _M_inner; 5290 5291 constexpr explicit 5292 _Sentinel(__zentinel<_Const> __inner) 5293 : _M_inner(__inner) 5294 { } 5295 5296 friend class zip_transform_view; 5297 5298 public: 5299 _Sentinel() = default; 5300 5301 constexpr 5302 _Sentinel(_Sentinel<!_Const> __i) 5303 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>> 5304 : _M_inner(std::move(__i._M_inner)) 5305 { } 5306 5307 template<bool _OtherConst> 5308 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>> 5309 friend constexpr bool 5310 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 5311 { return __x._M_inner == __y._M_inner; } 5312 5313 template<bool _OtherConst> 5314 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>> 5315 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>> 5316 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 5317 { return __x._M_inner - __y._M_inner; } 5318 5319 template<bool _OtherConst> 5320 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>> 5321 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>> 5322 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y) 5323 { return __x._M_inner - __y._M_inner; } 5324 }; 5325 5326 namespace views 5327 { 5328 namespace __detail 5329 { 5330 template<typename _Fp, typename... _Ts> 5331 concept __can_zip_transform_view 5332 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); }; 5333 } 5334 5335 struct _ZipTransform 5336 { 5337 template<typename _Fp> 5338 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&> 5339 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>> 5340 constexpr auto 5341 operator() [[nodiscard]] (_Fp&&) const 5342 { 5343 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>; 5344 } 5345 5346 template<typename _Fp, typename... _Ts> 5347 requires (sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...> 5348 constexpr auto 5349 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const 5350 { 5351 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...); 5352 } 5353 }; 5354 5355 inline constexpr _ZipTransform zip_transform; 5356 } 5357 5358 template<forward_range _Vp, size_t _Nm> 5359 requires view<_Vp> && (_Nm > 0) 5360 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>> 5361 { 5362 _Vp _M_base = _Vp(); 5363 5364 template<bool> class _Iterator; 5365 template<bool> class _Sentinel; 5366 5367 struct __as_sentinel 5368 { }; 5369 5370 public: 5371 adjacent_view() requires default_initializable<_Vp> = default; 5372 5373 constexpr explicit 5374 adjacent_view(_Vp __base) 5375 : _M_base(std::move(__base)) 5376 { } 5377 5378 // _GLIBCXX_RESOLVE_LIB_DEFECTS 5379 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor 5380 constexpr _Vp 5381 base() const & requires copy_constructible<_Vp> 5382 { return _M_base; } 5383 5384 constexpr _Vp 5385 base() && 5386 { return std::move(_M_base); } 5387 5388 constexpr auto 5389 begin() requires (!__detail::__simple_view<_Vp>) 5390 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); } 5391 5392 constexpr auto 5393 begin() const requires range<const _Vp> 5394 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); } 5395 5396 constexpr auto 5397 end() requires (!__detail::__simple_view<_Vp>) 5398 { 5399 if constexpr (common_range<_Vp>) 5400 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base)); 5401 else 5402 return _Sentinel<false>(ranges::end(_M_base)); 5403 } 5404 5405 constexpr auto 5406 end() const requires range<const _Vp> 5407 { 5408 if constexpr (common_range<const _Vp>) 5409 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base)); 5410 else 5411 return _Sentinel<true>(ranges::end(_M_base)); 5412 } 5413 5414 constexpr auto 5415 size() requires sized_range<_Vp> 5416 { 5417 using _ST = decltype(ranges::size(_M_base)); 5418 using _CT = common_type_t<_ST, size_t>; 5419 auto __sz = static_cast<_CT>(ranges::size(_M_base)); 5420 __sz -= std::min<_CT>(__sz, _Nm - 1); 5421 return static_cast<_ST>(__sz); 5422 } 5423 5424 constexpr auto 5425 size() const requires sized_range<const _Vp> 5426 { 5427 using _ST = decltype(ranges::size(_M_base)); 5428 using _CT = common_type_t<_ST, size_t>; 5429 auto __sz = static_cast<_CT>(ranges::size(_M_base)); 5430 __sz -= std::min<_CT>(__sz, _Nm - 1); 5431 return static_cast<_ST>(__sz); 5432 } 5433 }; 5434 5435 template<typename _Vp, size_t _Nm> 5436 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>> 5437 = enable_borrowed_range<_Vp>; 5438 5439 namespace __detail 5440 { 5441 // Yields tuple<_Tp, ..., _Tp> with _Nm elements. 5442 template<typename _Tp, size_t _Nm> 5443 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>())); 5444 5445 // For a functor F that is callable with N arguments, the expression 5446 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x). 5447 template<typename _Fp, size_t _Nm> 5448 struct __unarize 5449 { 5450 template<typename... _Ts> 5451 static invoke_result_t<_Fp, _Ts...> 5452 __tuple_apply(const tuple<_Ts...>&); // not defined 5453 5454 template<typename _Tp> 5455 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>())) 5456 operator()(_Tp&&); // not defined 5457 }; 5458 } 5459 5460 template<forward_range _Vp, size_t _Nm> 5461 requires view<_Vp> && (_Nm > 0) 5462 template<bool _Const> 5463 class adjacent_view<_Vp, _Nm>::_Iterator 5464 { 5465 #ifdef _GLIBCXX_CLANG // LLVM-61763 workaround 5466 public: 5467 #endif 5468 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 5469 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>(); 5470 5471 constexpr 5472 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last) 5473 { 5474 for (auto& __i : _M_current) 5475 { 5476 __i = __first; 5477 ranges::advance(__first, 1, __last); 5478 } 5479 } 5480 5481 constexpr 5482 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last) 5483 { 5484 if constexpr (!bidirectional_range<_Base>) 5485 for (auto& __it : _M_current) 5486 __it = __last; 5487 else 5488 for (size_t __i = 0; __i < _Nm; ++__i) 5489 { 5490 _M_current[_Nm - 1 - __i] = __last; 5491 ranges::advance(__last, -1, __first); 5492 } 5493 } 5494 5495 static auto 5496 _S_iter_concept() 5497 { 5498 if constexpr (random_access_range<_Base>) 5499 return random_access_iterator_tag{}; 5500 else if constexpr (bidirectional_range<_Base>) 5501 return bidirectional_iterator_tag{}; 5502 else 5503 return forward_iterator_tag{}; 5504 } 5505 5506 friend class adjacent_view; 5507 5508 #ifndef _GLIBCXX_CLANG // LLVM-61763 workaround 5509 template<forward_range _Wp, move_constructible _Fp, size_t _Mm> 5510 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp> 5511 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>> 5512 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>, 5513 range_reference_t<_Wp>>> 5514 friend class adjacent_transform_view; 5515 #endif 5516 5517 public: 5518 using iterator_category = input_iterator_tag; 5519 using iterator_concept = decltype(_S_iter_concept()); 5520 using value_type = conditional_t<_Nm == 2, 5521 pair<range_value_t<_Base>, range_value_t<_Base>>, 5522 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>; 5523 using difference_type = range_difference_t<_Base>; 5524 5525 _Iterator() = default; 5526 5527 constexpr 5528 _Iterator(_Iterator<!_Const> __i) 5529 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 5530 { 5531 for (size_t __j = 0; __j < _Nm; ++__j) 5532 _M_current[__j] = std::move(__i._M_current[__j]); 5533 } 5534 5535 constexpr auto 5536 operator*() const 5537 { 5538 auto __f = [](auto& __i) -> decltype(auto) { return *__i; }; 5539 return __detail::__tuple_transform(__f, _M_current); 5540 } 5541 5542 constexpr _Iterator& 5543 operator++() 5544 { 5545 for (auto& __i : _M_current) 5546 ++__i; 5547 return *this; 5548 } 5549 5550 constexpr _Iterator 5551 operator++(int) 5552 { 5553 auto __tmp = *this; 5554 ++*this; 5555 return __tmp; 5556 } 5557 5558 constexpr _Iterator& 5559 operator--() requires bidirectional_range<_Base> 5560 { 5561 for (auto& __i : _M_current) 5562 --__i; 5563 return *this; 5564 } 5565 5566 constexpr _Iterator 5567 operator--(int) requires bidirectional_range<_Base> 5568 { 5569 auto __tmp = *this; 5570 --*this; 5571 return __tmp; 5572 } 5573 5574 constexpr _Iterator& 5575 operator+=(difference_type __x) 5576 requires random_access_range<_Base> 5577 { 5578 for (auto& __i : _M_current) 5579 __i += __x; 5580 return *this; 5581 } 5582 5583 constexpr _Iterator& 5584 operator-=(difference_type __x) 5585 requires random_access_range<_Base> 5586 { 5587 for (auto& __i : _M_current) 5588 __i -= __x; 5589 return *this; 5590 } 5591 5592 constexpr auto 5593 operator[](difference_type __n) const 5594 requires random_access_range<_Base> 5595 { 5596 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; }; 5597 return __detail::__tuple_transform(__f, _M_current); 5598 } 5599 5600 friend constexpr bool 5601 operator==(const _Iterator& __x, const _Iterator& __y) 5602 { return __x._M_current.back() == __y._M_current.back(); } 5603 5604 friend constexpr bool 5605 operator<(const _Iterator& __x, const _Iterator& __y) 5606 requires random_access_range<_Base> 5607 { return __x._M_current.back() < __y._M_current.back(); } 5608 5609 friend constexpr bool 5610 operator>(const _Iterator& __x, const _Iterator& __y) 5611 requires random_access_range<_Base> 5612 { return __y < __x; } 5613 5614 friend constexpr bool 5615 operator<=(const _Iterator& __x, const _Iterator& __y) 5616 requires random_access_range<_Base> 5617 { return !(__y < __x); } 5618 5619 friend constexpr bool 5620 operator>=(const _Iterator& __x, const _Iterator& __y) 5621 requires random_access_range<_Base> 5622 { return !(__x < __y); } 5623 5624 friend constexpr auto 5625 operator<=>(const _Iterator& __x, const _Iterator& __y) 5626 requires random_access_range<_Base> 5627 && three_way_comparable<iterator_t<_Base>> 5628 { return __x._M_current.back() <=> __y._M_current.back(); } 5629 5630 friend constexpr _Iterator 5631 operator+(const _Iterator& __i, difference_type __n) 5632 requires random_access_range<_Base> 5633 { 5634 auto __r = __i; 5635 __r += __n; 5636 return __r; 5637 } 5638 5639 friend constexpr _Iterator 5640 operator+(difference_type __n, const _Iterator& __i) 5641 requires random_access_range<_Base> 5642 { 5643 auto __r = __i; 5644 __r += __n; 5645 return __r; 5646 } 5647 5648 friend constexpr _Iterator 5649 operator-(const _Iterator& __i, difference_type __n) 5650 requires random_access_range<_Base> 5651 { 5652 auto __r = __i; 5653 __r -= __n; 5654 return __r; 5655 } 5656 5657 friend constexpr difference_type 5658 operator-(const _Iterator& __x, const _Iterator& __y) 5659 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 5660 { return __x._M_current.back() - __y._M_current.back(); } 5661 5662 friend constexpr auto 5663 iter_move(const _Iterator& __i) 5664 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); } 5665 5666 friend constexpr void 5667 iter_swap(const _Iterator& __l, const _Iterator& __r) 5668 requires indirectly_swappable<iterator_t<_Base>> 5669 { 5670 for (size_t __i = 0; __i < _Nm; __i++) 5671 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]); 5672 } 5673 }; 5674 5675 template<forward_range _Vp, size_t _Nm> 5676 requires view<_Vp> && (_Nm > 0) 5677 template<bool _Const> 5678 class adjacent_view<_Vp, _Nm>::_Sentinel 5679 { 5680 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 5681 5682 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 5683 5684 constexpr explicit 5685 _Sentinel(sentinel_t<_Base> __end) 5686 : _M_end(__end) 5687 { } 5688 5689 friend class adjacent_view; 5690 5691 public: 5692 _Sentinel() = default; 5693 5694 constexpr 5695 _Sentinel(_Sentinel<!_Const> __i) 5696 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 5697 : _M_end(std::move(__i._M_end)) 5698 { } 5699 5700 template<bool _OtherConst> 5701 requires sentinel_for<sentinel_t<_Base>, 5702 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>> 5703 friend constexpr bool 5704 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 5705 { return __x._M_current.back() == __y._M_end; } 5706 5707 template<bool _OtherConst> 5708 requires sized_sentinel_for<sentinel_t<_Base>, 5709 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>> 5710 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>> 5711 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 5712 { return __x._M_current.back() - __y._M_end; } 5713 5714 template<bool _OtherConst> 5715 requires sized_sentinel_for<sentinel_t<_Base>, 5716 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>> 5717 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>> 5718 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x) 5719 { return __y._M_end - __x._M_current.back(); } 5720 }; 5721 5722 namespace views 5723 { 5724 namespace __detail 5725 { 5726 template<size_t _Nm, typename _Range> 5727 concept __can_adjacent_view 5728 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); }; 5729 } 5730 5731 template<size_t _Nm> 5732 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>> 5733 { 5734 template<viewable_range _Range> 5735 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range> 5736 constexpr auto 5737 operator() [[nodiscard]] (_Range&& __r) const 5738 { 5739 if constexpr (_Nm == 0) 5740 return views::empty<tuple<>>; 5741 else 5742 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r)); 5743 } 5744 }; 5745 5746 template<size_t _Nm> 5747 inline constexpr _Adjacent<_Nm> adjacent; 5748 5749 inline constexpr auto pairwise = adjacent<2>; 5750 } 5751 5752 template<forward_range _Vp, move_constructible _Fp, size_t _Nm> 5753 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp> 5754 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>> 5755 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>, 5756 range_reference_t<_Vp>>> 5757 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>> 5758 { 5759 [[no_unique_address]] __detail::__box<_Fp> _M_fun; 5760 adjacent_view<_Vp, _Nm> _M_inner; 5761 5762 using _InnerView = adjacent_view<_Vp, _Nm>; 5763 5764 template<bool _Const> 5765 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>; 5766 5767 template<bool _Const> 5768 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>; 5769 5770 template<bool> class _Iterator; 5771 template<bool> class _Sentinel; 5772 5773 public: 5774 adjacent_transform_view() = default; 5775 5776 constexpr explicit 5777 adjacent_transform_view(_Vp __base, _Fp __fun) 5778 : _M_fun(std::move(__fun)), _M_inner(std::move(__base)) 5779 { } 5780 5781 // _GLIBCXX_RESOLVE_LIB_DEFECTS 5782 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor 5783 // 3947. Unexpected constraints on adjacent_transform_view::base() 5784 constexpr _Vp 5785 base() const & requires copy_constructible<_Vp> 5786 { return _M_inner.base(); } 5787 5788 constexpr _Vp 5789 base() && 5790 { return std::move(_M_inner.base()); } 5791 5792 constexpr auto 5793 begin() 5794 { return _Iterator<false>(*this, _M_inner.begin()); } 5795 5796 constexpr auto 5797 begin() const 5798 requires range<const _InnerView> 5799 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>, 5800 range_reference_t<const _Vp>> 5801 { return _Iterator<true>(*this, _M_inner.begin()); } 5802 5803 constexpr auto 5804 end() 5805 { 5806 if constexpr (common_range<_InnerView>) 5807 return _Iterator<false>(*this, _M_inner.end()); 5808 else 5809 return _Sentinel<false>(_M_inner.end()); 5810 } 5811 5812 constexpr auto 5813 end() const 5814 requires range<const _InnerView> 5815 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>, 5816 range_reference_t<const _Vp>> 5817 { 5818 if constexpr (common_range<const _InnerView>) 5819 return _Iterator<true>(*this, _M_inner.end()); 5820 else 5821 return _Sentinel<true>(_M_inner.end()); 5822 } 5823 5824 constexpr auto 5825 size() requires sized_range<_InnerView> 5826 { return _M_inner.size(); } 5827 5828 constexpr auto 5829 size() const requires sized_range<const _InnerView> 5830 { return _M_inner.size(); } 5831 }; 5832 5833 template<forward_range _Vp, move_constructible _Fp, size_t _Nm> 5834 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp> 5835 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>> 5836 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>, 5837 range_reference_t<_Vp>>> 5838 template<bool _Const> 5839 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator 5840 { 5841 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>; 5842 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 5843 5844 _Parent* _M_parent = nullptr; 5845 _InnerIter<_Const> _M_inner; 5846 5847 constexpr 5848 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner) 5849 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner)) 5850 { } 5851 5852 static auto 5853 _S_iter_cat() 5854 { 5855 using __detail::__maybe_const_t; 5856 using __detail::__unarize; 5857 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>, 5858 range_reference_t<_Base>>; 5859 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category; 5860 // _GLIBCXX_RESOLVE_LIB_DEFECTS 5861 // 3798. Rvalue reference and iterator_category 5862 if constexpr (!is_reference_v<_Res>) 5863 return input_iterator_tag{}; 5864 else if constexpr (derived_from<_Cat, random_access_iterator_tag>) 5865 return random_access_iterator_tag{}; 5866 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>) 5867 return bidirectional_iterator_tag{}; 5868 else if constexpr (derived_from<_Cat, forward_iterator_tag>) 5869 return forward_iterator_tag{}; 5870 else 5871 return input_iterator_tag{}; 5872 } 5873 5874 friend class adjacent_transform_view; 5875 5876 public: 5877 using iterator_category = decltype(_S_iter_cat()); 5878 using iterator_concept = typename _InnerIter<_Const>::iterator_concept; 5879 using value_type 5880 = remove_cvref_t<invoke_result_t 5881 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>, 5882 range_reference_t<_Base>>>; 5883 using difference_type = range_difference_t<_Base>; 5884 5885 _Iterator() = default; 5886 5887 constexpr 5888 _Iterator(_Iterator<!_Const> __i) 5889 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>> 5890 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner)) 5891 { } 5892 5893 constexpr decltype(auto) 5894 operator*() const 5895 { 5896 return std::apply([&](const auto&... __iters) -> decltype(auto) { 5897 return std::__invoke(*_M_parent->_M_fun, *__iters...); 5898 }, _M_inner._M_current); 5899 } 5900 5901 constexpr _Iterator& 5902 operator++() 5903 { 5904 ++_M_inner; 5905 return *this; 5906 } 5907 5908 constexpr _Iterator 5909 operator++(int) 5910 { 5911 auto __tmp = *this; 5912 ++*this; 5913 return __tmp; 5914 } 5915 5916 constexpr _Iterator& 5917 operator--() requires bidirectional_range<_Base> 5918 { 5919 --_M_inner; 5920 return *this; 5921 } 5922 5923 constexpr _Iterator 5924 operator--(int) requires bidirectional_range<_Base> 5925 { 5926 auto __tmp = *this; 5927 --*this; 5928 return __tmp; 5929 } 5930 5931 constexpr _Iterator& 5932 operator+=(difference_type __x) requires random_access_range<_Base> 5933 { 5934 _M_inner += __x; 5935 return *this; 5936 } 5937 5938 constexpr _Iterator& 5939 operator-=(difference_type __x) requires random_access_range<_Base> 5940 { 5941 _M_inner -= __x; 5942 return *this; 5943 } 5944 5945 constexpr decltype(auto) 5946 operator[](difference_type __n) const requires random_access_range<_Base> 5947 { 5948 return std::apply([&](const auto&... __iters) -> decltype(auto) { 5949 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...); 5950 }, _M_inner._M_current); 5951 } 5952 5953 friend constexpr bool 5954 operator==(const _Iterator& __x, const _Iterator& __y) 5955 { return __x._M_inner == __y._M_inner; } 5956 5957 friend constexpr bool 5958 operator<(const _Iterator& __x, const _Iterator& __y) 5959 requires random_access_range<_Base> 5960 { return __x._M_inner < __y._M_inner; } 5961 5962 friend constexpr bool 5963 operator>(const _Iterator& __x, const _Iterator& __y) 5964 requires random_access_range<_Base> 5965 { return __x._M_inner > __y._M_inner; } 5966 5967 friend constexpr bool 5968 operator<=(const _Iterator& __x, const _Iterator& __y) 5969 requires random_access_range<_Base> 5970 { return __x._M_inner <= __y._M_inner; } 5971 5972 friend constexpr bool 5973 operator>=(const _Iterator& __x, const _Iterator& __y) 5974 requires random_access_range<_Base> 5975 { return __x._M_inner >= __y._M_inner; } 5976 5977 friend constexpr auto 5978 operator<=>(const _Iterator& __x, const _Iterator& __y) 5979 requires random_access_range<_Base> && 5980 three_way_comparable<_InnerIter<_Const>> 5981 { return __x._M_inner <=> __y._M_inner; } 5982 5983 friend constexpr _Iterator 5984 operator+(const _Iterator& __i, difference_type __n) 5985 requires random_access_range<_Base> 5986 { return _Iterator(*__i._M_parent, __i._M_inner + __n); } 5987 5988 friend constexpr _Iterator 5989 operator+(difference_type __n, const _Iterator& __i) 5990 requires random_access_range<_Base> 5991 { return _Iterator(*__i._M_parent, __i._M_inner + __n); } 5992 5993 friend constexpr _Iterator 5994 operator-(const _Iterator& __i, difference_type __n) 5995 requires random_access_range<_Base> 5996 { return _Iterator(*__i._M_parent, __i._M_inner - __n); } 5997 5998 friend constexpr difference_type 5999 operator-(const _Iterator& __x, const _Iterator& __y) 6000 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>> 6001 { return __x._M_inner - __y._M_inner; } 6002 }; 6003 6004 template<forward_range _Vp, move_constructible _Fp, size_t _Nm> 6005 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp> 6006 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>> 6007 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>, 6008 range_reference_t<_Vp>>> 6009 template<bool _Const> 6010 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel 6011 { 6012 _InnerSent<_Const> _M_inner; 6013 6014 constexpr explicit 6015 _Sentinel(_InnerSent<_Const> __inner) 6016 : _M_inner(__inner) 6017 { } 6018 6019 friend class adjacent_transform_view; 6020 6021 public: 6022 _Sentinel() = default; 6023 6024 constexpr 6025 _Sentinel(_Sentinel<!_Const> __i) 6026 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>> 6027 : _M_inner(std::move(__i._M_inner)) 6028 { } 6029 6030 template<bool _OtherConst> 6031 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>> 6032 friend constexpr bool 6033 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 6034 { return __x._M_inner == __y._M_inner; } 6035 6036 template<bool _OtherConst> 6037 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>> 6038 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>> 6039 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 6040 { return __x._M_inner - __y._M_inner; } 6041 6042 template<bool _OtherConst> 6043 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>> 6044 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>> 6045 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y) 6046 { return __x._M_inner - __y._M_inner; } 6047 }; 6048 6049 namespace views 6050 { 6051 namespace __detail 6052 { 6053 template<size_t _Nm, typename _Range, typename _Fp> 6054 concept __can_adjacent_transform_view 6055 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm> 6056 (std::declval<_Range>(), std::declval<_Fp>()); }; 6057 } 6058 6059 template<size_t _Nm> 6060 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>> 6061 { 6062 template<viewable_range _Range, typename _Fp> 6063 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp> 6064 constexpr auto 6065 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const 6066 { 6067 if constexpr (_Nm == 0) 6068 return zip_transform(std::forward<_Fp>(__f)); 6069 else 6070 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm> 6071 (std::forward<_Range>(__r), std::forward<_Fp>(__f)); 6072 } 6073 6074 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator(); 6075 static constexpr int _S_arity = 2; 6076 static constexpr bool _S_has_simple_extra_args = true; 6077 }; 6078 6079 template<size_t _Nm> 6080 inline constexpr _AdjacentTransform<_Nm> adjacent_transform; 6081 6082 inline constexpr auto pairwise_transform = adjacent_transform<2>; 6083 } 6084 #endif // __cpp_lib_ranges_zip 6085 6086 #ifdef __cpp_lib_ranges_chunk // C++ >= 23 6087 namespace __detail 6088 { 6089 template<typename _Tp> 6090 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom) 6091 { 6092 _Tp __r = __num / __denom; 6093 if (__num % __denom) 6094 ++__r; 6095 return __r; 6096 } 6097 } 6098 6099 template<view _Vp> 6100 requires input_range<_Vp> 6101 class chunk_view : public view_interface<chunk_view<_Vp>> 6102 { 6103 _Vp _M_base; 6104 range_difference_t<_Vp> _M_n; 6105 range_difference_t<_Vp> _M_remainder = 0; 6106 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current; 6107 6108 class _OuterIter; 6109 class _InnerIter; 6110 6111 public: 6112 constexpr explicit 6113 chunk_view(_Vp __base, range_difference_t<_Vp> __n) 6114 : _M_base(std::move(__base)), _M_n(__n) 6115 { __glibcxx_assert(__n >= 0); } 6116 6117 constexpr _Vp 6118 base() const & requires copy_constructible<_Vp> 6119 { return _M_base; } 6120 6121 constexpr _Vp 6122 base() && 6123 { return std::move(_M_base); } 6124 6125 constexpr _OuterIter 6126 begin() 6127 { 6128 _M_current = ranges::begin(_M_base); 6129 _M_remainder = _M_n; 6130 return _OuterIter(*this); 6131 } 6132 6133 constexpr default_sentinel_t 6134 end() const noexcept 6135 { return default_sentinel; } 6136 6137 constexpr auto 6138 size() requires sized_range<_Vp> 6139 { 6140 return __detail::__to_unsigned_like(__detail::__div_ceil 6141 (ranges::distance(_M_base), _M_n)); 6142 } 6143 6144 constexpr auto 6145 size() const requires sized_range<const _Vp> 6146 { 6147 return __detail::__to_unsigned_like(__detail::__div_ceil 6148 (ranges::distance(_M_base), _M_n)); 6149 } 6150 }; 6151 6152 template<typename _Range> 6153 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>; 6154 6155 template<view _Vp> 6156 requires input_range<_Vp> 6157 class chunk_view<_Vp>::_OuterIter 6158 { 6159 chunk_view* _M_parent; 6160 6161 constexpr explicit 6162 _OuterIter(chunk_view& __parent) noexcept 6163 : _M_parent(std::__addressof(__parent)) 6164 { } 6165 6166 friend chunk_view; 6167 6168 public: 6169 using iterator_concept = input_iterator_tag; 6170 using difference_type = range_difference_t<_Vp>; 6171 6172 struct value_type; 6173 6174 _OuterIter(_OuterIter&&) = default; 6175 _OuterIter& operator=(_OuterIter&&) = default; 6176 6177 constexpr value_type 6178 operator*() const 6179 { 6180 __glibcxx_assert(*this != default_sentinel); 6181 return value_type(*_M_parent); 6182 } 6183 6184 constexpr _OuterIter& 6185 operator++() 6186 { 6187 __glibcxx_assert(*this != default_sentinel); 6188 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder, 6189 ranges::end(_M_parent->_M_base)); 6190 _M_parent->_M_remainder = _M_parent->_M_n; 6191 return *this; 6192 } 6193 6194 constexpr void 6195 operator++(int) 6196 { ++*this; } 6197 6198 friend constexpr bool 6199 operator==(const _OuterIter& __x, default_sentinel_t) 6200 { 6201 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base) 6202 && __x._M_parent->_M_remainder != 0; 6203 } 6204 6205 friend constexpr difference_type 6206 operator-(default_sentinel_t, const _OuterIter& __x) 6207 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 6208 { 6209 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current; 6210 6211 if (__dist < __x._M_parent->_M_remainder) 6212 return __dist == 0 ? 0 : 1; 6213 6214 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder, 6215 __x._M_parent->_M_n); 6216 } 6217 6218 friend constexpr difference_type 6219 operator-(const _OuterIter& __x, default_sentinel_t __y) 6220 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 6221 { return -(__y - __x); } 6222 }; 6223 6224 template<view _Vp> 6225 requires input_range<_Vp> 6226 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type> 6227 { 6228 private: 6229 chunk_view* _M_parent; 6230 6231 constexpr explicit 6232 value_type(chunk_view& __parent) noexcept 6233 : _M_parent(std::__addressof(__parent)) 6234 { } 6235 6236 friend _OuterIter; 6237 6238 public: 6239 constexpr _InnerIter 6240 begin() const noexcept 6241 { return _InnerIter(*_M_parent); } 6242 6243 constexpr default_sentinel_t 6244 end() const noexcept 6245 { return default_sentinel; } 6246 6247 constexpr auto 6248 size() const 6249 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 6250 { 6251 return __detail::__to_unsigned_like 6252 (ranges::min(_M_parent->_M_remainder, 6253 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current)); 6254 } 6255 }; 6256 6257 template<view _Vp> 6258 requires input_range<_Vp> 6259 class chunk_view<_Vp>::_InnerIter 6260 { 6261 chunk_view* _M_parent; 6262 6263 constexpr explicit 6264 _InnerIter(chunk_view& __parent) noexcept 6265 : _M_parent(std::__addressof(__parent)) 6266 { } 6267 6268 friend _OuterIter::value_type; 6269 6270 public: 6271 using iterator_concept = input_iterator_tag; 6272 using difference_type = range_difference_t<_Vp>; 6273 using value_type = range_value_t<_Vp>; 6274 6275 _InnerIter(_InnerIter&&) = default; 6276 _InnerIter& operator=(_InnerIter&&) = default; 6277 6278 constexpr const iterator_t<_Vp>& 6279 base() const & 6280 { return *_M_parent->_M_current; } 6281 6282 constexpr range_reference_t<_Vp> 6283 operator*() const 6284 { 6285 __glibcxx_assert(*this != default_sentinel); 6286 return **_M_parent->_M_current; 6287 } 6288 6289 constexpr _InnerIter& 6290 operator++() 6291 { 6292 __glibcxx_assert(*this != default_sentinel); 6293 ++*_M_parent->_M_current; 6294 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base)) 6295 _M_parent->_M_remainder = 0; 6296 else 6297 --_M_parent->_M_remainder; 6298 return *this; 6299 } 6300 6301 constexpr void 6302 operator++(int) 6303 { ++*this; } 6304 6305 friend constexpr bool 6306 operator==(const _InnerIter& __x, default_sentinel_t) noexcept 6307 { return __x._M_parent->_M_remainder == 0; } 6308 6309 friend constexpr difference_type 6310 operator-(default_sentinel_t, const _InnerIter& __x) 6311 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 6312 { 6313 return ranges::min(__x._M_parent->_M_remainder, 6314 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current); 6315 } 6316 6317 friend constexpr difference_type 6318 operator-(const _InnerIter& __x, default_sentinel_t __y) 6319 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 6320 { return -(__y - __x); } 6321 6322 // _GLIBCXX_RESOLVE_LIB_DEFECTS 6323 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap 6324 friend constexpr range_rvalue_reference_t<_Vp> 6325 iter_move(const _InnerIter& __i) 6326 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current))) 6327 { return ranges::iter_move(*__i._M_parent->_M_current); } 6328 6329 friend constexpr void 6330 iter_swap(const _InnerIter& __x, const _InnerIter& __y) 6331 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current, 6332 *__x._M_parent->_M_current))) 6333 requires indirectly_swappable<iterator_t<_Vp>> 6334 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); } 6335 }; 6336 6337 template<view _Vp> 6338 requires forward_range<_Vp> 6339 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>> 6340 { 6341 _Vp _M_base; 6342 range_difference_t<_Vp> _M_n; 6343 template<bool> class _Iterator; 6344 6345 public: 6346 constexpr explicit 6347 chunk_view(_Vp __base, range_difference_t<_Vp> __n) 6348 : _M_base(std::move(__base)), _M_n(__n) 6349 { __glibcxx_assert(__n > 0); } 6350 6351 constexpr _Vp 6352 base() const & requires copy_constructible<_Vp> 6353 { return _M_base; } 6354 6355 constexpr _Vp 6356 base() && 6357 { return std::move(_M_base); } 6358 6359 constexpr auto 6360 begin() requires (!__detail::__simple_view<_Vp>) 6361 { return _Iterator<false>(this, ranges::begin(_M_base)); } 6362 6363 constexpr auto 6364 begin() const requires forward_range<const _Vp> 6365 { return _Iterator<true>(this, ranges::begin(_M_base)); } 6366 6367 constexpr auto 6368 end() requires (!__detail::__simple_view<_Vp>) 6369 { 6370 if constexpr (common_range<_Vp> && sized_range<_Vp>) 6371 { 6372 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n; 6373 return _Iterator<false>(this, ranges::end(_M_base), __missing); 6374 } 6375 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>) 6376 return _Iterator<false>(this, ranges::end(_M_base)); 6377 else 6378 return default_sentinel; 6379 } 6380 6381 constexpr auto 6382 end() const requires forward_range<const _Vp> 6383 { 6384 if constexpr (common_range<const _Vp> && sized_range<const _Vp>) 6385 { 6386 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n; 6387 return _Iterator<true>(this, ranges::end(_M_base), __missing); 6388 } 6389 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>) 6390 return _Iterator<true>(this, ranges::end(_M_base)); 6391 else 6392 return default_sentinel; 6393 } 6394 6395 constexpr auto 6396 size() requires sized_range<_Vp> 6397 { 6398 return __detail::__to_unsigned_like(__detail::__div_ceil 6399 (ranges::distance(_M_base), _M_n)); 6400 } 6401 6402 constexpr auto 6403 size() const requires sized_range<const _Vp> 6404 { 6405 return __detail::__to_unsigned_like(__detail::__div_ceil 6406 (ranges::distance(_M_base), _M_n)); 6407 } 6408 }; 6409 6410 template<typename _Vp> 6411 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>> 6412 = forward_range<_Vp> && enable_borrowed_range<_Vp>; 6413 6414 template<view _Vp> 6415 requires forward_range<_Vp> 6416 template<bool _Const> 6417 class chunk_view<_Vp>::_Iterator 6418 { 6419 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>; 6420 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 6421 6422 iterator_t<_Base> _M_current = iterator_t<_Base>(); 6423 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 6424 range_difference_t<_Base> _M_n = 0; 6425 range_difference_t<_Base> _M_missing = 0; 6426 6427 constexpr 6428 _Iterator(_Parent* __parent, iterator_t<_Base> __current, 6429 range_difference_t<_Base> __missing = 0) 6430 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)), 6431 _M_n(__parent->_M_n), _M_missing(__missing) 6432 { } 6433 6434 static auto 6435 _S_iter_cat() 6436 { 6437 if constexpr (random_access_range<_Base>) 6438 return random_access_iterator_tag{}; 6439 else if constexpr (bidirectional_range<_Base>) 6440 return bidirectional_iterator_tag{}; 6441 else 6442 return forward_iterator_tag{}; 6443 } 6444 6445 friend chunk_view; 6446 6447 public: 6448 using iterator_category = input_iterator_tag; 6449 using iterator_concept = decltype(_S_iter_cat()); 6450 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n)); 6451 using difference_type = range_difference_t<_Base>; 6452 6453 _Iterator() = default; 6454 6455 constexpr _Iterator(_Iterator<!_Const> __i) 6456 requires _Const 6457 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 6458 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 6459 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)), 6460 _M_n(__i._M_n), _M_missing(__i._M_missing) 6461 { } 6462 6463 constexpr iterator_t<_Base> 6464 base() const 6465 { return _M_current; } 6466 6467 constexpr value_type 6468 operator*() const 6469 { 6470 __glibcxx_assert(_M_current != _M_end); 6471 return views::take(subrange(_M_current, _M_end), _M_n); 6472 } 6473 6474 constexpr _Iterator& 6475 operator++() 6476 { 6477 __glibcxx_assert(_M_current != _M_end); 6478 _M_missing = ranges::advance(_M_current, _M_n, _M_end); 6479 return *this; 6480 } 6481 6482 constexpr _Iterator 6483 operator++(int) 6484 { 6485 auto __tmp = *this; 6486 ++*this; 6487 return __tmp; 6488 } 6489 6490 constexpr _Iterator& 6491 operator--() requires bidirectional_range<_Base> 6492 { 6493 ranges::advance(_M_current, _M_missing - _M_n); 6494 _M_missing = 0; 6495 return *this; 6496 } 6497 6498 constexpr _Iterator 6499 operator--(int) requires bidirectional_range<_Base> 6500 { 6501 auto __tmp = *this; 6502 --*this; 6503 return __tmp; 6504 } 6505 6506 constexpr _Iterator& 6507 operator+=(difference_type __x) 6508 requires random_access_range<_Base> 6509 { 6510 if (__x > 0) 6511 { 6512 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1)); 6513 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end); 6514 } 6515 else if (__x < 0) 6516 { 6517 ranges::advance(_M_current, _M_n * __x + _M_missing); 6518 _M_missing = 0; 6519 } 6520 return *this; 6521 } 6522 6523 constexpr _Iterator& 6524 operator-=(difference_type __x) 6525 requires random_access_range<_Base> 6526 { return *this += -__x; } 6527 6528 constexpr value_type 6529 operator[](difference_type __n) const 6530 requires random_access_range<_Base> 6531 { return *(*this + __n); } 6532 6533 friend constexpr bool 6534 operator==(const _Iterator& __x, const _Iterator& __y) 6535 { return __x._M_current == __y._M_current; } 6536 6537 friend constexpr bool 6538 operator==(const _Iterator& __x, default_sentinel_t) 6539 { return __x._M_current == __x._M_end; } 6540 6541 friend constexpr bool 6542 operator<(const _Iterator& __x, const _Iterator& __y) 6543 requires random_access_range<_Base> 6544 { return __x._M_current > __y._M_current; } 6545 6546 friend constexpr bool 6547 operator>(const _Iterator& __x, const _Iterator& __y) 6548 requires random_access_range<_Base> 6549 { return __y < __x; } 6550 6551 friend constexpr bool 6552 operator<=(const _Iterator& __x, const _Iterator& __y) 6553 requires random_access_range<_Base> 6554 { return !(__y < __x); } 6555 6556 friend constexpr bool 6557 operator>=(const _Iterator& __x, const _Iterator& __y) 6558 requires random_access_range<_Base> 6559 { return !(__x < __y); } 6560 6561 friend constexpr auto 6562 operator<=>(const _Iterator& __x, const _Iterator& __y) 6563 requires random_access_range<_Base> 6564 && three_way_comparable<iterator_t<_Base>> 6565 { return __x._M_current <=> __y._M_current; } 6566 6567 friend constexpr _Iterator 6568 operator+(const _Iterator& __i, difference_type __n) 6569 requires random_access_range<_Base> 6570 { 6571 auto __r = __i; 6572 __r += __n; 6573 return __r; 6574 } 6575 6576 friend constexpr _Iterator 6577 operator+(difference_type __n, const _Iterator& __i) 6578 requires random_access_range<_Base> 6579 { 6580 auto __r = __i; 6581 __r += __n; 6582 return __r; 6583 } 6584 6585 friend constexpr _Iterator 6586 operator-(const _Iterator& __i, difference_type __n) 6587 requires random_access_range<_Base> 6588 { 6589 auto __r = __i; 6590 __r -= __n; 6591 return __r; 6592 } 6593 6594 friend constexpr difference_type 6595 operator-(const _Iterator& __x, const _Iterator& __y) 6596 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 6597 { 6598 return (__x._M_current - __y._M_current 6599 + __x._M_missing - __y._M_missing) / __x._M_n; 6600 } 6601 6602 friend constexpr difference_type 6603 operator-(default_sentinel_t, const _Iterator& __x) 6604 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> 6605 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); } 6606 6607 friend constexpr difference_type 6608 operator-(const _Iterator& __x, default_sentinel_t __y) 6609 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> 6610 { return -(__y - __x); } 6611 }; 6612 6613 namespace views 6614 { 6615 namespace __detail 6616 { 6617 template<typename _Range, typename _Dp> 6618 concept __can_chunk_view 6619 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); }; 6620 } 6621 6622 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk> 6623 { 6624 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>> 6625 requires __detail::__can_chunk_view<_Range, _Dp> 6626 constexpr auto 6627 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const 6628 { return chunk_view(std::forward<_Range>(__r), __n); } 6629 6630 using __adaptor::_RangeAdaptor<_Chunk>::operator(); 6631 static constexpr int _S_arity = 2; 6632 static constexpr bool _S_has_simple_extra_args = true; 6633 }; 6634 6635 inline constexpr _Chunk chunk; 6636 } 6637 #endif // __cpp_lib_ranges_chunk 6638 6639 #ifdef __cpp_lib_ranges_slide // C++ >= 23 6640 namespace __detail 6641 { 6642 template<typename _Vp> 6643 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>; 6644 6645 template<typename _Vp> 6646 concept __slide_caches_last 6647 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>; 6648 6649 template<typename _Vp> 6650 concept __slide_caches_first 6651 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>; 6652 } 6653 6654 template<forward_range _Vp> 6655 requires view<_Vp> 6656 class slide_view : public view_interface<slide_view<_Vp>> 6657 { 6658 _Vp _M_base; 6659 range_difference_t<_Vp> _M_n; 6660 [[no_unique_address]] 6661 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>, 6662 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin; 6663 [[no_unique_address]] 6664 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>, 6665 __detail::_CachedPosition<_Vp>, 1> _M_cached_end; 6666 6667 template<bool> class _Iterator; 6668 class _Sentinel; 6669 6670 public: 6671 constexpr explicit 6672 slide_view(_Vp __base, range_difference_t<_Vp> __n) 6673 : _M_base(std::move(__base)), _M_n(__n) 6674 { __glibcxx_assert(__n > 0); } 6675 6676 // _GLIBCXX_RESOLVE_LIB_DEFECTS 6677 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor 6678 constexpr _Vp 6679 base() const & requires copy_constructible<_Vp> 6680 { return _M_base; } 6681 6682 constexpr _Vp 6683 base() && 6684 { return std::move(_M_base); } 6685 6686 constexpr auto 6687 begin() requires (!(__detail::__simple_view<_Vp> 6688 && __detail::__slide_caches_nothing<const _Vp>)) 6689 { 6690 if constexpr (__detail::__slide_caches_first<_Vp>) 6691 { 6692 iterator_t<_Vp> __it; 6693 if (_M_cached_begin._M_has_value()) 6694 __it = _M_cached_begin._M_get(_M_base); 6695 else 6696 { 6697 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base)); 6698 _M_cached_begin._M_set(_M_base, __it); 6699 } 6700 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n); 6701 } 6702 else 6703 return _Iterator<false>(ranges::begin(_M_base), _M_n); 6704 } 6705 6706 constexpr auto 6707 begin() const requires __detail::__slide_caches_nothing<const _Vp> 6708 { return _Iterator<true>(ranges::begin(_M_base), _M_n); } 6709 6710 constexpr auto 6711 end() requires (!(__detail::__simple_view<_Vp> 6712 && __detail::__slide_caches_nothing<const _Vp>)) 6713 { 6714 if constexpr (__detail::__slide_caches_nothing<_Vp>) 6715 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()), 6716 _M_n); 6717 else if constexpr (__detail::__slide_caches_last<_Vp>) 6718 { 6719 iterator_t<_Vp> __it; 6720 if (_M_cached_end._M_has_value()) 6721 __it = _M_cached_end._M_get(_M_base); 6722 else 6723 { 6724 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base)); 6725 _M_cached_end._M_set(_M_base, __it); 6726 } 6727 return _Iterator<false>(std::move(__it), _M_n); 6728 } 6729 else if constexpr (common_range<_Vp>) 6730 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n); 6731 else 6732 return _Sentinel(ranges::end(_M_base)); 6733 } 6734 6735 constexpr auto 6736 end() const requires __detail::__slide_caches_nothing<const _Vp> 6737 { return begin() + range_difference_t<const _Vp>(size()); } 6738 6739 constexpr auto 6740 size() requires sized_range<_Vp> 6741 { 6742 auto __sz = ranges::distance(_M_base) - _M_n + 1; 6743 if (__sz < 0) 6744 __sz = 0; 6745 return __detail::__to_unsigned_like(__sz); 6746 } 6747 6748 constexpr auto 6749 size() const requires sized_range<const _Vp> 6750 { 6751 auto __sz = ranges::distance(_M_base) - _M_n + 1; 6752 if (__sz < 0) 6753 __sz = 0; 6754 return __detail::__to_unsigned_like(__sz); 6755 } 6756 }; 6757 6758 template<typename _Range> 6759 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>; 6760 6761 template<typename _Vp> 6762 inline constexpr bool enable_borrowed_range<slide_view<_Vp>> 6763 = enable_borrowed_range<_Vp>; 6764 6765 template<forward_range _Vp> 6766 requires view<_Vp> 6767 template<bool _Const> 6768 class slide_view<_Vp>::_Iterator 6769 { 6770 using _Base = __detail::__maybe_const_t<_Const, _Vp>; 6771 static constexpr bool _S_last_elt_present 6772 = __detail::__slide_caches_first<_Base>; 6773 6774 iterator_t<_Base> _M_current = iterator_t<_Base>(); 6775 [[no_unique_address]] 6776 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>> 6777 _M_last_elt = decltype(_M_last_elt)(); 6778 range_difference_t<_Base> _M_n = 0; 6779 6780 constexpr 6781 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n) 6782 requires (!_S_last_elt_present) 6783 : _M_current(__current), _M_n(__n) 6784 { } 6785 6786 constexpr 6787 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt, 6788 range_difference_t<_Base> __n) 6789 requires _S_last_elt_present 6790 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n) 6791 { } 6792 6793 static auto 6794 _S_iter_concept() 6795 { 6796 if constexpr (random_access_range<_Base>) 6797 return random_access_iterator_tag{}; 6798 else if constexpr (bidirectional_range<_Base>) 6799 return bidirectional_iterator_tag{}; 6800 else 6801 return forward_iterator_tag{}; 6802 } 6803 6804 friend slide_view; 6805 friend slide_view::_Sentinel; 6806 6807 public: 6808 using iterator_category = input_iterator_tag; 6809 using iterator_concept = decltype(_S_iter_concept()); 6810 using value_type = decltype(views::counted(_M_current, _M_n)); 6811 using difference_type = range_difference_t<_Base>; 6812 6813 _Iterator() = default; 6814 6815 constexpr 6816 _Iterator(_Iterator<!_Const> __i) 6817 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 6818 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n) 6819 { } 6820 6821 constexpr auto 6822 operator*() const 6823 { return views::counted(_M_current, _M_n); } 6824 6825 constexpr _Iterator& 6826 operator++() 6827 { 6828 ++_M_current; 6829 if constexpr (_S_last_elt_present) 6830 ++_M_last_elt; 6831 return *this; 6832 } 6833 6834 constexpr _Iterator 6835 operator++(int) 6836 { 6837 auto __tmp = *this; 6838 ++*this; 6839 return __tmp; 6840 } 6841 6842 constexpr _Iterator& 6843 operator--() requires bidirectional_range<_Base> 6844 { 6845 --_M_current; 6846 if constexpr (_S_last_elt_present) 6847 --_M_last_elt; 6848 return *this; 6849 } 6850 6851 constexpr _Iterator 6852 operator--(int) requires bidirectional_range<_Base> 6853 { 6854 auto __tmp = *this; 6855 --*this; 6856 return __tmp; 6857 } 6858 6859 constexpr _Iterator& 6860 operator+=(difference_type __x) 6861 requires random_access_range<_Base> 6862 { 6863 _M_current += __x; 6864 if constexpr (_S_last_elt_present) 6865 _M_last_elt += __x; 6866 return *this; 6867 } 6868 6869 constexpr _Iterator& 6870 operator-=(difference_type __x) 6871 requires random_access_range<_Base> 6872 { 6873 _M_current -= __x; 6874 if constexpr (_S_last_elt_present) 6875 _M_last_elt -= __x; 6876 return *this; 6877 } 6878 6879 constexpr auto 6880 operator[](difference_type __n) const 6881 requires random_access_range<_Base> 6882 { return views::counted(_M_current + __n, _M_n); } 6883 6884 friend constexpr bool 6885 operator==(const _Iterator& __x, const _Iterator& __y) 6886 { 6887 if constexpr (_S_last_elt_present) 6888 return __x._M_last_elt == __y._M_last_elt; 6889 else 6890 return __x._M_current == __y._M_current; 6891 } 6892 6893 friend constexpr bool 6894 operator<(const _Iterator& __x, const _Iterator& __y) 6895 requires random_access_range<_Base> 6896 { return __x._M_current < __y._M_current; } 6897 6898 friend constexpr bool 6899 operator>(const _Iterator& __x, const _Iterator& __y) 6900 requires random_access_range<_Base> 6901 { return __y < __x; } 6902 6903 friend constexpr bool 6904 operator<=(const _Iterator& __x, const _Iterator& __y) 6905 requires random_access_range<_Base> 6906 { return !(__y < __x); } 6907 6908 friend constexpr bool 6909 operator>=(const _Iterator& __x, const _Iterator& __y) 6910 requires random_access_range<_Base> 6911 { return !(__x < __y); } 6912 6913 friend constexpr auto 6914 operator<=>(const _Iterator& __x, const _Iterator& __y) 6915 requires random_access_range<_Base> 6916 && three_way_comparable<iterator_t<_Base>> 6917 { return __x._M_current <=> __y._M_current; } 6918 6919 friend constexpr _Iterator 6920 operator+(const _Iterator& __i, difference_type __n) 6921 requires random_access_range<_Base> 6922 { 6923 auto __r = __i; 6924 __r += __n; 6925 return __r; 6926 } 6927 6928 friend constexpr _Iterator 6929 operator+(difference_type __n, const _Iterator& __i) 6930 requires random_access_range<_Base> 6931 { 6932 auto __r = __i; 6933 __r += __n; 6934 return __r; 6935 } 6936 6937 friend constexpr _Iterator 6938 operator-(const _Iterator& __i, difference_type __n) 6939 requires random_access_range<_Base> 6940 { 6941 auto __r = __i; 6942 __r -= __n; 6943 return __r; 6944 } 6945 6946 friend constexpr difference_type 6947 operator-(const _Iterator& __x, const _Iterator& __y) 6948 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 6949 { 6950 if constexpr (_S_last_elt_present) 6951 return __x._M_last_elt - __y._M_last_elt; 6952 else 6953 return __x._M_current - __y._M_current; 6954 } 6955 }; 6956 6957 template<forward_range _Vp> 6958 requires view<_Vp> 6959 class slide_view<_Vp>::_Sentinel 6960 { 6961 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>(); 6962 6963 constexpr explicit 6964 _Sentinel(sentinel_t<_Vp> __end) 6965 : _M_end(__end) 6966 { } 6967 6968 friend slide_view; 6969 6970 public: 6971 _Sentinel() = default; 6972 6973 friend constexpr bool 6974 operator==(const _Iterator<false>& __x, const _Sentinel& __y) 6975 { return __x._M_last_elt == __y._M_end; } 6976 6977 friend constexpr range_difference_t<_Vp> 6978 operator-(const _Iterator<false>& __x, const _Sentinel& __y) 6979 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 6980 { return __x._M_last_elt - __y._M_end; } 6981 6982 friend constexpr range_difference_t<_Vp> 6983 operator-(const _Sentinel& __y, const _Iterator<false>& __x) 6984 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 6985 { return __y._M_end -__x._M_last_elt; } 6986 }; 6987 6988 namespace views 6989 { 6990 namespace __detail 6991 { 6992 template<typename _Range, typename _Dp> 6993 concept __can_slide_view 6994 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); }; 6995 } 6996 6997 struct _Slide : __adaptor::_RangeAdaptor<_Slide> 6998 { 6999 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>> 7000 requires __detail::__can_slide_view<_Range, _Dp> 7001 constexpr auto 7002 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const 7003 { return slide_view(std::forward<_Range>(__r), __n); } 7004 7005 using __adaptor::_RangeAdaptor<_Slide>::operator(); 7006 static constexpr int _S_arity = 2; 7007 static constexpr bool _S_has_simple_extra_args = true; 7008 }; 7009 7010 inline constexpr _Slide slide; 7011 } 7012 #endif // __cpp_lib_ranges_slide 7013 7014 #ifdef __cpp_lib_ranges_chunk_by // C++ >= 23 7015 template<forward_range _Vp, 7016 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred> 7017 requires view<_Vp> && is_object_v<_Pred> 7018 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>> 7019 { 7020 _Vp _M_base = _Vp(); 7021 __detail::__box<_Pred> _M_pred; 7022 __detail::_CachedPosition<_Vp> _M_cached_begin; 7023 7024 constexpr iterator_t<_Vp> 7025 _M_find_next(iterator_t<_Vp> __current) 7026 { 7027 __glibcxx_assert(_M_pred.has_value()); 7028 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) { 7029 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y))); 7030 }; 7031 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred); 7032 return ranges::next(__it, 1, ranges::end(_M_base)); 7033 } 7034 7035 constexpr iterator_t<_Vp> 7036 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp> 7037 { 7038 __glibcxx_assert(_M_pred.has_value()); 7039 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) { 7040 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x))); 7041 }; 7042 auto __rbegin = std::make_reverse_iterator(__current); 7043 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base)); 7044 __glibcxx_assert(__rbegin != __rend); 7045 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base(); 7046 return ranges::prev(__it, 1, ranges::begin(_M_base)); 7047 } 7048 7049 class _Iterator; 7050 7051 public: 7052 chunk_by_view() requires (default_initializable<_Vp> 7053 && default_initializable<_Pred>) 7054 = default; 7055 7056 constexpr explicit 7057 chunk_by_view(_Vp __base, _Pred __pred) 7058 : _M_base(std::move(__base)), _M_pred(std::move(__pred)) 7059 { } 7060 7061 constexpr _Vp 7062 base() const & requires copy_constructible<_Vp> 7063 { return _M_base; } 7064 7065 constexpr _Vp 7066 base() && 7067 { return std::move(_M_base); } 7068 7069 constexpr const _Pred& 7070 pred() const 7071 { return *_M_pred; } 7072 7073 constexpr _Iterator 7074 begin() 7075 { 7076 __glibcxx_assert(_M_pred.has_value()); 7077 iterator_t<_Vp> __it; 7078 if (_M_cached_begin._M_has_value()) 7079 __it = _M_cached_begin._M_get(_M_base); 7080 else 7081 { 7082 __it = _M_find_next(ranges::begin(_M_base)); 7083 _M_cached_begin._M_set(_M_base, __it); 7084 } 7085 return _Iterator(*this, ranges::begin(_M_base), __it); 7086 } 7087 7088 constexpr auto 7089 end() 7090 { 7091 if constexpr (common_range<_Vp>) 7092 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base)); 7093 else 7094 return default_sentinel; 7095 } 7096 }; 7097 7098 template<typename _Range, typename _Pred> 7099 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>; 7100 7101 template<forward_range _Vp, 7102 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred> 7103 requires view<_Vp> && is_object_v<_Pred> 7104 class chunk_by_view<_Vp, _Pred>::_Iterator 7105 { 7106 chunk_by_view* _M_parent = nullptr; 7107 iterator_t<_Vp> _M_current = iterator_t<_Vp>(); 7108 iterator_t<_Vp> _M_next = iterator_t<_Vp>(); 7109 7110 constexpr 7111 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next) 7112 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next) 7113 { } 7114 7115 static auto 7116 _S_iter_concept() 7117 { 7118 if constexpr (bidirectional_range<_Vp>) 7119 return bidirectional_iterator_tag{}; 7120 else 7121 return forward_iterator_tag{}; 7122 } 7123 7124 friend chunk_by_view; 7125 7126 public: 7127 using value_type = subrange<iterator_t<_Vp>>; 7128 using difference_type = range_difference_t<_Vp>; 7129 using iterator_category = input_iterator_tag; 7130 using iterator_concept = decltype(_S_iter_concept()); 7131 7132 _Iterator() = default; 7133 7134 constexpr value_type 7135 operator*() const 7136 { 7137 __glibcxx_assert(_M_current != _M_next); 7138 return ranges::subrange(_M_current, _M_next); 7139 } 7140 7141 constexpr _Iterator& 7142 operator++() 7143 { 7144 __glibcxx_assert(_M_current != _M_next); 7145 _M_current = _M_next; 7146 _M_next = _M_parent->_M_find_next(_M_current); 7147 return *this; 7148 } 7149 7150 constexpr _Iterator 7151 operator++(int) 7152 { 7153 auto __tmp = *this; 7154 ++*this; 7155 return __tmp; 7156 } 7157 7158 constexpr _Iterator& 7159 operator--() requires bidirectional_range<_Vp> 7160 { 7161 _M_next = _M_current; 7162 _M_current = _M_parent->_M_find_prev(_M_next); 7163 return *this; 7164 } 7165 7166 constexpr _Iterator 7167 operator--(int) requires bidirectional_range<_Vp> 7168 { 7169 auto __tmp = *this; 7170 --*this; 7171 return __tmp; 7172 } 7173 7174 friend constexpr bool 7175 operator==(const _Iterator& __x, const _Iterator& __y) 7176 { return __x._M_current == __y._M_current; } 7177 7178 friend constexpr bool 7179 operator==(const _Iterator& __x, default_sentinel_t) 7180 { return __x._M_current == __x._M_next; } 7181 }; 7182 7183 namespace views 7184 { 7185 namespace __detail 7186 { 7187 template<typename _Range, typename _Pred> 7188 concept __can_chunk_by_view 7189 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); }; 7190 } 7191 7192 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy> 7193 { 7194 template<viewable_range _Range, typename _Pred> 7195 requires __detail::__can_chunk_by_view<_Range, _Pred> 7196 constexpr auto 7197 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const 7198 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); } 7199 7200 using __adaptor::_RangeAdaptor<_ChunkBy>::operator(); 7201 static constexpr int _S_arity = 2; 7202 static constexpr bool _S_has_simple_extra_args = true; 7203 }; 7204 7205 inline constexpr _ChunkBy chunk_by; 7206 } 7207 #endif // __cpp_lib_ranges_chunk_by 7208 7209 #ifdef __cpp_lib_ranges_join_with // C++ >= 23 7210 namespace __detail 7211 { 7212 template<typename _Range, typename _Pattern> 7213 concept __compatible_joinable_ranges 7214 = common_with<range_value_t<_Range>, range_value_t<_Pattern>> 7215 && common_reference_with<range_reference_t<_Range>, 7216 range_reference_t<_Pattern>> 7217 && common_reference_with<range_rvalue_reference_t<_Range>, 7218 range_rvalue_reference_t<_Pattern>>; 7219 7220 template<typename _Range> 7221 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>; 7222 } 7223 7224 template<input_range _Vp, forward_range _Pattern> 7225 requires view<_Vp> && view<_Pattern> 7226 && input_range<range_reference_t<_Vp>> 7227 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern> 7228 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>> 7229 { 7230 using _InnerRange = range_reference_t<_Vp>; 7231 7232 _Vp _M_base = _Vp(); 7233 [[no_unique_address]] 7234 __detail::__maybe_present_t<!forward_range<_Vp>, 7235 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it; 7236 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner; 7237 _Pattern _M_pattern = _Pattern(); 7238 7239 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>; 7240 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>; 7241 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>; 7242 7243 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>; 7244 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>; 7245 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>; 7246 7247 template<bool _Const> 7248 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>; 7249 7250 template<bool _Const> 7251 struct __iter_cat 7252 { }; 7253 7254 template<bool _Const> 7255 requires _S_ref_is_glvalue<_Const> 7256 && forward_range<_Base<_Const>> 7257 && forward_range<_InnerBase<_Const>> 7258 struct __iter_cat<_Const> 7259 { 7260 private: 7261 static auto 7262 _S_iter_cat() 7263 { 7264 using _OuterIter = join_with_view::_OuterIter<_Const>; 7265 using _InnerIter = join_with_view::_InnerIter<_Const>; 7266 using _PatternIter = join_with_view::_PatternIter<_Const>; 7267 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category; 7268 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category; 7269 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category; 7270 // _GLIBCXX_RESOLVE_LIB_DEFECTS 7271 // 3798. Rvalue reference and iterator_category 7272 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>, 7273 iter_reference_t<_PatternIter>>>) 7274 return input_iterator_tag{}; 7275 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag> 7276 && derived_from<_InnerCat, bidirectional_iterator_tag> 7277 && derived_from<_PatternCat, bidirectional_iterator_tag> 7278 && common_range<_InnerBase<_Const>> 7279 && common_range<_PatternBase<_Const>>) 7280 return bidirectional_iterator_tag{}; 7281 else if constexpr (derived_from<_OuterCat, forward_iterator_tag> 7282 && derived_from<_InnerCat, forward_iterator_tag> 7283 && derived_from<_PatternCat, forward_iterator_tag>) 7284 return forward_iterator_tag{}; 7285 else 7286 return input_iterator_tag{}; 7287 } 7288 public: 7289 using iterator_category = decltype(_S_iter_cat()); 7290 }; 7291 7292 template<bool> class _Iterator; 7293 template<bool> class _Sentinel; 7294 7295 public: 7296 join_with_view() requires (default_initializable<_Vp> 7297 && default_initializable<_Pattern>) 7298 = default; 7299 7300 constexpr 7301 join_with_view(_Vp __base, _Pattern __pattern) 7302 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern)) 7303 { } 7304 7305 template<input_range _Range> 7306 requires constructible_from<_Vp, views::all_t<_Range>> 7307 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>> 7308 constexpr 7309 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e) 7310 : _M_base(views::all(std::forward<_Range>(__r))), 7311 _M_pattern(views::single(std::move(__e))) 7312 { } 7313 7314 constexpr _Vp 7315 base() const& requires copy_constructible<_Vp> 7316 { return _M_base; } 7317 7318 constexpr _Vp 7319 base() && 7320 { return std::move(_M_base); } 7321 7322 constexpr auto 7323 begin() 7324 { 7325 if constexpr (forward_range<_Vp>) 7326 { 7327 constexpr bool __use_const = is_reference_v<_InnerRange> 7328 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>; 7329 return _Iterator<__use_const>{*this, ranges::begin(_M_base)}; 7330 } 7331 else 7332 { 7333 _M_outer_it = ranges::begin(_M_base); 7334 return _Iterator<false>{*this}; 7335 } 7336 } 7337 7338 constexpr auto 7339 begin() const 7340 requires forward_range<const _Vp> 7341 && forward_range<const _Pattern> 7342 && is_reference_v<range_reference_t<const _Vp>> 7343 && input_range<range_reference_t<const _Vp>> 7344 { return _Iterator<true>{*this, ranges::begin(_M_base)}; } 7345 7346 constexpr auto 7347 end() 7348 { 7349 constexpr bool __use_const 7350 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>; 7351 if constexpr (is_reference_v<_InnerRange> 7352 && forward_range<_Vp> && common_range<_Vp> 7353 && forward_range<_InnerRange> && common_range<_InnerRange>) 7354 return _Iterator<__use_const>{*this, ranges::end(_M_base)}; 7355 else 7356 return _Sentinel<__use_const>{*this}; 7357 } 7358 7359 constexpr auto 7360 end() const 7361 requires forward_range<const _Vp> 7362 && forward_range<const _Pattern> 7363 && is_reference_v<range_reference_t<const _Vp>> 7364 && input_range<range_reference_t<const _Vp>> 7365 { 7366 using _InnerConstRange = range_reference_t<const _Vp>; 7367 if constexpr (forward_range<_InnerConstRange> 7368 && common_range<const _Vp> 7369 && common_range<_InnerConstRange>) 7370 return _Iterator<true>{*this, ranges::end(_M_base)}; 7371 else 7372 return _Sentinel<true>{*this}; 7373 } 7374 }; 7375 7376 template<typename _Range, typename _Pattern> 7377 join_with_view(_Range&&, _Pattern&&) 7378 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>; 7379 7380 template<input_range _Range> 7381 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>) 7382 -> join_with_view<views::all_t<_Range>, 7383 single_view<range_value_t<range_reference_t<_Range>>>>; 7384 7385 template<input_range _Vp, forward_range _Pattern> 7386 requires view<_Vp> && view<_Pattern> 7387 && input_range<range_reference_t<_Vp>> 7388 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern> 7389 template<bool _Const> 7390 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const> 7391 { 7392 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>; 7393 using _Base = join_with_view::_Base<_Const>; 7394 using _InnerBase = join_with_view::_InnerBase<_Const>; 7395 using _PatternBase = join_with_view::_PatternBase<_Const>; 7396 7397 using _OuterIter = join_with_view::_OuterIter<_Const>; 7398 using _InnerIter = join_with_view::_InnerIter<_Const>; 7399 using _PatternIter = join_with_view::_PatternIter<_Const>; 7400 7401 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>; 7402 7403 _Parent* _M_parent = nullptr; 7404 [[no_unique_address]] 7405 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it 7406 = decltype(_M_outer_it)(); 7407 variant<_PatternIter, _InnerIter> _M_inner_it; 7408 7409 constexpr _OuterIter& 7410 _M_get_outer() 7411 { 7412 if constexpr (forward_range<_Base>) 7413 return _M_outer_it; 7414 else 7415 return *_M_parent->_M_outer_it; 7416 } 7417 7418 constexpr const _OuterIter& 7419 _M_get_outer() const 7420 { 7421 if constexpr (forward_range<_Base>) 7422 return _M_outer_it; 7423 else 7424 return *_M_parent->_M_outer_it; 7425 } 7426 7427 constexpr 7428 _Iterator(_Parent& __parent, _OuterIter __outer) 7429 requires forward_range<_Base> 7430 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer)) 7431 { 7432 if (_M_get_outer() != ranges::end(_M_parent->_M_base)) 7433 { 7434 auto&& __inner = _M_update_inner(); 7435 _M_inner_it.template emplace<1>(ranges::begin(__inner)); 7436 _M_satisfy(); 7437 } 7438 } 7439 7440 constexpr 7441 _Iterator(_Parent& __parent) 7442 requires (!forward_range<_Base>) 7443 : _M_parent(std::__addressof(__parent)) 7444 { 7445 if (_M_get_outer() != ranges::end(_M_parent->_M_base)) 7446 { 7447 auto&& __inner = _M_update_inner(); 7448 _M_inner_it.template emplace<1>(ranges::begin(__inner)); 7449 _M_satisfy(); 7450 } 7451 } 7452 7453 constexpr auto& 7454 _M_update_inner() 7455 { 7456 _OuterIter& __outer = _M_get_outer(); 7457 if constexpr (_S_ref_is_glvalue) 7458 return __detail::__as_lvalue(*__outer); 7459 else 7460 return _M_parent->_M_inner._M_emplace_deref(__outer); 7461 } 7462 7463 constexpr auto& 7464 _M_get_inner() 7465 { 7466 if constexpr (_S_ref_is_glvalue) 7467 return __detail::__as_lvalue(*_M_get_outer()); 7468 else 7469 return *_M_parent->_M_inner; 7470 } 7471 7472 constexpr void 7473 _M_satisfy() 7474 { 7475 while (true) 7476 { 7477 if (_M_inner_it.index() == 0) 7478 { 7479 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern)) 7480 break; 7481 7482 auto&& __inner = _M_update_inner(); 7483 _M_inner_it.template emplace<1>(ranges::begin(__inner)); 7484 } 7485 else 7486 { 7487 auto&& __inner = _M_get_inner(); 7488 if (std::get<1>(_M_inner_it) != ranges::end(__inner)) 7489 break; 7490 7491 if (++_M_get_outer() == ranges::end(_M_parent->_M_base)) 7492 { 7493 if constexpr (_S_ref_is_glvalue) 7494 _M_inner_it.template emplace<0>(); 7495 break; 7496 } 7497 7498 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern)); 7499 } 7500 } 7501 } 7502 7503 static auto 7504 _S_iter_concept() 7505 { 7506 if constexpr (_S_ref_is_glvalue 7507 && bidirectional_range<_Base> 7508 && __detail::__bidirectional_common<_InnerBase> 7509 && __detail::__bidirectional_common<_PatternBase>) 7510 return bidirectional_iterator_tag{}; 7511 else if constexpr (_S_ref_is_glvalue 7512 && forward_range<_Base> 7513 && forward_range<_InnerBase>) 7514 return forward_iterator_tag{}; 7515 else 7516 return input_iterator_tag{}; 7517 } 7518 7519 friend join_with_view; 7520 7521 public: 7522 using iterator_concept = decltype(_S_iter_concept()); 7523 // iterator_category defined in join_with_view::__iter_cat 7524 using value_type = common_type_t<iter_value_t<_InnerIter>, 7525 iter_value_t<_PatternIter>>; 7526 using difference_type = common_type_t<iter_difference_t<_OuterIter>, 7527 iter_difference_t<_InnerIter>, 7528 iter_difference_t<_PatternIter>>; 7529 7530 _Iterator() = default; 7531 7532 constexpr 7533 _Iterator(_Iterator<!_Const> __i) 7534 requires _Const 7535 && convertible_to<iterator_t<_Vp>, _OuterIter> 7536 && convertible_to<iterator_t<_InnerRange>, _InnerIter> 7537 && convertible_to<iterator_t<_Pattern>, _PatternIter> 7538 : _M_parent(__i._M_parent), 7539 _M_outer_it(std::move(__i._M_outer_it)) 7540 { 7541 if (__i._M_inner_it.index() == 0) 7542 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it))); 7543 else 7544 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it))); 7545 } 7546 7547 constexpr common_reference_t<iter_reference_t<_InnerIter>, 7548 iter_reference_t<_PatternIter>> 7549 operator*() const 7550 { 7551 if (_M_inner_it.index() == 0) 7552 return *std::get<0>(_M_inner_it); 7553 else 7554 return *std::get<1>(_M_inner_it); 7555 } 7556 7557 constexpr _Iterator& 7558 operator++() 7559 { 7560 if (_M_inner_it.index() == 0) 7561 ++std::get<0>(_M_inner_it); 7562 else 7563 ++std::get<1>(_M_inner_it); 7564 _M_satisfy(); 7565 return *this; 7566 } 7567 7568 constexpr void 7569 operator++(int) 7570 { ++*this; } 7571 7572 constexpr _Iterator 7573 operator++(int) 7574 requires _S_ref_is_glvalue 7575 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter> 7576 { 7577 _Iterator __tmp = *this; 7578 ++*this; 7579 return __tmp; 7580 } 7581 7582 constexpr _Iterator& 7583 operator--() 7584 requires _S_ref_is_glvalue 7585 && bidirectional_range<_Base> 7586 && __detail::__bidirectional_common<_InnerBase> 7587 && __detail::__bidirectional_common<_PatternBase> 7588 { 7589 if (_M_outer_it == ranges::end(_M_parent->_M_base)) 7590 { 7591 auto&& __inner = *--_M_outer_it; 7592 _M_inner_it.template emplace<1>(ranges::end(__inner)); 7593 } 7594 7595 while (true) 7596 { 7597 if (_M_inner_it.index() == 0) 7598 { 7599 auto& __it = std::get<0>(_M_inner_it); 7600 if (__it == ranges::begin(_M_parent->_M_pattern)) 7601 { 7602 auto&& __inner = *--_M_outer_it; 7603 _M_inner_it.template emplace<1>(ranges::end(__inner)); 7604 } 7605 else 7606 break; 7607 } 7608 else 7609 { 7610 auto& __it = std::get<1>(_M_inner_it); 7611 auto&& __inner = *_M_outer_it; 7612 if (__it == ranges::begin(__inner)) 7613 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern)); 7614 else 7615 break; 7616 } 7617 } 7618 7619 if (_M_inner_it.index() == 0) 7620 --std::get<0>(_M_inner_it); 7621 else 7622 --std::get<1>(_M_inner_it); 7623 return *this; 7624 } 7625 7626 constexpr _Iterator 7627 operator--(int) 7628 requires _S_ref_is_glvalue && bidirectional_range<_Base> 7629 && __detail::__bidirectional_common<_InnerBase> 7630 && __detail::__bidirectional_common<_PatternBase> 7631 { 7632 _Iterator __tmp = *this; 7633 --*this; 7634 return __tmp; 7635 } 7636 7637 friend constexpr bool 7638 operator==(const _Iterator& __x, const _Iterator& __y) 7639 requires _S_ref_is_glvalue 7640 && forward_range<_Base> && equality_comparable<_InnerIter> 7641 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; } 7642 7643 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>, 7644 iter_rvalue_reference_t<_PatternIter>> 7645 iter_move(const _Iterator& __x) 7646 { 7647 if (__x._M_inner_it.index() == 0) 7648 return ranges::iter_move(std::get<0>(__x._M_inner_it)); 7649 else 7650 return ranges::iter_move(std::get<1>(__x._M_inner_it)); 7651 } 7652 7653 friend constexpr void 7654 iter_swap(const _Iterator& __x, const _Iterator& __y) 7655 requires indirectly_swappable<_InnerIter, _PatternIter> 7656 { 7657 if (__x._M_inner_it.index() == 0) 7658 { 7659 if (__y._M_inner_it.index() == 0) 7660 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it)); 7661 else 7662 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it)); 7663 } 7664 else 7665 { 7666 if (__y._M_inner_it.index() == 0) 7667 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it)); 7668 else 7669 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it)); 7670 } 7671 } 7672 }; 7673 7674 template<input_range _Vp, forward_range _Pattern> 7675 requires view<_Vp> && view<_Pattern> 7676 && input_range<range_reference_t<_Vp>> 7677 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern> 7678 template<bool _Const> 7679 class join_with_view<_Vp, _Pattern>::_Sentinel 7680 { 7681 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>; 7682 using _Base = join_with_view::_Base<_Const>; 7683 7684 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 7685 7686 constexpr explicit 7687 _Sentinel(_Parent& __parent) 7688 : _M_end(ranges::end(__parent._M_base)) 7689 { } 7690 7691 friend join_with_view; 7692 7693 public: 7694 _Sentinel() = default; 7695 7696 constexpr 7697 _Sentinel(_Sentinel<!_Const> __s) 7698 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 7699 : _M_end(std::move(__s._M_end)) 7700 { } 7701 7702 template<bool _OtherConst> 7703 requires sentinel_for<sentinel_t<_Base>, 7704 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>> 7705 friend constexpr bool 7706 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 7707 { return __x._M_get_outer() == __y._M_end; } 7708 }; 7709 7710 namespace views 7711 { 7712 namespace __detail 7713 { 7714 template<typename _Range, typename _Pattern> 7715 concept __can_join_with_view 7716 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); }; 7717 } // namespace __detail 7718 7719 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith> 7720 { 7721 template<viewable_range _Range, typename _Pattern> 7722 requires __detail::__can_join_with_view<_Range, _Pattern> 7723 constexpr auto 7724 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const 7725 { 7726 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f)); 7727 } 7728 7729 using _RangeAdaptor<_JoinWith>::operator(); 7730 static constexpr int _S_arity = 2; 7731 template<typename _Pattern> 7732 static constexpr bool _S_has_simple_extra_args 7733 = _LazySplit::_S_has_simple_extra_args<_Pattern>; 7734 }; 7735 7736 inline constexpr _JoinWith join_with; 7737 } // namespace views 7738 #endif // __cpp_lib_ranges_join_with 7739 7740 #ifdef __cpp_lib_ranges_repeat // C++ >= 23 7741 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t> 7742 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> 7743 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>) 7744 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>> 7745 { 7746 __detail::__box<_Tp> _M_value; 7747 [[no_unique_address]] _Bound _M_bound = _Bound(); 7748 7749 class _Iterator; 7750 7751 template<typename _Range> 7752 friend constexpr auto 7753 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>); 7754 7755 template<typename _Range> 7756 friend constexpr auto 7757 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>); 7758 7759 public: 7760 repeat_view() requires default_initializable<_Tp> = default; 7761 7762 constexpr explicit 7763 repeat_view(const _Tp& __value, _Bound __bound = _Bound()) 7764 requires copy_constructible<_Tp> 7765 : _M_value(__value), _M_bound(__bound) 7766 { 7767 if constexpr (!same_as<_Bound, unreachable_sentinel_t>) 7768 __glibcxx_assert(__bound >= 0); 7769 } 7770 7771 constexpr explicit 7772 repeat_view(_Tp&& __value, _Bound __bound = _Bound()) 7773 : _M_value(std::move(__value)), _M_bound(__bound) 7774 { } 7775 7776 template<typename... _Args, typename... _BoundArgs> 7777 requires constructible_from<_Tp, _Args...> 7778 && constructible_from<_Bound, _BoundArgs...> 7779 constexpr explicit 7780 repeat_view(piecewise_construct_t, 7781 tuple<_Args...> __args, 7782 tuple<_BoundArgs...> __bound_args = tuple<>{}) 7783 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))), 7784 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args))) 7785 { } 7786 7787 constexpr _Iterator 7788 begin() const 7789 { return _Iterator(std::__addressof(*_M_value)); } 7790 7791 constexpr _Iterator 7792 end() const requires (!same_as<_Bound, unreachable_sentinel_t>) 7793 { return _Iterator(std::__addressof(*_M_value), _M_bound); } 7794 7795 constexpr unreachable_sentinel_t 7796 end() const noexcept 7797 { return unreachable_sentinel; } 7798 7799 constexpr auto 7800 size() const requires (!same_as<_Bound, unreachable_sentinel_t>) 7801 { return __detail::__to_unsigned_like(_M_bound); } 7802 }; 7803 7804 // _GLIBCXX_RESOLVE_LIB_DEFECTS 7805 // 4053. Unary call to std::views::repeat does not decay the argument 7806 template<typename _Tp, typename _Bound = unreachable_sentinel_t> 7807 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>; 7808 7809 template<move_constructible _Tp, semiregular _Bound> 7810 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> 7811 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>) 7812 class repeat_view<_Tp, _Bound>::_Iterator 7813 { 7814 using __index_type 7815 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>; 7816 7817 const _Tp* _M_value = nullptr; 7818 __index_type _M_current = __index_type(); 7819 7820 constexpr explicit 7821 _Iterator(const _Tp* __value, __index_type __bound = __index_type()) 7822 : _M_value(__value), _M_current(__bound) 7823 { 7824 if constexpr (!same_as<_Bound, unreachable_sentinel_t>) 7825 __glibcxx_assert(__bound >= 0); 7826 } 7827 7828 friend repeat_view; 7829 7830 public: 7831 using iterator_concept = random_access_iterator_tag; 7832 using iterator_category = random_access_iterator_tag; 7833 using value_type = _Tp; 7834 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>, 7835 __index_type, 7836 __detail::__iota_diff_t<__index_type>>; 7837 7838 _Iterator() = default; 7839 7840 constexpr const _Tp& 7841 operator*() const noexcept 7842 { return *_M_value; } 7843 7844 constexpr _Iterator& 7845 operator++() 7846 { 7847 ++_M_current; 7848 return *this; 7849 } 7850 7851 constexpr _Iterator 7852 operator++(int) 7853 { 7854 auto __tmp = *this; 7855 ++*this; 7856 return __tmp; 7857 } 7858 7859 constexpr _Iterator& 7860 operator--() 7861 { 7862 if constexpr (!same_as<_Bound, unreachable_sentinel_t>) 7863 __glibcxx_assert(_M_current > 0); 7864 --_M_current; 7865 return *this; 7866 } 7867 7868 constexpr _Iterator 7869 operator--(int) 7870 { 7871 auto __tmp = *this; 7872 --*this; 7873 return __tmp; 7874 } 7875 7876 constexpr _Iterator& 7877 operator+=(difference_type __n) 7878 { 7879 if constexpr (!same_as<_Bound, unreachable_sentinel_t>) 7880 __glibcxx_assert(_M_current + __n >= 0); 7881 _M_current += __n; 7882 return *this; 7883 } 7884 7885 constexpr _Iterator& 7886 operator-=(difference_type __n) 7887 { 7888 if constexpr (!same_as<_Bound, unreachable_sentinel_t>) 7889 __glibcxx_assert(_M_current - __n >= 0); 7890 _M_current -= __n; 7891 return *this; 7892 } 7893 7894 constexpr const _Tp& 7895 operator[](difference_type __n) const noexcept 7896 { return *(*this + __n); } 7897 7898 friend constexpr bool 7899 operator==(const _Iterator& __x, const _Iterator& __y) 7900 { return __x._M_current == __y._M_current; } 7901 7902 friend constexpr auto 7903 operator<=>(const _Iterator& __x, const _Iterator& __y) 7904 { return __x._M_current <=> __y._M_current; } 7905 7906 friend constexpr _Iterator 7907 operator+(_Iterator __i, difference_type __n) 7908 { 7909 __i += __n; 7910 return __i; 7911 } 7912 7913 friend constexpr _Iterator 7914 operator+(difference_type __n, _Iterator __i) 7915 { return __i + __n; } 7916 7917 friend constexpr _Iterator 7918 operator-(_Iterator __i, difference_type __n) 7919 { 7920 __i -= __n; 7921 return __i; 7922 } 7923 7924 friend constexpr difference_type 7925 operator-(const _Iterator& __x, const _Iterator& __y) 7926 { 7927 return (static_cast<difference_type>(__x._M_current) 7928 - static_cast<difference_type>(__y._M_current)); 7929 } 7930 }; 7931 7932 namespace views 7933 { 7934 namespace __detail 7935 { 7936 template<typename _Tp, typename _Bound> 7937 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true; 7938 7939 template<typename _Tp> 7940 concept __can_repeat_view 7941 = requires { repeat_view(std::declval<_Tp>()); }; 7942 7943 template<typename _Tp, typename _Bound> 7944 concept __can_bounded_repeat_view 7945 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); }; 7946 } 7947 7948 struct _Repeat 7949 { 7950 template<typename _Tp> 7951 requires __detail::__can_repeat_view<_Tp> 7952 constexpr auto 7953 operator() [[nodiscard]] (_Tp&& __value) const 7954 { 7955 // _GLIBCXX_RESOLVE_LIB_DEFECTS 7956 // 4054. Repeating a repeat_view should repeat the view 7957 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value)); 7958 } 7959 7960 template<typename _Tp, typename _Bound> 7961 requires __detail::__can_bounded_repeat_view<_Tp, _Bound> 7962 constexpr auto 7963 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const 7964 { return repeat_view(std::forward<_Tp>(__value), __bound); } 7965 }; 7966 7967 inline constexpr _Repeat repeat; 7968 7969 namespace __detail 7970 { 7971 template<typename _Range> 7972 constexpr auto 7973 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n) 7974 { 7975 using _Tp = remove_cvref_t<_Range>; 7976 static_assert(__is_repeat_view<_Tp>); 7977 if constexpr (sized_range<_Tp>) 7978 return views::repeat(*std::forward<_Range>(__r)._M_value, 7979 std::min(ranges::distance(__r), __n)); 7980 else 7981 return views::repeat(*std::forward<_Range>(__r)._M_value, __n); 7982 } 7983 7984 template<typename _Range> 7985 constexpr auto 7986 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n) 7987 { 7988 using _Tp = remove_cvref_t<_Range>; 7989 static_assert(__is_repeat_view<_Tp>); 7990 if constexpr (sized_range<_Tp>) 7991 { 7992 auto __sz = ranges::distance(__r); 7993 return views::repeat(*std::forward<_Range>(__r)._M_value, 7994 __sz - std::min(__sz, __n)); 7995 } 7996 else 7997 return __r; 7998 } 7999 } 8000 } 8001 #endif // __cpp_lib_ranges_repeat 8002 8003 #ifdef __cpp_lib_ranges_stride // C++ >= 23 8004 template<input_range _Vp> 8005 requires view<_Vp> 8006 class stride_view : public view_interface<stride_view<_Vp>> 8007 { 8008 _Vp _M_base; 8009 range_difference_t<_Vp> _M_stride; 8010 8011 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>; 8012 8013 template<bool _Const> 8014 struct __iter_cat 8015 { }; 8016 8017 template<bool _Const> 8018 requires forward_range<_Base<_Const>> 8019 struct __iter_cat<_Const> 8020 { 8021 private: 8022 static auto 8023 _S_iter_cat() 8024 { 8025 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category; 8026 if constexpr (derived_from<_Cat, random_access_iterator_tag>) 8027 return random_access_iterator_tag{}; 8028 else 8029 return _Cat{}; 8030 } 8031 public: 8032 using iterator_category = decltype(_S_iter_cat()); 8033 }; 8034 8035 template<bool> class _Iterator; 8036 8037 public: 8038 constexpr explicit 8039 stride_view(_Vp __base, range_difference_t<_Vp> __stride) 8040 : _M_base(std::move(__base)), _M_stride(__stride) 8041 { __glibcxx_assert(__stride > 0); } 8042 8043 constexpr _Vp 8044 base() const& requires copy_constructible<_Vp> 8045 { return _M_base; } 8046 8047 constexpr _Vp 8048 base() && 8049 { return std::move(_M_base); } 8050 8051 constexpr range_difference_t<_Vp> 8052 stride() const noexcept 8053 { return _M_stride; } 8054 8055 constexpr auto 8056 begin() requires (!__detail::__simple_view<_Vp>) 8057 { return _Iterator<false>(this, ranges::begin(_M_base)); } 8058 8059 constexpr auto 8060 begin() const requires range<const _Vp> 8061 { return _Iterator<true>(this, ranges::begin(_M_base)); } 8062 8063 constexpr auto 8064 end() requires (!__detail::__simple_view<_Vp>) 8065 { 8066 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>) 8067 { 8068 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride; 8069 return _Iterator<false>(this, ranges::end(_M_base), __missing); 8070 } 8071 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>) 8072 return _Iterator<false>(this, ranges::end(_M_base)); 8073 else 8074 return default_sentinel; 8075 } 8076 8077 constexpr auto 8078 end() const requires range<const _Vp> 8079 { 8080 if constexpr (common_range<const _Vp> && sized_range<const _Vp> 8081 && forward_range<const _Vp>) 8082 { 8083 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride; 8084 return _Iterator<true>(this, ranges::end(_M_base), __missing); 8085 } 8086 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>) 8087 return _Iterator<true>(this, ranges::end(_M_base)); 8088 else 8089 return default_sentinel; 8090 } 8091 8092 constexpr auto 8093 size() requires sized_range<_Vp> 8094 { 8095 return __detail::__to_unsigned_like 8096 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride)); 8097 } 8098 8099 constexpr auto 8100 size() const requires sized_range<const _Vp> 8101 { 8102 return __detail::__to_unsigned_like 8103 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride)); 8104 } 8105 }; 8106 8107 template<typename _Range> 8108 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>; 8109 8110 template<typename _Vp> 8111 inline constexpr bool enable_borrowed_range<stride_view<_Vp>> 8112 = enable_borrowed_range<_Vp>; 8113 8114 template<input_range _Vp> 8115 requires view<_Vp> 8116 template<bool _Const> 8117 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const> 8118 { 8119 using _Parent = __detail::__maybe_const_t<_Const, stride_view>; 8120 using _Base = stride_view::_Base<_Const>; 8121 8122 iterator_t<_Base> _M_current = iterator_t<_Base>(); 8123 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 8124 range_difference_t<_Base> _M_stride = 0; 8125 range_difference_t<_Base> _M_missing = 0; 8126 8127 constexpr 8128 _Iterator(_Parent* __parent, iterator_t<_Base> __current, 8129 range_difference_t<_Base> __missing = 0) 8130 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)), 8131 _M_stride(__parent->_M_stride), _M_missing(__missing) 8132 { } 8133 8134 static auto 8135 _S_iter_concept() 8136 { 8137 if constexpr (random_access_range<_Base>) 8138 return random_access_iterator_tag{}; 8139 else if constexpr (bidirectional_range<_Base>) 8140 return bidirectional_iterator_tag{}; 8141 else if constexpr (forward_range<_Base>) 8142 return forward_iterator_tag{}; 8143 else 8144 return input_iterator_tag{}; 8145 } 8146 8147 friend stride_view; 8148 8149 public: 8150 using difference_type = range_difference_t<_Base>; 8151 using value_type = range_value_t<_Base>; 8152 using iterator_concept = decltype(_S_iter_concept()); 8153 // iterator_category defined in stride_view::__iter_cat 8154 8155 _Iterator() requires default_initializable<iterator_t<_Base>> = default; 8156 8157 constexpr 8158 _Iterator(_Iterator<!_Const> __other) 8159 requires _Const 8160 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 8161 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 8162 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)), 8163 _M_stride(__other._M_stride), _M_missing(__other._M_missing) 8164 { } 8165 8166 constexpr iterator_t<_Base> 8167 base() && 8168 { return std::move(_M_current); } 8169 8170 constexpr const iterator_t<_Base>& 8171 base() const & noexcept 8172 { return _M_current; } 8173 8174 constexpr decltype(auto) 8175 operator*() const 8176 { return *_M_current; } 8177 8178 constexpr _Iterator& 8179 operator++() 8180 { 8181 __glibcxx_assert(_M_current != _M_end); 8182 _M_missing = ranges::advance(_M_current, _M_stride, _M_end); 8183 return *this; 8184 } 8185 8186 constexpr void 8187 operator++(int) 8188 { ++*this; } 8189 8190 constexpr _Iterator 8191 operator++(int) requires forward_range<_Base> 8192 { 8193 auto __tmp = *this; 8194 ++*this; 8195 return __tmp; 8196 } 8197 8198 constexpr _Iterator& 8199 operator--() requires bidirectional_range<_Base> 8200 { 8201 ranges::advance(_M_current, _M_missing - _M_stride); 8202 _M_missing = 0; 8203 return *this; 8204 } 8205 8206 constexpr _Iterator 8207 operator--(int) requires bidirectional_range<_Base> 8208 { 8209 auto __tmp = *this; 8210 --*this; 8211 return __tmp; 8212 } 8213 8214 constexpr _Iterator& 8215 operator+=(difference_type __n) requires random_access_range<_Base> 8216 { 8217 if (__n > 0) 8218 { 8219 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1)); 8220 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end); 8221 } 8222 else if (__n < 0) 8223 { 8224 ranges::advance(_M_current, _M_stride * __n + _M_missing); 8225 _M_missing = 0; 8226 } 8227 return *this; 8228 } 8229 8230 constexpr _Iterator& 8231 operator-=(difference_type __n) requires random_access_range<_Base> 8232 { return *this += -__n; } 8233 8234 constexpr decltype(auto) operator[](difference_type __n) const 8235 requires random_access_range<_Base> 8236 { return *(*this + __n); } 8237 8238 friend constexpr bool 8239 operator==(const _Iterator& __x, default_sentinel_t) 8240 { return __x._M_current == __x._M_end; } 8241 8242 friend constexpr bool 8243 operator==(const _Iterator& __x, const _Iterator& __y) 8244 requires equality_comparable<iterator_t<_Base>> 8245 { return __x._M_current == __y._M_current; } 8246 8247 friend constexpr bool 8248 operator<(const _Iterator& __x, const _Iterator& __y) 8249 requires random_access_range<_Base> 8250 { return __x._M_current < __y._M_current; } 8251 8252 friend constexpr bool 8253 operator>(const _Iterator& __x, const _Iterator& __y) 8254 requires random_access_range<_Base> 8255 { return __y._M_current < __x._M_current; } 8256 8257 friend constexpr bool 8258 operator<=(const _Iterator& __x, const _Iterator& __y) 8259 requires random_access_range<_Base> 8260 { return !(__y._M_current < __x._M_current); } 8261 8262 friend constexpr bool 8263 operator>=(const _Iterator& __x, const _Iterator& __y) 8264 requires random_access_range<_Base> 8265 { return !(__x._M_current < __y._M_current); } 8266 8267 friend constexpr auto 8268 operator<=>(const _Iterator& __x, const _Iterator& __y) 8269 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>> 8270 { return __x._M_current <=> __y._M_current; } 8271 8272 friend constexpr _Iterator 8273 operator+(const _Iterator& __i, difference_type __n) 8274 requires random_access_range<_Base> 8275 { 8276 auto __r = __i; 8277 __r += __n; 8278 return __r; 8279 } 8280 8281 friend constexpr _Iterator 8282 operator+(difference_type __n, const _Iterator& __i) 8283 requires random_access_range<_Base> 8284 { return __i + __n; } 8285 8286 friend constexpr _Iterator 8287 operator-(const _Iterator& __i, difference_type __n) 8288 requires random_access_range<_Base> 8289 { 8290 auto __r = __i; 8291 __r -= __n; 8292 return __r; 8293 } 8294 8295 friend constexpr difference_type 8296 operator-(const _Iterator& __x, const _Iterator& __y) 8297 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> 8298 { 8299 auto __n = __x._M_current - __y._M_current; 8300 if constexpr (forward_range<_Base>) 8301 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride; 8302 else if (__n < 0) 8303 return -__detail::__div_ceil(-__n, __x._M_stride); 8304 else 8305 return __detail::__div_ceil(__n, __x._M_stride); 8306 } 8307 8308 friend constexpr difference_type 8309 operator-(default_sentinel_t, const _Iterator& __x) 8310 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> 8311 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); } 8312 8313 friend constexpr difference_type 8314 operator-(const _Iterator& __x, default_sentinel_t __y) 8315 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> 8316 { return -(__y - __x); } 8317 8318 friend constexpr range_rvalue_reference_t<_Base> 8319 iter_move(const _Iterator& __i) 8320 noexcept(noexcept(ranges::iter_move(__i._M_current))) 8321 { return ranges::iter_move(__i._M_current); } 8322 8323 friend constexpr void 8324 iter_swap(const _Iterator& __x, const _Iterator& __y) 8325 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current))) 8326 requires indirectly_swappable<iterator_t<_Base>> 8327 { ranges::iter_swap(__x._M_current, __y._M_current); } 8328 }; 8329 8330 namespace views 8331 { 8332 namespace __detail 8333 { 8334 template<typename _Range, typename _Dp> 8335 concept __can_stride_view 8336 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); }; 8337 } 8338 8339 struct _Stride : __adaptor::_RangeAdaptor<_Stride> 8340 { 8341 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>> 8342 requires __detail::__can_stride_view<_Range, _Dp> 8343 constexpr auto 8344 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const 8345 { return stride_view(std::forward<_Range>(__r), __n); } 8346 8347 using __adaptor::_RangeAdaptor<_Stride>::operator(); 8348 static constexpr int _S_arity = 2; 8349 static constexpr bool _S_has_simple_extra_args = true; 8350 }; 8351 8352 inline constexpr _Stride stride; 8353 } 8354 #endif // __cpp_lib_ranges_stride 8355 8356 #ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23 8357 namespace __detail 8358 { 8359 template<bool _Const, typename _First, typename... _Vs> 8360 concept __cartesian_product_is_random_access 8361 = (random_access_range<__maybe_const_t<_Const, _First>> 8362 && ... 8363 && (random_access_range<__maybe_const_t<_Const, _Vs>> 8364 && sized_range<__maybe_const_t<_Const, _Vs>>)); 8365 8366 template<typename _Range> 8367 concept __cartesian_product_common_arg 8368 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>); 8369 8370 template<bool _Const, typename _First, typename... _Vs> 8371 concept __cartesian_product_is_bidirectional 8372 = (bidirectional_range<__maybe_const_t<_Const, _First>> 8373 && ... 8374 && (bidirectional_range<__maybe_const_t<_Const, _Vs>> 8375 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>)); 8376 8377 template<typename _First, typename... _Vs> 8378 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>; 8379 8380 template<typename... _Vs> 8381 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...); 8382 8383 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs> 8384 concept __cartesian_is_sized_sentinel 8385 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>, 8386 iterator_t<__maybe_const_t<_Const, _First>>> 8387 && ... 8388 && (sized_range<__maybe_const_t<_Const, _Vs>> 8389 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>, 8390 iterator_t<__maybe_const_t<_Const, _Vs>>>)); 8391 8392 template<__cartesian_product_common_arg _Range> 8393 constexpr auto 8394 __cartesian_common_arg_end(_Range& __r) 8395 { 8396 if constexpr (common_range<_Range>) 8397 return ranges::end(__r); 8398 else 8399 return ranges::begin(__r) + ranges::distance(__r); 8400 } 8401 } // namespace __detail 8402 8403 template<input_range _First, forward_range... _Vs> 8404 requires (view<_First> && ... && view<_Vs>) 8405 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>> 8406 { 8407 tuple<_First, _Vs...> _M_bases; 8408 8409 template<bool> class _Iterator; 8410 8411 static auto 8412 _S_difference_type() 8413 { 8414 // TODO: Implement the recommended practice of using the smallest 8415 // sufficiently wide type according to the maximum sizes of the 8416 // underlying ranges? 8417 return common_type_t<ptrdiff_t, 8418 range_difference_t<_First>, 8419 range_difference_t<_Vs>...>{}; 8420 } 8421 8422 public: 8423 cartesian_product_view() = default; 8424 8425 constexpr explicit 8426 cartesian_product_view(_First __first, _Vs... __rest) 8427 : _M_bases(std::move(__first), std::move(__rest)...) 8428 { } 8429 8430 constexpr _Iterator<false> 8431 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>) 8432 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); } 8433 8434 constexpr _Iterator<true> 8435 begin() const requires (range<const _First> && ... && range<const _Vs>) 8436 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); } 8437 8438 constexpr _Iterator<false> 8439 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>) 8440 && __detail::__cartesian_product_is_common<_First, _Vs...>) 8441 { 8442 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) { 8443 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>; 8444 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...); 8445 auto& __first = std::get<0>(_M_bases); 8446 return _Ret{(__empty_tail 8447 ? ranges::begin(__first) 8448 : __detail::__cartesian_common_arg_end(__first)), 8449 ranges::begin(std::get<1 + _Is>(_M_bases))...}; 8450 }(make_index_sequence<sizeof...(_Vs)>{}); 8451 8452 return _Iterator<false>{*this, std::move(__its)}; 8453 } 8454 8455 constexpr _Iterator<true> 8456 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...> 8457 { 8458 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) { 8459 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>; 8460 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...); 8461 auto& __first = std::get<0>(_M_bases); 8462 return _Ret{(__empty_tail 8463 ? ranges::begin(__first) 8464 : __detail::__cartesian_common_arg_end(__first)), 8465 ranges::begin(std::get<1 + _Is>(_M_bases))...}; 8466 }(make_index_sequence<sizeof...(_Vs)>{}); 8467 8468 return _Iterator<true>{*this, std::move(__its)}; 8469 } 8470 8471 constexpr default_sentinel_t 8472 end() const noexcept 8473 { return default_sentinel; } 8474 8475 constexpr auto 8476 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...> 8477 { 8478 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>; 8479 return [&]<size_t... _Is>(index_sequence<_Is...>) { 8480 auto __size = static_cast<_ST>(1); 8481 #ifdef _GLIBCXX_ASSERTIONS 8482 if constexpr (integral<_ST>) 8483 { 8484 bool __overflow 8485 = (__builtin_mul_overflow(__size, 8486 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))), 8487 &__size) 8488 || ...); 8489 __glibcxx_assert(!__overflow); 8490 } 8491 else 8492 #endif 8493 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...); 8494 return __size; 8495 }(make_index_sequence<1 + sizeof...(_Vs)>{}); 8496 } 8497 8498 constexpr auto 8499 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...> 8500 { 8501 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>; 8502 return [&]<size_t... _Is>(index_sequence<_Is...>) { 8503 auto __size = static_cast<_ST>(1); 8504 #ifdef _GLIBCXX_ASSERTIONS 8505 if constexpr (integral<_ST>) 8506 { 8507 bool __overflow 8508 = (__builtin_mul_overflow(__size, 8509 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))), 8510 &__size) 8511 || ...); 8512 __glibcxx_assert(!__overflow); 8513 } 8514 else 8515 #endif 8516 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...); 8517 return __size; 8518 }(make_index_sequence<1 + sizeof...(_Vs)>{}); 8519 } 8520 }; 8521 8522 template<typename... _Vs> 8523 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>; 8524 8525 template<input_range _First, forward_range... _Vs> 8526 requires (view<_First> && ... && view<_Vs>) 8527 template<bool _Const> 8528 class cartesian_product_view<_First, _Vs...>::_Iterator 8529 { 8530 using _Parent = __maybe_const_t<_Const, cartesian_product_view>; 8531 _Parent* _M_parent = nullptr; 8532 tuple<iterator_t<__maybe_const_t<_Const, _First>>, 8533 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current; 8534 8535 constexpr 8536 _Iterator(_Parent& __parent, decltype(_M_current) __current) 8537 : _M_parent(std::__addressof(__parent)), 8538 _M_current(std::move(__current)) 8539 { } 8540 8541 static auto 8542 _S_iter_concept() 8543 { 8544 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>) 8545 return random_access_iterator_tag{}; 8546 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>) 8547 return bidirectional_iterator_tag{}; 8548 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>) 8549 return forward_iterator_tag{}; 8550 else 8551 return input_iterator_tag{}; 8552 } 8553 8554 friend cartesian_product_view; 8555 8556 public: 8557 using iterator_category = input_iterator_tag; 8558 using iterator_concept = decltype(_S_iter_concept()); 8559 using value_type 8560 = tuple<range_value_t<__maybe_const_t<_Const, _First>>, 8561 range_value_t<__maybe_const_t<_Const, _Vs>>...>; 8562 using reference 8563 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>, 8564 range_reference_t<__maybe_const_t<_Const, _Vs>>...>; 8565 using difference_type = decltype(cartesian_product_view::_S_difference_type()); 8566 8567 _Iterator() = default; 8568 8569 constexpr 8570 _Iterator(_Iterator<!_Const> __i) 8571 requires _Const 8572 && (convertible_to<iterator_t<_First>, iterator_t<const _First>> 8573 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>) 8574 : _M_parent(std::__addressof(__i._M_parent)), 8575 _M_current(std::move(__i._M_current)) 8576 { } 8577 8578 constexpr auto 8579 operator*() const 8580 { 8581 auto __f = [](auto& __i) -> decltype(auto) { 8582 return *__i; 8583 }; 8584 return __detail::__tuple_transform(__f, _M_current); 8585 } 8586 8587 constexpr _Iterator& 8588 operator++() 8589 { 8590 _M_next(); 8591 return *this; 8592 } 8593 8594 constexpr void 8595 operator++(int) 8596 { ++*this; } 8597 8598 constexpr _Iterator 8599 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>> 8600 { 8601 auto __tmp = *this; 8602 ++*this; 8603 return __tmp; 8604 } 8605 8606 constexpr _Iterator& 8607 operator--() 8608 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...> 8609 { 8610 _M_prev(); 8611 return *this; 8612 } 8613 8614 constexpr _Iterator 8615 operator--(int) 8616 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...> 8617 { 8618 auto __tmp = *this; 8619 --*this; 8620 return __tmp; 8621 } 8622 8623 constexpr _Iterator& 8624 operator+=(difference_type __x) 8625 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...> 8626 { 8627 _M_advance(__x); 8628 return *this; 8629 } 8630 8631 constexpr _Iterator& 8632 operator-=(difference_type __x) 8633 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...> 8634 { return *this += -__x; } 8635 8636 constexpr reference 8637 operator[](difference_type __n) const 8638 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...> 8639 { return *((*this) + __n); } 8640 8641 friend constexpr bool 8642 operator==(const _Iterator& __x, const _Iterator& __y) 8643 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>> 8644 { return __x._M_current == __y._M_current; } 8645 8646 friend constexpr bool 8647 operator==(const _Iterator& __x, default_sentinel_t) 8648 { 8649 return [&]<size_t... _Is>(index_sequence<_Is...>) { 8650 return ((std::get<_Is>(__x._M_current) 8651 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases))) 8652 || ...); 8653 }(make_index_sequence<1 + sizeof...(_Vs)>{}); 8654 } 8655 8656 friend constexpr auto 8657 operator<=>(const _Iterator& __x, const _Iterator& __y) 8658 requires __detail::__all_random_access<_Const, _First, _Vs...> 8659 { return __x._M_current <=> __y._M_current; } 8660 8661 friend constexpr _Iterator 8662 operator+(_Iterator __x, difference_type __y) 8663 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...> 8664 { return __x += __y; } 8665 8666 friend constexpr _Iterator 8667 operator+(difference_type __x, _Iterator __y) 8668 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...> 8669 { return __y += __x; } 8670 8671 friend constexpr _Iterator 8672 operator-(_Iterator __x, difference_type __y) 8673 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...> 8674 { return __x -= __y; } 8675 8676 friend constexpr difference_type 8677 operator-(const _Iterator& __x, const _Iterator& __y) 8678 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...> 8679 { return __x._M_distance_from(__y._M_current); } 8680 8681 friend constexpr difference_type 8682 operator-(const _Iterator& __i, default_sentinel_t) 8683 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...> 8684 { 8685 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) { 8686 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)), 8687 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...}; 8688 }(make_index_sequence<sizeof...(_Vs)>{}); 8689 return __i._M_distance_from(__end_tuple); 8690 } 8691 8692 friend constexpr difference_type 8693 operator-(default_sentinel_t, const _Iterator& __i) 8694 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...> 8695 { return -(__i - default_sentinel); } 8696 8697 friend constexpr auto 8698 iter_move(const _Iterator& __i) 8699 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); } 8700 8701 friend constexpr void 8702 iter_swap(const _Iterator& __l, const _Iterator& __r) 8703 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>> 8704 && ... 8705 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>) 8706 { 8707 [&]<size_t... _Is>(index_sequence<_Is...>) { 8708 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...); 8709 }(make_index_sequence<1 + sizeof...(_Vs)>{}); 8710 } 8711 8712 private: 8713 template<size_t _Nm = sizeof...(_Vs)> 8714 constexpr void 8715 _M_next() 8716 { 8717 auto& __it = std::get<_Nm>(_M_current); 8718 ++__it; 8719 if constexpr (_Nm > 0) 8720 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases))) 8721 { 8722 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases)); 8723 _M_next<_Nm - 1>(); 8724 } 8725 } 8726 8727 template<size_t _Nm = sizeof...(_Vs)> 8728 constexpr void 8729 _M_prev() 8730 { 8731 auto& __it = std::get<_Nm>(_M_current); 8732 if constexpr (_Nm > 0) 8733 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases))) 8734 { 8735 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases)); 8736 _M_prev<_Nm - 1>(); 8737 } 8738 --__it; 8739 } 8740 8741 template<size_t _Nm = sizeof...(_Vs)> 8742 constexpr void 8743 _M_advance(difference_type __x) 8744 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...> 8745 { 8746 if (__x == 1) 8747 _M_next<_Nm>(); 8748 else if (__x == -1) 8749 _M_prev<_Nm>(); 8750 else if (__x != 0) 8751 { 8752 // Constant time iterator advancement. 8753 auto& __r = std::get<_Nm>(_M_parent->_M_bases); 8754 auto& __it = std::get<_Nm>(_M_current); 8755 if constexpr (_Nm == 0) 8756 { 8757 #ifdef _GLIBCXX_ASSERTIONS 8758 if constexpr (sized_range<__maybe_const_t<_Const, _First>>) 8759 { 8760 auto __size = ranges::ssize(__r); 8761 auto __begin = ranges::begin(__r); 8762 auto __offset = __it - __begin; 8763 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size); 8764 } 8765 #endif 8766 __it += __x; 8767 } 8768 else 8769 { 8770 auto __size = ranges::ssize(__r); 8771 auto __begin = ranges::begin(__r); 8772 auto __offset = __it - __begin; 8773 __offset += __x; 8774 __x = __offset / __size; 8775 __offset %= __size; 8776 if (__offset < 0) 8777 { 8778 __offset = __size + __offset; 8779 --__x; 8780 } 8781 __it = __begin + __offset; 8782 _M_advance<_Nm - 1>(__x); 8783 } 8784 } 8785 } 8786 8787 template<typename _Tuple> 8788 constexpr difference_type 8789 _M_distance_from(const _Tuple& __t) const 8790 { 8791 return [&]<size_t... _Is>(index_sequence<_Is...>) { 8792 auto __sum = static_cast<difference_type>(0); 8793 #ifdef _GLIBCXX_ASSERTIONS 8794 if constexpr (integral<difference_type>) 8795 { 8796 bool __overflow 8797 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum) 8798 || ...); 8799 __glibcxx_assert(!__overflow); 8800 } 8801 else 8802 #endif 8803 __sum = (_M_scaled_distance<_Is>(__t) + ...); 8804 return __sum; 8805 }(make_index_sequence<1 + sizeof...(_Vs)>{}); 8806 } 8807 8808 template<size_t _Nm, typename _Tuple> 8809 constexpr difference_type 8810 _M_scaled_distance(const _Tuple& __t) const 8811 { 8812 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current) 8813 - std::get<_Nm>(__t)); 8814 #ifdef _GLIBCXX_ASSERTIONS 8815 if constexpr (integral<difference_type>) 8816 { 8817 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist); 8818 __glibcxx_assert(!__overflow); 8819 } 8820 else 8821 #endif 8822 __dist *= _M_scaled_size<_Nm+1>(); 8823 return __dist; 8824 } 8825 8826 template<size_t _Nm> 8827 constexpr difference_type 8828 _M_scaled_size() const 8829 { 8830 if constexpr (_Nm <= sizeof...(_Vs)) 8831 { 8832 auto __size = static_cast<difference_type>(ranges::size 8833 (std::get<_Nm>(_M_parent->_M_bases))); 8834 #ifdef _GLIBCXX_ASSERTIONS 8835 if constexpr (integral<difference_type>) 8836 { 8837 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size); 8838 __glibcxx_assert(!__overflow); 8839 } 8840 else 8841 #endif 8842 __size *= _M_scaled_size<_Nm+1>(); 8843 return __size; 8844 } 8845 else 8846 return static_cast<difference_type>(1); 8847 } 8848 }; 8849 8850 namespace views 8851 { 8852 namespace __detail 8853 { 8854 template<typename... _Ts> 8855 concept __can_cartesian_product_view 8856 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); }; 8857 } 8858 8859 struct _CartesianProduct 8860 { 8861 template<typename... _Ts> 8862 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>) 8863 constexpr auto 8864 operator() [[nodiscard]] (_Ts&&... __ts) const 8865 { 8866 if constexpr (sizeof...(_Ts) == 0) 8867 return views::single(tuple{}); 8868 else 8869 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...); 8870 } 8871 }; 8872 8873 inline constexpr _CartesianProduct cartesian_product; 8874 } 8875 #endif // __cpp_lib_ranges_cartesian_product 8876 8877 #ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23 8878 template<input_range _Vp> 8879 requires view<_Vp> 8880 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>> 8881 { 8882 _Vp _M_base = _Vp(); 8883 8884 public: 8885 as_rvalue_view() requires default_initializable<_Vp> = default; 8886 8887 constexpr explicit 8888 as_rvalue_view(_Vp __base) 8889 : _M_base(std::move(__base)) 8890 { } 8891 8892 constexpr _Vp 8893 base() const& requires copy_constructible<_Vp> 8894 { return _M_base; } 8895 8896 constexpr _Vp 8897 base() && 8898 { return std::move(_M_base); } 8899 8900 constexpr auto 8901 begin() requires (!__detail::__simple_view<_Vp>) 8902 { return move_iterator(ranges::begin(_M_base)); } 8903 8904 constexpr auto 8905 begin() const requires range<const _Vp> 8906 { return move_iterator(ranges::begin(_M_base)); } 8907 8908 constexpr auto 8909 end() requires (!__detail::__simple_view<_Vp>) 8910 { 8911 if constexpr (common_range<_Vp>) 8912 return move_iterator(ranges::end(_M_base)); 8913 else 8914 return move_sentinel(ranges::end(_M_base)); 8915 } 8916 8917 constexpr auto 8918 end() const requires range<const _Vp> 8919 { 8920 if constexpr (common_range<const _Vp>) 8921 return move_iterator(ranges::end(_M_base)); 8922 else 8923 return move_sentinel(ranges::end(_M_base)); 8924 } 8925 8926 constexpr auto 8927 size() requires sized_range<_Vp> 8928 { return ranges::size(_M_base); } 8929 8930 constexpr auto 8931 size() const requires sized_range<const _Vp> 8932 { return ranges::size(_M_base); } 8933 }; 8934 8935 template<typename _Range> 8936 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>; 8937 8938 template<typename _Tp> 8939 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>> 8940 = enable_borrowed_range<_Tp>; 8941 8942 namespace views 8943 { 8944 namespace __detail 8945 { 8946 template<typename _Tp> 8947 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); }; 8948 } 8949 8950 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue> 8951 { 8952 template<viewable_range _Range> 8953 requires __detail::__can_as_rvalue_view<_Range> 8954 constexpr auto 8955 operator() [[nodiscard]] (_Range&& __r) const 8956 { 8957 if constexpr (same_as<range_rvalue_reference_t<_Range>, 8958 range_reference_t<_Range>>) 8959 return views::all(std::forward<_Range>(__r)); 8960 else 8961 return as_rvalue_view(std::forward<_Range>(__r)); 8962 } 8963 }; 8964 8965 inline constexpr _AsRvalue as_rvalue; 8966 } 8967 #endif // __cpp_lib_as_rvalue 8968 8969 #ifdef __cpp_lib_ranges_enumerate // C++ >= 23 8970 namespace __detail 8971 { 8972 template<typename _Range> 8973 concept __range_with_movable_reference = input_range<_Range> 8974 && move_constructible<range_reference_t<_Range>> 8975 && move_constructible<range_rvalue_reference_t<_Range>>; 8976 } 8977 8978 template<view _Vp> 8979 requires __detail::__range_with_movable_reference<_Vp> 8980 class enumerate_view : public view_interface<enumerate_view<_Vp>> 8981 { 8982 _Vp _M_base = _Vp(); 8983 8984 template<bool _Const> class _Iterator; 8985 template<bool _Const> class _Sentinel; 8986 8987 public: 8988 enumerate_view() requires default_initializable<_Vp> = default; 8989 8990 constexpr explicit 8991 enumerate_view(_Vp __base) 8992 : _M_base(std::move(__base)) 8993 { } 8994 8995 constexpr auto 8996 begin() requires (!__detail::__simple_view<_Vp>) 8997 { return _Iterator<false>(ranges::begin(_M_base), 0); } 8998 8999 constexpr auto 9000 begin() const requires __detail::__range_with_movable_reference<const _Vp> 9001 { return _Iterator<true>(ranges::begin(_M_base), 0); } 9002 9003 constexpr auto 9004 end() requires (!__detail::__simple_view<_Vp>) 9005 { 9006 if constexpr (common_range<_Vp> && sized_range<_Vp>) 9007 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base)); 9008 else 9009 return _Sentinel<false>(ranges::end(_M_base)); 9010 } 9011 9012 constexpr auto 9013 end() const requires __detail::__range_with_movable_reference<const _Vp> 9014 { 9015 if constexpr (common_range<const _Vp> && sized_range<const _Vp>) 9016 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base)); 9017 else 9018 return _Sentinel<true>(ranges::end(_M_base)); 9019 } 9020 9021 constexpr auto 9022 size() requires sized_range<_Vp> 9023 { return ranges::size(_M_base); } 9024 9025 constexpr auto 9026 size() const requires sized_range<const _Vp> 9027 { return ranges::size(_M_base); } 9028 9029 constexpr _Vp 9030 base() const & requires copy_constructible<_Vp> 9031 { return _M_base; } 9032 9033 constexpr _Vp 9034 base() && 9035 { return std::move(_M_base); } 9036 }; 9037 9038 template<typename _Range> 9039 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>; 9040 9041 template<typename _Tp> 9042 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>> 9043 = enable_borrowed_range<_Tp>; 9044 9045 template<view _Vp> 9046 requires __detail::__range_with_movable_reference<_Vp> 9047 template<bool _Const> 9048 class enumerate_view<_Vp>::_Iterator 9049 { 9050 using _Base = __maybe_const_t<_Const, _Vp>; 9051 9052 static auto 9053 _S_iter_concept() 9054 { 9055 if constexpr (random_access_range<_Base>) 9056 return random_access_iterator_tag{}; 9057 else if constexpr (bidirectional_range<_Base>) 9058 return bidirectional_iterator_tag{}; 9059 else if constexpr (forward_range<_Base>) 9060 return forward_iterator_tag{}; 9061 else 9062 return input_iterator_tag{}; 9063 } 9064 9065 friend enumerate_view; 9066 9067 public: 9068 using iterator_category = input_iterator_tag; 9069 using iterator_concept = decltype(_S_iter_concept()); 9070 using difference_type = range_difference_t<_Base>; 9071 using value_type = tuple<difference_type, range_value_t<_Base>>; 9072 9073 private: 9074 using __reference_type = tuple<difference_type, range_reference_t<_Base>>; 9075 9076 iterator_t<_Base> _M_current = iterator_t<_Base>(); 9077 difference_type _M_pos = 0; 9078 9079 constexpr explicit 9080 _Iterator(iterator_t<_Base> __current, difference_type __pos) 9081 : _M_current(std::move(__current)), _M_pos(__pos) 9082 { } 9083 9084 public: 9085 _Iterator() requires default_initializable<iterator_t<_Base>> = default; 9086 9087 constexpr 9088 _Iterator(_Iterator<!_Const> __i) 9089 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 9090 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos) 9091 { } 9092 9093 constexpr const iterator_t<_Base> & 9094 base() const & noexcept 9095 { return _M_current; } 9096 9097 constexpr iterator_t<_Base> 9098 base() && 9099 { return std::move(_M_current); } 9100 9101 constexpr difference_type 9102 index() const noexcept 9103 { return _M_pos; } 9104 9105 constexpr auto 9106 operator*() const 9107 { return __reference_type(_M_pos, *_M_current); } 9108 9109 constexpr _Iterator& 9110 operator++() 9111 { 9112 ++_M_current; 9113 ++_M_pos; 9114 return *this; 9115 } 9116 9117 constexpr void 9118 operator++(int) 9119 { ++*this; } 9120 9121 constexpr _Iterator 9122 operator++(int) requires forward_range<_Base> 9123 { 9124 auto __tmp = *this; 9125 ++*this; 9126 return __tmp; 9127 } 9128 9129 constexpr _Iterator& 9130 operator--() requires bidirectional_range<_Base> 9131 { 9132 --_M_current; 9133 --_M_pos; 9134 return *this; 9135 } 9136 9137 constexpr _Iterator 9138 operator--(int) requires bidirectional_range<_Base> 9139 { 9140 auto __tmp = *this; 9141 --*this; 9142 return __tmp; 9143 } 9144 9145 constexpr _Iterator& 9146 operator+=(difference_type __n) requires random_access_range<_Base> 9147 { 9148 _M_current += __n; 9149 _M_pos += __n; 9150 return *this; 9151 } 9152 9153 constexpr _Iterator& 9154 operator-=(difference_type __n) requires random_access_range<_Base> 9155 { 9156 _M_current -= __n; 9157 _M_pos -= __n; 9158 return *this; 9159 } 9160 9161 constexpr auto 9162 operator[](difference_type __n) const requires random_access_range<_Base> 9163 { return __reference_type(_M_pos + __n, _M_current[__n]); } 9164 9165 friend constexpr bool 9166 operator==(const _Iterator& __x, const _Iterator& __y) noexcept 9167 { return __x._M_pos == __y._M_pos; } 9168 9169 friend constexpr strong_ordering 9170 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept 9171 { return __x._M_pos <=> __y._M_pos; } 9172 9173 friend constexpr _Iterator 9174 operator+(const _Iterator& __x, difference_type __y) 9175 requires random_access_range<_Base> 9176 { return (auto(__x) += __y); } 9177 9178 friend constexpr _Iterator 9179 operator+(difference_type __x, const _Iterator& __y) 9180 requires random_access_range<_Base> 9181 { return auto(__y) += __x; } 9182 9183 friend constexpr _Iterator 9184 operator-(const _Iterator& __x, difference_type __y) 9185 requires random_access_range<_Base> 9186 { return auto(__x) -= __y; } 9187 9188 friend constexpr difference_type 9189 operator-(const _Iterator& __x, const _Iterator& __y) noexcept 9190 { return __x._M_pos - __y._M_pos; } 9191 9192 friend constexpr auto 9193 iter_move(const _Iterator& __i) 9194 noexcept(noexcept(ranges::iter_move(__i._M_current)) 9195 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>) 9196 { 9197 return tuple<difference_type, range_rvalue_reference_t<_Base>> 9198 (__i._M_pos, ranges::iter_move(__i._M_current)); 9199 } 9200 }; 9201 9202 template<view _Vp> 9203 requires __detail::__range_with_movable_reference<_Vp> 9204 template<bool _Const> 9205 class enumerate_view<_Vp>::_Sentinel 9206 { 9207 using _Base = __maybe_const_t<_Const, _Vp>; 9208 9209 sentinel_t<_Base> _M_end = sentinel_t<_Base>(); 9210 9211 constexpr explicit 9212 _Sentinel(sentinel_t<_Base> __end) 9213 : _M_end(std::move(__end)) 9214 { } 9215 9216 friend enumerate_view; 9217 9218 public: 9219 _Sentinel() = default; 9220 9221 constexpr 9222 _Sentinel(_Sentinel<!_Const> __other) 9223 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>> 9224 : _M_end(std::move(__other._M_end)) 9225 { } 9226 9227 constexpr sentinel_t<_Base> 9228 base() const 9229 { return _M_end; } 9230 9231 template<bool _OtherConst> 9232 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>> 9233 friend constexpr bool 9234 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 9235 { return __x._M_current == __y._M_end; } 9236 9237 template<bool _OtherConst> 9238 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>> 9239 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>> 9240 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y) 9241 { return __x._M_current - __y._M_end; } 9242 9243 template<bool _OtherConst> 9244 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>> 9245 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>> 9246 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y) 9247 { return __x._M_end - __y._M_current; } 9248 }; 9249 9250 namespace views 9251 { 9252 namespace __detail 9253 { 9254 template<typename _Tp> 9255 concept __can_enumerate_view 9256 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); }; 9257 } 9258 9259 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate> 9260 { 9261 template<viewable_range _Range> 9262 requires __detail::__can_enumerate_view<_Range> 9263 constexpr auto 9264 operator() [[nodiscard]] (_Range&& __r) const 9265 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); } 9266 }; 9267 9268 inline constexpr _Enumerate enumerate; 9269 } 9270 #endif // __cpp_lib_ranges_enumerate 9271 9272 #ifdef __cpp_lib_ranges_as_const // C++ >= 23 9273 template<view _Vp> 9274 requires input_range<_Vp> 9275 class as_const_view : public view_interface<as_const_view<_Vp>> 9276 { 9277 _Vp _M_base = _Vp(); 9278 9279 public: 9280 as_const_view() requires default_initializable<_Vp> = default; 9281 9282 constexpr explicit 9283 as_const_view(_Vp __base) 9284 noexcept(is_nothrow_move_constructible_v<_Vp>) 9285 : _M_base(std::move(__base)) 9286 { } 9287 9288 constexpr _Vp 9289 base() const & 9290 noexcept(is_nothrow_copy_constructible_v<_Vp>) 9291 requires copy_constructible<_Vp> 9292 { return _M_base; } 9293 9294 constexpr _Vp 9295 base() && 9296 noexcept(is_nothrow_move_constructible_v<_Vp>) 9297 { return std::move(_M_base); } 9298 9299 constexpr auto 9300 begin() requires (!__detail::__simple_view<_Vp>) 9301 { return ranges::cbegin(_M_base); } 9302 9303 constexpr auto 9304 begin() const requires range<const _Vp> 9305 { return ranges::cbegin(_M_base); } 9306 9307 constexpr auto 9308 end() requires (!__detail::__simple_view<_Vp>) 9309 { return ranges::cend(_M_base); } 9310 9311 constexpr auto 9312 end() const requires range<const _Vp> 9313 { return ranges::cend(_M_base); } 9314 9315 constexpr auto 9316 size() requires sized_range<_Vp> 9317 { return ranges::size(_M_base); } 9318 9319 constexpr auto 9320 size() const requires sized_range<const _Vp> 9321 { return ranges::size(_M_base); } 9322 }; 9323 9324 template<typename _Range> 9325 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>; 9326 9327 template<typename _Tp> 9328 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>> 9329 = enable_borrowed_range<_Tp>; 9330 9331 namespace views 9332 { 9333 namespace __detail 9334 { 9335 template<typename _Tp> 9336 inline constexpr bool __is_constable_ref_view = false; 9337 9338 template<typename _Range> 9339 inline constexpr bool __is_constable_ref_view<ref_view<_Range>> 9340 = constant_range<const _Range>; 9341 9342 template<typename _Range> 9343 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); }; 9344 } 9345 9346 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst> 9347 { 9348 template<viewable_range _Range> 9349 constexpr auto 9350 operator()(_Range&& __r) const 9351 noexcept(noexcept(as_const_view(std::declval<_Range>()))) 9352 requires __detail::__can_as_const_view<_Range> 9353 { 9354 using _Tp = remove_cvref_t<_Range>; 9355 using element_type = remove_reference_t<range_reference_t<_Range>>; 9356 if constexpr (constant_range<views::all_t<_Range>>) 9357 return views::all(std::forward<_Range>(__r)); 9358 else if constexpr (__detail::__is_empty_view<_Tp>) 9359 return views::empty<const element_type>; 9360 else if constexpr (std::__detail::__is_span<_Tp>) 9361 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r)); 9362 else if constexpr (__detail::__is_constable_ref_view<_Tp>) 9363 return ref_view(std::as_const(std::forward<_Range>(__r).base())); 9364 else if constexpr (is_lvalue_reference_v<_Range> 9365 && constant_range<const _Tp> 9366 && !view<_Tp>) 9367 return ref_view(static_cast<const _Tp&>(__r)); 9368 else 9369 return as_const_view(std::forward<_Range>(__r)); 9370 } 9371 }; 9372 9373 inline constexpr _AsConst as_const; 9374 } 9375 #endif // __cpp_lib_as_const 9376 } // namespace ranges 9377 9378 namespace views = ranges::views; 9379 9380 #if __cpp_lib_ranges_to_container // C++ >= 23 9381 namespace ranges 9382 { 9383 /// @cond undocumented 9384 namespace __detail 9385 { 9386 template<typename _Container> 9387 constexpr bool __reservable_container 9388 = sized_range<_Container> 9389 && requires(_Container& __c, range_size_t<_Container> __n) { 9390 __c.reserve(__n); 9391 { __c.capacity() } -> same_as<decltype(__n)>; 9392 { __c.max_size() } -> same_as<decltype(__n)>; 9393 }; 9394 9395 template<typename _Cont, typename _Range> 9396 constexpr bool __toable = requires { 9397 requires (!input_range<_Cont> 9398 || convertible_to<range_reference_t<_Range>, 9399 range_value_t<_Cont>>); 9400 }; 9401 } // namespace __detail 9402 /// @endcond 9403 9404 /// Convert a range to a container. 9405 /** 9406 * @tparam _Cont A container type. 9407 * @param __r A range that models the `input_range` concept. 9408 * @param __args... Arguments to pass to the container constructor. 9409 * @since C++23 9410 * 9411 * This function converts a range to the `_Cont` type. 9412 * 9413 * For example, `std::ranges::to<std::vector<int>>(some_view)` 9414 * will convert the view to `std::vector<int>`. 9415 * 9416 * Additional constructor arguments for the container can be supplied after 9417 * the input range argument, e.g. 9418 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`. 9419 */ 9420 template<typename _Cont, input_range _Rg, typename... _Args> 9421 requires (!view<_Cont>) 9422 constexpr _Cont 9423 to [[nodiscard]] (_Rg&& __r, _Args&&... __args) 9424 { 9425 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>); 9426 static_assert(is_class_v<_Cont> || is_union_v<_Cont>); 9427 9428 if constexpr (__detail::__toable<_Cont, _Rg>) 9429 { 9430 if constexpr (constructible_from<_Cont, _Rg, _Args...>) 9431 return _Cont(std::forward<_Rg>(__r), 9432 std::forward<_Args>(__args)...); 9433 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>) 9434 return _Cont(from_range, std::forward<_Rg>(__r), 9435 std::forward<_Args>(__args)...); 9436 else if constexpr (requires { requires common_range<_Rg>; 9437 typename __iter_category_t<iterator_t<_Rg>>; 9438 requires derived_from<__iter_category_t<iterator_t<_Rg>>, 9439 input_iterator_tag>; 9440 requires constructible_from<_Cont, iterator_t<_Rg>, 9441 sentinel_t<_Rg>, _Args...>; 9442 }) 9443 return _Cont(ranges::begin(__r), ranges::end(__r), 9444 std::forward<_Args>(__args)...); 9445 else 9446 { 9447 static_assert(constructible_from<_Cont, _Args...>); 9448 _Cont __c(std::forward<_Args>(__args)...); 9449 if constexpr (sized_range<_Rg> 9450 && __detail::__reservable_container<_Cont>) 9451 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r))); 9452 // _GLIBCXX_RESOLVE_LIB_DEFECTS 9453 // 4016. container-insertable checks do not match what 9454 // container-inserter does 9455 auto __it = ranges::begin(__r); 9456 const auto __sent = ranges::end(__r); 9457 while (__it != __sent) 9458 { 9459 if constexpr (requires { __c.emplace_back(*__it); }) 9460 __c.emplace_back(*__it); 9461 else if constexpr (requires { __c.push_back(*__it); }) 9462 __c.push_back(*__it); 9463 else if constexpr (requires { __c.emplace(__c.end(), *__it); }) 9464 __c.emplace(__c.end(), *__it); 9465 else 9466 __c.insert(__c.end(), *__it); 9467 ++__it; 9468 } 9469 return __c; 9470 } 9471 } 9472 else 9473 { 9474 static_assert(input_range<range_reference_t<_Rg>>); 9475 // _GLIBCXX_RESOLVE_LIB_DEFECTS 9476 // 3984. ranges::to's recursion branch may be ill-formed 9477 return ranges::to<_Cont>(ref_view(__r) | views::transform( 9478 []<typename _Elt>(_Elt&& __elem) { 9479 using _ValT = range_value_t<_Cont>; 9480 return ranges::to<_ValT>(std::forward<_Elt>(__elem)); 9481 }), std::forward<_Args>(__args)...); 9482 } 9483 } 9484 9485 /// @cond undocumented 9486 namespace __detail 9487 { 9488 template<typename _Rg> 9489 struct _InputIter 9490 { 9491 using iterator_category = input_iterator_tag; 9492 using value_type = range_value_t<_Rg>; 9493 using difference_type = ptrdiff_t; 9494 using pointer = add_pointer_t<range_reference_t<_Rg>>; 9495 using reference = range_reference_t<_Rg>; 9496 reference operator*() const; 9497 pointer operator->() const; 9498 _InputIter& operator++(); 9499 _InputIter operator++(int); 9500 bool operator==(const _InputIter&) const; 9501 }; 9502 9503 template<template<typename...> typename _Cont, input_range _Rg, 9504 typename... _Args> 9505 using _DeduceExpr1 9506 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...)); 9507 9508 template<template<typename...> typename _Cont, input_range _Rg, 9509 typename... _Args> 9510 using _DeduceExpr2 9511 = decltype(_Cont(from_range, std::declval<_Rg>(), 9512 std::declval<_Args>()...)); 9513 9514 template<template<typename...> typename _Cont, input_range _Rg, 9515 typename... _Args> 9516 using _DeduceExpr3 9517 = decltype(_Cont(std::declval<_InputIter<_Rg>>(), 9518 std::declval<_InputIter<_Rg>>(), 9519 std::declval<_Args>()...)); 9520 9521 } // namespace __detail 9522 /// @endcond 9523 9524 template<template<typename...> typename _Cont, input_range _Rg, 9525 typename... _Args> 9526 constexpr auto 9527 to [[nodiscard]] (_Rg&& __r, _Args&&... __args) 9528 { 9529 using __detail::_DeduceExpr1; 9530 using __detail::_DeduceExpr2; 9531 using __detail::_DeduceExpr3; 9532 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; }) 9533 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>( 9534 std::forward<_Rg>(__r), std::forward<_Args>(__args)...); 9535 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; }) 9536 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>( 9537 std::forward<_Rg>(__r), std::forward<_Args>(__args)...); 9538 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; }) 9539 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>( 9540 std::forward<_Rg>(__r), std::forward<_Args>(__args)...); 9541 else 9542 static_assert(false); // Cannot deduce container specialization. 9543 } 9544 9545 /// @cond undocumented 9546 namespace __detail 9547 { 9548 template<typename _Cont> 9549 struct _To 9550 { 9551 template<typename _Range, typename... _Args> 9552 requires requires { ranges::to<_Cont>(std::declval<_Range>(), 9553 std::declval<_Args>()...); } 9554 constexpr auto 9555 operator()(_Range&& __r, _Args&&... __args) const 9556 { 9557 return ranges::to<_Cont>(std::forward<_Range>(__r), 9558 std::forward<_Args>(__args)...); 9559 } 9560 }; 9561 } // namespace __detail 9562 /// @endcond 9563 9564 /// ranges::to adaptor for converting a range to a container type 9565 /** 9566 * @tparam _Cont A container type. 9567 * @param __args... Arguments to pass to the container constructor. 9568 * @since C++23 9569 * 9570 * This range adaptor returns a range adaptor closure object that converts 9571 * a range to the `_Cont` type. 9572 * 9573 * For example, `some_view | std::ranges::to<std::vector<int>>()` 9574 * will convert the view to `std::vector<int>`. 9575 * 9576 * Additional constructor arguments for the container can be supplied, e.g. 9577 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`. 9578 */ 9579 template<typename _Cont, typename... _Args> 9580 requires (!view<_Cont>) 9581 constexpr auto 9582 to [[nodiscard]] (_Args&&... __args) 9583 { 9584 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>); 9585 static_assert(is_class_v<_Cont> || is_union_v<_Cont>); 9586 9587 using __detail::_To; 9588 using views::__adaptor::_Partial; 9589 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...}; 9590 } 9591 9592 /// @cond undocumented 9593 namespace __detail 9594 { 9595 template<template<typename...> typename _Cont> 9596 struct _To2 9597 { 9598 template<typename _Range, typename... _Args> 9599 requires requires { ranges::to<_Cont>(std::declval<_Range>(), 9600 std::declval<_Args>()...); } 9601 constexpr auto 9602 operator()(_Range&& __r, _Args&&... __args) const 9603 { 9604 return ranges::to<_Cont>(std::forward<_Range>(__r), 9605 std::forward<_Args>(__args)...); 9606 } 9607 }; 9608 } // namespace __detail 9609 /// @endcond 9610 9611 /// ranges::to adaptor for converting a range to a deduced container type. 9612 /** 9613 * @tparam _Cont A container template. 9614 * @param __args... Arguments to pass to the container constructor. 9615 * @since C++23 9616 * 9617 * This range adaptor returns a range adaptor closure object that converts 9618 * a range to a specialization of the `_Cont` class template. The specific 9619 * specialization of `_Cont` to be used is deduced automatically. 9620 * 9621 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})` 9622 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the 9623 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`. 9624 * 9625 * Additional constructor arguments for the container can be supplied, e.g. 9626 * `r | std::ranges::to<std::vector>(an_allocator)`. 9627 */ 9628 template<template<typename...> typename _Cont, typename... _Args> 9629 constexpr auto 9630 to [[nodiscard]] (_Args&&... __args) 9631 { 9632 using __detail::_To2; 9633 using views::__adaptor::_Partial; 9634 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...}; 9635 } 9636 9637 } // namespace ranges 9638 #endif // __cpp_lib_ranges_to_container 9639 9640 #if __cpp_lib_ranges_concat // C++ >= C++26 9641 namespace ranges 9642 { 9643 namespace __detail 9644 { 9645 template<typename... _Rs> 9646 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>; 9647 9648 template<typename... _Rs> 9649 using __concat_value_t = common_type_t<range_value_t<_Rs>...>; 9650 9651 template<typename... _Rs> 9652 using __concat_rvalue_reference_t 9653 = common_reference_t<range_rvalue_reference_t<_Rs>...>; 9654 9655 template<typename _Ref, typename _RRef, typename _It> 9656 concept __concat_indirectly_readable_impl = requires(const _It __it) { 9657 { *__it } -> convertible_to<_Ref>; 9658 { ranges::iter_move(__it) } -> convertible_to<_RRef>; 9659 }; 9660 9661 template<typename... _Rs> 9662 concept __concat_indirectly_readable 9663 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&> 9664 && common_reference_with<__concat_reference_t<_Rs...>&&, 9665 __concat_rvalue_reference_t<_Rs...>&&> 9666 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&, 9667 __concat_value_t<_Rs...> const&> 9668 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>, 9669 __concat_rvalue_reference_t<_Rs...>, 9670 iterator_t<_Rs>> 9671 && ...); 9672 9673 template<typename... _Rs> 9674 concept __concatable = requires { 9675 typename __concat_reference_t<_Rs...>; 9676 typename __concat_value_t<_Rs...>; 9677 typename __concat_rvalue_reference_t<_Rs...>; 9678 } && __concat_indirectly_readable<_Rs...>; 9679 9680 template<bool _Const, typename _Range, typename... _Rs> 9681 struct __all_but_last_common 9682 { 9683 static inline constexpr bool value 9684 = requires { requires (common_range<__maybe_const_t<_Const, _Range>> 9685 && __all_but_last_common<_Const, _Rs...>::value); }; 9686 }; 9687 9688 template<bool _Const, typename _Range> 9689 struct __all_but_last_common<_Const, _Range> 9690 { static inline constexpr bool value = true; }; 9691 9692 template<bool _Const, typename... _Rs> 9693 concept __concat_is_random_access = __all_random_access<_Const, _Rs...> 9694 && __all_but_last_common<_Const, _Rs...>::value; 9695 9696 template<bool _Const, typename... _Rs> 9697 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...> 9698 && __all_but_last_common<_Const, _Rs...>::value; 9699 9700 template<typename _Range, typename... _Rs> 9701 struct __all_but_first_sized 9702 { static inline constexpr bool value = (sized_range<_Rs> && ...); }; 9703 } // namespace __detail 9704 9705 template<input_range... _Vs> 9706 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...> 9707 class concat_view : public view_interface<concat_view<_Vs...>> 9708 { 9709 tuple<_Vs...> _M_views; 9710 9711 template<bool _Const> class _Iterator; 9712 9713 public: 9714 constexpr concat_view() = default; 9715 9716 constexpr explicit 9717 concat_view(_Vs... __views) 9718 : _M_views(std::move(__views)...) 9719 { } 9720 9721 constexpr _Iterator<false> 9722 begin() requires (!(__detail::__simple_view<_Vs> && ...)) 9723 { 9724 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views))); 9725 __it.template _M_satisfy<0>(); 9726 return __it; 9727 } 9728 9729 constexpr _Iterator<true> 9730 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...> 9731 { 9732 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views))); 9733 __it.template _M_satisfy<0>(); 9734 return __it; 9735 } 9736 9737 constexpr auto 9738 end() requires (!(__detail::__simple_view<_Vs> && ...)) 9739 { 9740 constexpr auto __n = sizeof...(_Vs); 9741 if constexpr (__detail::__all_forward<false, _Vs...> 9742 && common_range<_Vs...[__n - 1]>) 9743 return _Iterator<false>(this, in_place_index<__n - 1>, 9744 ranges::end(std::get<__n - 1>(_M_views))); 9745 else 9746 return default_sentinel; 9747 } 9748 9749 constexpr auto 9750 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...> 9751 { 9752 constexpr auto __n = sizeof...(_Vs); 9753 if constexpr (__detail::__all_forward<true, _Vs...> 9754 && common_range<const _Vs...[__n - 1]>) 9755 return _Iterator<true>(this, in_place_index<__n - 1>, 9756 ranges::end(std::get<__n - 1>(_M_views))); 9757 else 9758 return default_sentinel; 9759 } 9760 9761 constexpr auto 9762 size() requires (sized_range<_Vs>&&...) 9763 { 9764 return std::apply([](auto... __sizes) { 9765 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>; 9766 return (_CT(__sizes) + ...); 9767 }, __detail::__tuple_transform(ranges::size, _M_views)); 9768 } 9769 9770 constexpr auto 9771 size() const requires (sized_range<const _Vs>&&...) 9772 { 9773 return std::apply([](auto... __sizes) { 9774 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>; 9775 return (_CT(__sizes) + ...); 9776 }, __detail::__tuple_transform(ranges::size, _M_views)); 9777 } 9778 }; 9779 9780 template<typename... _Rs> 9781 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>; 9782 9783 namespace __detail 9784 { 9785 template<bool _Const, typename... _Vs> 9786 struct __concat_view_iter_cat 9787 { }; 9788 9789 template<bool _Const, typename... _Vs> 9790 requires __detail::__all_forward<_Const, _Vs...> 9791 struct __concat_view_iter_cat<_Const, _Vs...> 9792 { 9793 static auto 9794 _S_iter_cat() 9795 { 9796 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>) 9797 return input_iterator_tag{}; 9798 else 9799 return []<typename... _Cats>(_Cats... __cats) { 9800 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...) 9801 && __concat_is_random_access<_Const, _Vs...>) 9802 return random_access_iterator_tag{}; 9803 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...) 9804 && __concat_is_bidirectional<_Const, _Vs...>) 9805 return bidirectional_iterator_tag{}; 9806 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...)) 9807 return forward_iterator_tag{}; 9808 else 9809 return input_iterator_tag{}; 9810 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>> 9811 ::iterator_category{}...); 9812 } 9813 }; 9814 } 9815 9816 template<input_range... _Vs> 9817 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...> 9818 template<bool _Const> 9819 class concat_view<_Vs...>::_Iterator 9820 : public __detail::__concat_view_iter_cat<_Const, _Vs...> 9821 { 9822 static auto 9823 _S_iter_concept() 9824 { 9825 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>) 9826 return random_access_iterator_tag{}; 9827 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>) 9828 return bidirectional_iterator_tag{}; 9829 else if constexpr (__detail::__all_forward<_Const, _Vs...>) 9830 return forward_iterator_tag{}; 9831 else 9832 return input_iterator_tag{}; 9833 } 9834 9835 friend concat_view; 9836 friend _Iterator<!_Const>; 9837 9838 public: 9839 // iterator_category defined in __concat_view_iter_cat 9840 using iterator_concept = decltype(_S_iter_concept()); 9841 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>; 9842 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>; 9843 9844 private: 9845 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>; 9846 9847 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr; 9848 __base_iter _M_it; 9849 9850 template<size_t _Nm> 9851 constexpr void 9852 _M_satisfy() 9853 { 9854 if constexpr (_Nm < (sizeof...(_Vs) - 1)) 9855 { 9856 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views))) 9857 { 9858 _M_it.template emplace<_Nm + 1>(ranges::begin 9859 (std::get<_Nm + 1>(_M_parent->_M_views))); 9860 _M_satisfy<_Nm + 1>(); 9861 } 9862 } 9863 } 9864 9865 template<size_t _Nm> 9866 constexpr void 9867 _M_prev() 9868 { 9869 if constexpr (_Nm == 0) 9870 --std::get<0>(_M_it); 9871 else 9872 { 9873 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views))) 9874 { 9875 _M_it.template emplace<_Nm - 1>(ranges::end 9876 (std::get<_Nm - 1>(_M_parent->_M_views))); 9877 _M_prev<_Nm - 1>(); 9878 } 9879 else 9880 --std::get<_Nm>(_M_it); 9881 } 9882 } 9883 9884 template<size_t _Nm> 9885 constexpr void 9886 _M_advance_fwd(difference_type __offset, difference_type __steps) 9887 { 9888 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>; 9889 if constexpr (_Nm == sizeof...(_Vs) - 1) 9890 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps); 9891 else 9892 { 9893 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views)); 9894 if (__offset + __steps < __n_size) 9895 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps); 9896 else 9897 { 9898 _M_it.template emplace<_Nm + 1>(ranges::begin 9899 (std::get<_Nm + 1>(_M_parent->_M_views))); 9900 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size); 9901 } 9902 } 9903 } 9904 9905 template<size_t _Nm> 9906 constexpr void 9907 _M_advance_bwd(difference_type __offset, difference_type __steps) 9908 { 9909 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>; 9910 if constexpr (_Nm == 0) 9911 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps); 9912 else { 9913 if (__offset >= __steps) 9914 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps); 9915 else 9916 { 9917 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views)); 9918 _M_it.template emplace<_Nm - 1>(ranges::end 9919 (std::get<_Nm - 1>(_M_parent->_M_views))); 9920 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset); 9921 } 9922 } 9923 } 9924 9925 // Invoke the function object __f, which has a call operator with a size_t 9926 // template parameter (corresponding to an index into the pack of views), 9927 // using the runtime value of __index as the template argument. 9928 template<typename _Fp> 9929 static constexpr auto 9930 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index) 9931 { 9932 return [&__f, __index]<size_t _Idx>(this auto&& __self) { 9933 if (_Idx == __index) 9934 return __f.template operator()<_Idx>(); 9935 if constexpr (_Idx + 1 < sizeof...(_Vs)) 9936 return __self.template operator()<_Idx + 1>(); 9937 __builtin_unreachable(); 9938 }.template operator()<0>(); 9939 } 9940 9941 template<typename _Fp> 9942 constexpr auto 9943 _M_invoke_with_runtime_index(_Fp&& __f) 9944 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); } 9945 9946 template<typename... _Args> 9947 explicit constexpr 9948 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args) 9949 requires constructible_from<__base_iter, _Args&&...> 9950 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...) 9951 { } 9952 9953 public: 9954 _Iterator() = default; 9955 9956 constexpr 9957 _Iterator(_Iterator<!_Const> __it) 9958 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...) 9959 : _M_parent(__it._M_parent), 9960 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() { 9961 return __base_iter(in_place_index<_Idx>, 9962 std::get<_Idx>(std::move(__it._M_it))); 9963 }, __it._M_it.index())) 9964 { } 9965 9966 constexpr decltype(auto) 9967 operator*() const 9968 { 9969 __glibcxx_assert(!_M_it.valueless_by_exception()); 9970 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>; 9971 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it); 9972 } 9973 9974 constexpr _Iterator& 9975 operator++() 9976 { 9977 _M_invoke_with_runtime_index([this]<size_t _Idx>() { 9978 ++std::get<_Idx>(_M_it); 9979 _M_satisfy<_Idx>(); 9980 }); 9981 return *this; 9982 } 9983 9984 constexpr void 9985 operator++(int) 9986 { ++*this; } 9987 9988 constexpr _Iterator 9989 operator++(int) 9990 requires __detail::__all_forward<_Const, _Vs...> 9991 { 9992 auto __tmp = *this; 9993 ++*this; 9994 return __tmp; 9995 } 9996 9997 constexpr _Iterator& 9998 operator--() 9999 requires __detail::__concat_is_bidirectional<_Const, _Vs...> 10000 { 10001 __glibcxx_assert(!_M_it.valueless_by_exception()); 10002 _M_invoke_with_runtime_index([this]<size_t _Idx>() { 10003 _M_prev<_Idx>(); 10004 }); 10005 return *this; 10006 } 10007 10008 constexpr _Iterator 10009 operator--(int) 10010 requires __detail::__concat_is_bidirectional<_Const, _Vs...> 10011 { 10012 auto __tmp = *this; 10013 --*this; 10014 return __tmp; 10015 } 10016 10017 constexpr _Iterator& 10018 operator+=(difference_type __n) 10019 requires __detail::__concat_is_random_access<_Const, _Vs...> 10020 { 10021 __glibcxx_assert(!_M_it.valueless_by_exception()); 10022 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() { 10023 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views)); 10024 if (__n > 0) 10025 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n); 10026 else if (__n < 0) 10027 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n); 10028 }); 10029 return *this; 10030 } 10031 10032 constexpr _Iterator& 10033 operator-=(difference_type __n) 10034 requires __detail::__concat_is_random_access<_Const, _Vs...> 10035 { 10036 *this += -__n; 10037 return *this; 10038 } 10039 10040 constexpr decltype(auto) 10041 operator[](difference_type __n) const 10042 requires __detail::__concat_is_random_access<_Const, _Vs...> 10043 { return *((*this) + __n); } 10044 10045 friend constexpr bool 10046 operator==(const _Iterator& __x, const _Iterator& __y) 10047 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...) 10048 { 10049 __glibcxx_assert(!__x._M_it.valueless_by_exception()); 10050 __glibcxx_assert(!__y._M_it.valueless_by_exception()); 10051 return __x._M_it == __y._M_it; 10052 } 10053 10054 friend constexpr bool 10055 operator==(const _Iterator& __it, default_sentinel_t) 10056 { 10057 __glibcxx_assert(!__it._M_it.valueless_by_exception()); 10058 constexpr auto __last_idx = sizeof...(_Vs) - 1; 10059 return (__it._M_it.index() == __last_idx 10060 && (std::get<__last_idx>(__it._M_it) 10061 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views)))); 10062 } 10063 10064 friend constexpr bool 10065 operator<(const _Iterator& __x, const _Iterator& __y) 10066 requires __detail::__all_random_access<_Const, _Vs...> 10067 { return __x._M_it < __y._M_it; } 10068 10069 friend constexpr bool 10070 operator>(const _Iterator& __x, const _Iterator& __y) 10071 requires __detail::__all_random_access<_Const, _Vs...> 10072 { return __x._M_it > __y._M_it; } 10073 10074 friend constexpr bool 10075 operator<=(const _Iterator& __x, const _Iterator& __y) 10076 requires __detail::__all_random_access<_Const, _Vs...> 10077 { return __x._M_it <= __y._M_it; } 10078 10079 friend constexpr bool 10080 operator>=(const _Iterator& __x, const _Iterator& __y) 10081 requires __detail::__all_random_access<_Const, _Vs...> 10082 { return __x._M_it >= __y._M_it; } 10083 10084 friend constexpr auto 10085 operator<=>(const _Iterator& __x, const _Iterator& __y) 10086 requires __detail::__all_random_access<_Const, _Vs...> 10087 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...) 10088 { return __x._M_it <=> __y._M_it; } 10089 10090 friend constexpr _Iterator 10091 operator+(const _Iterator& __it, difference_type __n) 10092 requires __detail::__concat_is_random_access<_Const, _Vs...> 10093 { return auto(__it) += __n; } 10094 10095 friend constexpr _Iterator 10096 operator+(difference_type __n, const _Iterator& __it) 10097 requires __detail::__concat_is_random_access<_Const, _Vs...> 10098 { return __it + __n; } 10099 10100 friend constexpr _Iterator 10101 operator-(const _Iterator& __it, difference_type __n) 10102 requires __detail::__concat_is_random_access<_Const, _Vs...> 10103 { return auto(__it) -= __n; } 10104 10105 friend constexpr difference_type 10106 operator-(const _Iterator& __x, const _Iterator& __y) 10107 requires __detail::__concat_is_random_access<_Const, _Vs...> 10108 { 10109 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type { 10110 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type { 10111 if constexpr (_Ix > _Iy) 10112 { 10113 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it), 10114 ranges::end(std::get<_Iy>(__y._M_parent 10115 ->_M_views))); 10116 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent 10117 ->_M_views)), 10118 std::get<_Ix>(__x._M_it)); 10119 difference_type __s = 0; 10120 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) { 10121 if constexpr (_Idx < _Ix) 10122 { 10123 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views)); 10124 __self.template operator()<_Idx + 1>(); 10125 } 10126 }(); 10127 return __dy + __s + __dx; 10128 } 10129 else if constexpr (_Ix < _Iy) 10130 return -(__y - __x); 10131 else 10132 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it); 10133 }, __y._M_it.index()); 10134 }, __x._M_it.index()); 10135 } 10136 10137 friend constexpr difference_type 10138 operator-(const _Iterator& __x, default_sentinel_t) 10139 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>, 10140 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...) 10141 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value 10142 { 10143 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type { 10144 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it), 10145 ranges::end(std::get<_Ix>(__x._M_parent->_M_views))); 10146 difference_type __s = 0; 10147 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) { 10148 if constexpr (_Idx < sizeof...(_Vs)) 10149 { 10150 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views)); 10151 __self.template operator()<_Idx + 1>(); 10152 } 10153 }(); 10154 return -(__dx + __s); 10155 }, __x._M_it.index()); 10156 } 10157 10158 friend constexpr difference_type 10159 operator-(default_sentinel_t, const _Iterator& __x) 10160 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>, 10161 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...) 10162 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value 10163 { return -(__x - default_sentinel); } 10164 10165 friend constexpr decltype(auto) 10166 iter_move(const _Iterator& __it) 10167 { 10168 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>; 10169 return std::visit([](const auto& __i) -> _Res { 10170 return ranges::iter_move(__i); 10171 }, __it._M_it); 10172 } 10173 10174 friend constexpr void 10175 iter_swap(const _Iterator& __x, const _Iterator& __y) 10176 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>> 10177 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>) 10178 { 10179 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) { 10180 if constexpr (is_same_v<_Tp, _Up>) 10181 ranges::iter_swap(__it1, __it2); 10182 else 10183 ranges::swap(*__it1, *__it2); 10184 }, __x._M_it, __y._M_it); 10185 } 10186 }; 10187 10188 namespace views 10189 { 10190 namespace __detail 10191 { 10192 template<typename... _Ts> 10193 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); }; 10194 } 10195 10196 struct _Concat 10197 { 10198 template<typename... _Ts> 10199 requires __detail::__can_concat_view<_Ts...> 10200 constexpr auto 10201 operator() [[nodiscard]] (_Ts&&... __ts) const 10202 { return concat_view(std::forward<_Ts>(__ts)...); } 10203 10204 template<input_range _Range> 10205 constexpr auto 10206 operator() [[nodiscard]] (_Range&& __t) const 10207 { return views::all(std::forward<_Range>(__t)); } 10208 }; 10209 10210 inline constexpr _Concat concat; 10211 } 10212 10213 } // namespace ranges 10214 #endif // __cpp_lib_ranges_concat 10215 10216 #if __cpp_lib_ranges_cache_latest // C++ >= 26 10217 namespace ranges 10218 { 10219 template<input_range _Vp> 10220 requires view<_Vp> 10221 class cache_latest_view : public view_interface<cache_latest_view<_Vp>> 10222 { 10223 _Vp _M_base = _Vp(); 10224 10225 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>, 10226 add_pointer_t<range_reference_t<_Vp>>, 10227 range_reference_t<_Vp>>; 10228 __detail::__non_propagating_cache<__cache_t> _M_cache; 10229 10230 class _Iterator; 10231 class _Sentinel; 10232 10233 public: 10234 cache_latest_view() requires default_initializable<_Vp> = default; 10235 10236 constexpr explicit 10237 cache_latest_view(_Vp __base) 10238 : _M_base(std::move(__base)) 10239 { } 10240 10241 constexpr _Vp 10242 base() const & requires copy_constructible<_Vp> 10243 { return _M_base; } 10244 10245 constexpr _Vp 10246 base() && 10247 { return std::move(_M_base); } 10248 10249 constexpr auto 10250 begin() 10251 { return _Iterator(*this); } 10252 10253 constexpr auto 10254 end() 10255 { return _Sentinel(*this); } 10256 10257 constexpr auto 10258 size() requires sized_range<_Vp> 10259 { return ranges::size(_M_base); } 10260 10261 constexpr auto 10262 size() const requires sized_range<const _Vp> 10263 { return ranges::size(_M_base); } 10264 }; 10265 10266 template<typename _Range> 10267 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>; 10268 10269 template<input_range _Vp> 10270 requires view<_Vp> 10271 class cache_latest_view<_Vp>::_Iterator 10272 { 10273 cache_latest_view* _M_parent; 10274 iterator_t<_Vp> _M_current; 10275 10276 constexpr explicit 10277 _Iterator(cache_latest_view& __parent) 10278 : _M_parent(std::__addressof(__parent)), 10279 _M_current(ranges::begin(__parent._M_base)) 10280 { } 10281 10282 friend class cache_latest_view; 10283 10284 public: 10285 using difference_type = range_difference_t<_Vp>; 10286 using value_type = range_value_t<_Vp>; 10287 using iterator_concept = input_iterator_tag; 10288 10289 _Iterator(_Iterator&&) = default; 10290 10291 _Iterator& 10292 operator=(_Iterator&&) = default; 10293 10294 constexpr iterator_t<_Vp> 10295 base() && 10296 { return std::move(_M_current); } 10297 10298 constexpr const iterator_t<_Vp>& 10299 base() const & noexcept 10300 { return _M_current; } 10301 10302 constexpr range_reference_t<_Vp>& 10303 operator*() const 10304 { 10305 if constexpr (is_reference_v<range_reference_t<_Vp>>) 10306 { 10307 if (!_M_parent->_M_cache) 10308 _M_parent->_M_cache = std::__addressof(__detail::__as_lvalue(*_M_current)); 10309 return **_M_parent->_M_cache; 10310 } 10311 else 10312 { 10313 if (!_M_parent->_M_cache) 10314 _M_parent->_M_cache._M_emplace_deref(_M_current); 10315 return *_M_parent->_M_cache; 10316 } 10317 } 10318 10319 constexpr _Iterator& 10320 operator++() 10321 { 10322 _M_parent->_M_cache._M_reset(); 10323 ++_M_current; 10324 return *this; 10325 } 10326 10327 constexpr void 10328 operator++(int) 10329 { ++*this; } 10330 10331 friend constexpr range_rvalue_reference_t<_Vp> 10332 iter_move(const _Iterator& __i) 10333 noexcept(noexcept(ranges::iter_move(__i._M_current))) 10334 { return ranges::iter_move(__i._M_current); } 10335 10336 friend constexpr void 10337 iter_swap(const _Iterator& __x, const _Iterator& __y) 10338 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current))) 10339 requires indirectly_swappable<iterator_t<_Vp>> 10340 { ranges::iter_swap(__x._M_current, __y._M_current); } 10341 }; 10342 10343 template<input_range _Vp> 10344 requires view<_Vp> 10345 class cache_latest_view<_Vp>::_Sentinel 10346 { 10347 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>(); 10348 10349 constexpr explicit 10350 _Sentinel(cache_latest_view& __parent) 10351 : _M_end(ranges::end(__parent._M_base)) 10352 { } 10353 10354 friend class cache_latest_view; 10355 10356 public: 10357 _Sentinel() = default; 10358 10359 constexpr sentinel_t<_Vp> 10360 base() const 10361 { return _M_end; } 10362 10363 friend constexpr bool 10364 operator==(const _Iterator& __x, const _Sentinel& __y) 10365 { return __x._M_current == __y._M_end; } 10366 10367 friend constexpr range_difference_t<_Vp> 10368 operator-(const _Iterator& __x, const _Sentinel& __y) 10369 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 10370 { return __x._M_current - __y._M_end; } 10371 10372 friend constexpr range_difference_t<_Vp> 10373 operator-(const _Sentinel& __x, const _Iterator& __y) 10374 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>> 10375 { return __x._M_end - __y._M_current; } 10376 }; 10377 10378 namespace views 10379 { 10380 namespace __detail 10381 { 10382 template<typename _Tp> 10383 concept __can_cache_latest = requires { cache_latest_view(std::declval<_Tp>()); }; 10384 } 10385 10386 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest> 10387 { 10388 template<viewable_range _Range> 10389 requires __detail::__can_cache_latest<_Range> 10390 constexpr auto 10391 operator() [[nodiscard]] (_Range&& __r) const 10392 { return cache_latest_view(std::forward<_Range>(__r)); } 10393 10394 static constexpr bool _S_has_simple_call_op = true; 10395 }; 10396 10397 inline constexpr _CacheLatest cache_latest; 10398 } 10399 } // namespace ranges 10400 #endif // __cpp_lib_ranges_cache_latest 10401 10402 #if __cpp_lib_ranges_to_input // C++ >= 26 10403 namespace ranges 10404 { 10405 template<input_range _Vp> 10406 requires view<_Vp> 10407 class to_input_view : public view_interface<to_input_view<_Vp>> 10408 { 10409 _Vp _M_base = _Vp(); 10410 10411 template<bool _Const> 10412 class _Iterator; 10413 10414 public: 10415 to_input_view() requires default_initializable<_Vp> = default; 10416 10417 constexpr explicit 10418 to_input_view(_Vp __base) 10419 : _M_base(std::move(__base)) 10420 { } 10421 10422 constexpr _Vp 10423 base() const & requires copy_constructible<_Vp> 10424 { return _M_base; } 10425 10426 constexpr _Vp 10427 base() && 10428 { return std::move(_M_base); } 10429 10430 constexpr auto 10431 begin() requires (!__detail::__simple_view<_Vp>) 10432 { return _Iterator<false>(ranges::begin(_M_base)); } 10433 10434 constexpr auto 10435 begin() const requires range<const _Vp> 10436 { return _Iterator<true>(ranges::begin(_M_base)); } 10437 10438 constexpr auto 10439 end() requires (!__detail::__simple_view<_Vp>) 10440 { return ranges::end(_M_base); } 10441 10442 constexpr auto 10443 end() const requires range<const _Vp> 10444 { return ranges::end(_M_base); } 10445 10446 constexpr auto 10447 size() requires sized_range<_Vp> 10448 { return ranges::size(_M_base); } 10449 10450 constexpr auto 10451 size() const requires sized_range<const _Vp> 10452 { return ranges::size(_M_base); } 10453 }; 10454 10455 template<typename _Range> 10456 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>; 10457 10458 template<input_range _Vp> 10459 requires view<_Vp> 10460 template<bool _Const> 10461 class to_input_view<_Vp>::_Iterator 10462 { 10463 using _Base = __maybe_const_t<_Const, _Vp>; 10464 10465 iterator_t<_Base> _M_current = iterator_t<_Base>(); 10466 10467 constexpr explicit 10468 _Iterator(iterator_t<_Base> __current) 10469 : _M_current(std::move(__current)) 10470 { } 10471 10472 friend to_input_view; 10473 friend _Iterator<!_Const>; 10474 10475 public: 10476 using difference_type = range_difference_t<_Base>; 10477 using value_type = range_value_t<_Base>; 10478 using iterator_concept = input_iterator_tag; 10479 10480 _Iterator() requires default_initializable<iterator_t<_Base>> = default; 10481 10482 _Iterator(_Iterator&&) = default; 10483 _Iterator& operator=(_Iterator&&) = default; 10484 10485 constexpr 10486 _Iterator(_Iterator<!_Const> __i) 10487 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>> 10488 : _M_current(std::move(__i._M_current)) 10489 { } 10490 10491 constexpr iterator_t<_Base> 10492 base() && 10493 { return std::move(_M_current); } 10494 10495 constexpr const iterator_t<_Base>& 10496 base() const & noexcept 10497 { return _M_current; } 10498 10499 constexpr decltype(auto) 10500 operator*() const 10501 { return *_M_current; } 10502 10503 constexpr _Iterator& 10504 operator++() 10505 { 10506 ++_M_current; 10507 return *this; 10508 } 10509 10510 constexpr void 10511 operator++(int) 10512 { ++*this; } 10513 10514 friend constexpr bool 10515 operator==(const _Iterator& __x, const sentinel_t<_Base>& __y) 10516 { return __x._M_current == __y; } 10517 10518 friend constexpr difference_type 10519 operator-(const sentinel_t<_Base>& __y, const _Iterator& __x) 10520 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> 10521 { return __y - __x._M_current; } 10522 10523 friend constexpr difference_type 10524 operator-(const _Iterator& __x, const sentinel_t<_Base>& __y) 10525 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>> 10526 { return __x._M_current - __y; } 10527 10528 friend constexpr range_rvalue_reference_t<_Base> 10529 iter_move(const _Iterator& __i) 10530 noexcept(noexcept(ranges::iter_move(__i._M_current))) 10531 { return ranges::iter_move(__i._M_current); } 10532 10533 friend constexpr void 10534 iter_swap(const _Iterator& __x, const _Iterator& __y) 10535 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current))) 10536 requires indirectly_swappable<iterator_t<_Base>> 10537 { ranges::iter_swap(__x._M_current, __y._M_current); } 10538 }; 10539 10540 namespace views 10541 { 10542 namespace __detail 10543 { 10544 template<typename _Tp> 10545 concept __can_to_input = requires { to_input_view(std::declval<_Tp>()); }; 10546 } 10547 10548 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput> 10549 { 10550 template<viewable_range _Range> 10551 requires __detail::__can_to_input<_Range> 10552 constexpr auto 10553 operator() [[nodiscard]] (_Range&& __r) const 10554 { 10555 if constexpr (input_range<_Range> 10556 && !common_range<_Range> 10557 && !forward_range<_Range>) 10558 return views::all(std::forward<_Range>(__r)); 10559 else 10560 return to_input_view(std::forward<_Range>(__r)); 10561 } 10562 10563 static constexpr bool _S_has_simple_call_op = true; 10564 }; 10565 10566 inline constexpr _ToInput to_input; 10567 } 10568 } // namespace ranges 10569 #endif // __cpp_lib_ranges_to_input 10570 10571 _GLIBCXX_END_NAMESPACE_VERSION 10572 } // namespace std 10573 #endif // library concepts 10574 #endif // C++2a 10575 #endif /* _GLIBCXX_RANGES */