Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/bits/ranges_base.h
$ cat -n /usr/include/c++/13/bits/ranges_base.h 1 // Core concepts and definitions for
-*- C++ -*- 2 3 // Copyright (C) 2019-2023 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 //
. 24 25 /** @file bits/ranges_base.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{ranges} 28 */ 29 30 #ifndef _GLIBCXX_RANGES_BASE_H 31 #define _GLIBCXX_RANGES_BASE_H 1 32 33 #pragma GCC system_header 34 35 #if __cplusplus > 201703L 36 #include
37 #include
38 #include
39 #include
40 41 #ifdef __cpp_lib_concepts 42 namespace std _GLIBCXX_VISIBILITY(default) 43 { 44 _GLIBCXX_BEGIN_NAMESPACE_VERSION 45 namespace ranges 46 { 47 template
48 inline constexpr bool disable_sized_range = false; 49 50 template
51 inline constexpr bool enable_borrowed_range = false; 52 53 namespace __detail 54 { 55 constexpr __max_size_type 56 __to_unsigned_like(__max_size_type __t) noexcept 57 { return __t; } 58 59 constexpr __max_size_type 60 __to_unsigned_like(__max_diff_type __t) noexcept 61 { return __max_size_type(__t); } 62 63 template
64 constexpr auto 65 __to_unsigned_like(_Tp __t) noexcept 66 { return static_cast
>(__t); } 67 68 #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ 69 constexpr unsigned __int128 70 __to_unsigned_like(__int128 __t) noexcept 71 { return __t; } 72 73 constexpr unsigned __int128 74 __to_unsigned_like(unsigned __int128 __t) noexcept 75 { return __t; } 76 #endif 77 78 template
79 using __make_unsigned_like_t 80 = decltype(__detail::__to_unsigned_like(std::declval<_Tp>())); 81 82 // Part of the constraints of ranges::borrowed_range 83 template
84 concept __maybe_borrowed_range 85 = is_lvalue_reference_v<_Tp> 86 || enable_borrowed_range
>; 87 88 } // namespace __detail 89 90 namespace __cust_access 91 { 92 using std::ranges::__detail::__maybe_borrowed_range; 93 using std::__detail::__range_iter_t; 94 95 struct _Begin 96 { 97 private: 98 template
99 static constexpr bool 100 _S_noexcept() 101 { 102 if constexpr (is_array_v
>) 103 return true; 104 else if constexpr (__member_begin<_Tp>) 105 return noexcept(__decay_copy(std::declval<_Tp&>().begin())); 106 else 107 return noexcept(__decay_copy(begin(std::declval<_Tp&>()))); 108 } 109 110 public: 111 template<__maybe_borrowed_range _Tp> 112 requires is_array_v
> || __member_begin<_Tp> 113 || __adl_begin<_Tp> 114 constexpr auto 115 operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) 116 { 117 if constexpr (is_array_v
>) 118 { 119 static_assert(is_lvalue_reference_v<_Tp>); 120 return __t + 0; 121 } 122 else if constexpr (__member_begin<_Tp>) 123 return __t.begin(); 124 else 125 return begin(__t); 126 } 127 }; 128 129 template
130 concept __member_end = requires(_Tp& __t) 131 { 132 { __decay_copy(__t.end()) } -> sentinel_for<__range_iter_t<_Tp>>; 133 }; 134 135 // Poison pills so that unqualified lookup doesn't find std::end. 136 void end(auto&) = delete; 137 void end(const auto&) = delete; 138 139 template
140 concept __adl_end = __class_or_enum
> 141 && requires(_Tp& __t) 142 { 143 { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>; 144 }; 145 146 struct _End 147 { 148 private: 149 template
150 static constexpr bool 151 _S_noexcept() 152 { 153 if constexpr (is_bounded_array_v
>) 154 return true; 155 else if constexpr (__member_end<_Tp>) 156 return noexcept(__decay_copy(std::declval<_Tp&>().end())); 157 else 158 return noexcept(__decay_copy(end(std::declval<_Tp&>()))); 159 } 160 161 public: 162 template<__maybe_borrowed_range _Tp> 163 requires is_bounded_array_v
> 164 || __member_end<_Tp> || __adl_end<_Tp> 165 constexpr auto 166 operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) 167 { 168 if constexpr (is_bounded_array_v
>) 169 { 170 static_assert(is_lvalue_reference_v<_Tp>); 171 return __t + extent_v
>; 172 } 173 else if constexpr (__member_end<_Tp>) 174 return __t.end(); 175 else 176 return end(__t); 177 } 178 }; 179 180 template
181 concept __member_rbegin = requires(_Tp& __t) 182 { 183 { __decay_copy(__t.rbegin()) } -> input_or_output_iterator; 184 }; 185 186 void rbegin(auto&) = delete; 187 void rbegin(const auto&) = delete; 188 189 template
190 concept __adl_rbegin = __class_or_enum
> 191 && requires(_Tp& __t) 192 { 193 { __decay_copy(rbegin(__t)) } -> input_or_output_iterator; 194 }; 195 196 template
197 concept __reversable = requires(_Tp& __t) 198 { 199 { _Begin{}(__t) } -> bidirectional_iterator; 200 { _End{}(__t) } -> same_as
; 201 }; 202 203 struct _RBegin 204 { 205 private: 206 template
207 static constexpr bool 208 _S_noexcept() 209 { 210 if constexpr (__member_rbegin<_Tp>) 211 return noexcept(__decay_copy(std::declval<_Tp&>().rbegin())); 212 else if constexpr (__adl_rbegin<_Tp>) 213 return noexcept(__decay_copy(rbegin(std::declval<_Tp&>()))); 214 else 215 { 216 if constexpr (noexcept(_End{}(std::declval<_Tp&>()))) 217 { 218 using _It = decltype(_End{}(std::declval<_Tp&>())); 219 // std::reverse_iterator copy-initializes its member. 220 return is_nothrow_copy_constructible_v<_It>; 221 } 222 else 223 return false; 224 } 225 } 226 227 public: 228 template<__maybe_borrowed_range _Tp> 229 requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp> 230 constexpr auto 231 operator()[[nodiscard]](_Tp&& __t) const 232 noexcept(_S_noexcept<_Tp&>()) 233 { 234 if constexpr (__member_rbegin<_Tp>) 235 return __t.rbegin(); 236 else if constexpr (__adl_rbegin<_Tp>) 237 return rbegin(__t); 238 else 239 return std::make_reverse_iterator(_End{}(__t)); 240 } 241 }; 242 243 template
244 concept __member_rend = requires(_Tp& __t) 245 { 246 { __decay_copy(__t.rend()) } 247 -> sentinel_for
(__t)))>; 248 }; 249 250 void rend(auto&) = delete; 251 void rend(const auto&) = delete; 252 253 template
254 concept __adl_rend = __class_or_enum
> 255 && requires(_Tp& __t) 256 { 257 { __decay_copy(rend(__t)) } 258 -> sentinel_for
(__t)))>; 259 }; 260 261 struct _REnd 262 { 263 private: 264 template
265 static constexpr bool 266 _S_noexcept() 267 { 268 if constexpr (__member_rend<_Tp>) 269 return noexcept(__decay_copy(std::declval<_Tp&>().rend())); 270 else if constexpr (__adl_rend<_Tp>) 271 return noexcept(__decay_copy(rend(std::declval<_Tp&>()))); 272 else 273 { 274 if constexpr (noexcept(_Begin{}(std::declval<_Tp&>()))) 275 { 276 using _It = decltype(_Begin{}(std::declval<_Tp&>())); 277 // std::reverse_iterator copy-initializes its member. 278 return is_nothrow_copy_constructible_v<_It>; 279 } 280 else 281 return false; 282 } 283 } 284 285 public: 286 template<__maybe_borrowed_range _Tp> 287 requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp> 288 constexpr auto 289 operator()[[nodiscard]](_Tp&& __t) const 290 noexcept(_S_noexcept<_Tp&>()) 291 { 292 if constexpr (__member_rend<_Tp>) 293 return __t.rend(); 294 else if constexpr (__adl_rend<_Tp>) 295 return rend(__t); 296 else 297 return std::make_reverse_iterator(_Begin{}(__t)); 298 } 299 }; 300 301 template
302 concept __member_size = !disable_sized_range
> 303 && requires(_Tp& __t) 304 { 305 { __decay_copy(__t.size()) } -> __detail::__is_integer_like; 306 }; 307 308 void size(auto&) = delete; 309 void size(const auto&) = delete; 310 311 template
312 concept __adl_size = __class_or_enum
> 313 && !disable_sized_range
> 314 && requires(_Tp& __t) 315 { 316 { __decay_copy(size(__t)) } -> __detail::__is_integer_like; 317 }; 318 319 template
320 concept __sentinel_size = requires(_Tp& __t) 321 { 322 requires (!is_unbounded_array_v
>); 323 324 { _Begin{}(__t) } -> forward_iterator; 325 326 { _End{}(__t) } -> sized_sentinel_for
; 327 328 __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t)); 329 }; 330 331 struct _Size 332 { 333 private: 334 template
335 static constexpr bool 336 _S_noexcept() 337 { 338 if constexpr (is_bounded_array_v
>) 339 return true; 340 else if constexpr (__member_size<_Tp>) 341 return noexcept(__decay_copy(std::declval<_Tp&>().size())); 342 else if constexpr (__adl_size<_Tp>) 343 return noexcept(__decay_copy(size(std::declval<_Tp&>()))); 344 else if constexpr (__sentinel_size<_Tp>) 345 return noexcept(_End{}(std::declval<_Tp&>()) 346 - _Begin{}(std::declval<_Tp&>())); 347 } 348 349 public: 350 template
351 requires is_bounded_array_v
> 352 || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp> 353 constexpr auto 354 operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) 355 { 356 if constexpr (is_bounded_array_v
>) 357 return extent_v
>; 358 else if constexpr (__member_size<_Tp>) 359 return __t.size(); 360 else if constexpr (__adl_size<_Tp>) 361 return size(__t); 362 else if constexpr (__sentinel_size<_Tp>) 363 return __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t)); 364 } 365 }; 366 367 struct _SSize 368 { 369 // _GLIBCXX_RESOLVE_LIB_DEFECTS 370 // 3403. Domain of ranges::ssize(E) doesn't match ranges::size(E) 371 template
372 requires requires (_Tp& __t) { _Size{}(__t); } 373 constexpr auto 374 operator()[[nodiscard]](_Tp&& __t) const noexcept(noexcept(_Size{}(__t))) 375 { 376 auto __size = _Size{}(__t); 377 using __size_type = decltype(__size); 378 // Return the wider of ptrdiff_t and make-signed-like-t<__size_type>. 379 if constexpr (integral<__size_type>) 380 { 381 using __gnu_cxx::__int_traits; 382 if constexpr (__int_traits<__size_type>::__digits 383 < __int_traits
::__digits) 384 return static_cast
(__size); 385 else 386 return static_cast
>(__size); 387 } 388 #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ 389 // For strict-ansi modes integral<__int128> is false 390 else if constexpr (__detail::__is_int128<__size_type>) 391 return static_cast<__int128>(__size); 392 #endif 393 else // Must be one of __max_diff_type or __max_size_type. 394 return __detail::__max_diff_type(__size); 395 } 396 }; 397 398 template
399 concept __member_empty = requires(_Tp& __t) { bool(__t.empty()); }; 400 401 template
402 concept __size0_empty = requires(_Tp& __t) { _Size{}(__t) == 0; }; 403 404 template
405 concept __eq_iter_empty = requires(_Tp& __t) 406 { 407 requires (!is_unbounded_array_v
>); 408 409 { _Begin{}(__t) } -> forward_iterator; 410 411 bool(_Begin{}(__t) == _End{}(__t)); 412 }; 413 414 struct _Empty 415 { 416 private: 417 template
418 static constexpr bool 419 _S_noexcept() 420 { 421 if constexpr (__member_empty<_Tp>) 422 return noexcept(bool(std::declval<_Tp&>().empty())); 423 else if constexpr (__size0_empty<_Tp>) 424 return noexcept(_Size{}(std::declval<_Tp&>()) == 0); 425 else 426 return noexcept(bool(_Begin{}(std::declval<_Tp&>()) 427 == _End{}(std::declval<_Tp&>()))); 428 } 429 430 public: 431 template
432 requires __member_empty<_Tp> || __size0_empty<_Tp> 433 || __eq_iter_empty<_Tp> 434 constexpr bool 435 operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp&>()) 436 { 437 if constexpr (__member_empty<_Tp>) 438 return bool(__t.empty()); 439 else if constexpr (__size0_empty<_Tp>) 440 return _Size{}(__t) == 0; 441 else 442 return bool(_Begin{}(__t) == _End{}(__t)); 443 } 444 }; 445 446 template
447 concept __pointer_to_object = is_pointer_v<_Tp> 448 && is_object_v
>; 449 450 template
451 concept __member_data = requires(_Tp& __t) 452 { 453 { __decay_copy(__t.data()) } -> __pointer_to_object; 454 }; 455 456 template
457 concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>; 458 459 struct _Data 460 { 461 private: 462 template
463 static constexpr bool 464 _S_noexcept() 465 { 466 if constexpr (__member_data<_Tp>) 467 return noexcept(__decay_copy(std::declval<_Tp&>().data())); 468 else 469 return noexcept(_Begin{}(std::declval<_Tp&>())); 470 } 471 472 public: 473 template<__maybe_borrowed_range _Tp> 474 requires __member_data<_Tp> || __begin_data<_Tp> 475 constexpr auto 476 operator()[[nodiscard]](_Tp&& __t) const noexcept(_S_noexcept<_Tp>()) 477 { 478 if constexpr (__member_data<_Tp>) 479 return __t.data(); 480 else 481 return std::to_address(_Begin{}(__t)); 482 } 483 }; 484 485 } // namespace __cust_access 486 487 inline namespace __cust 488 { 489 inline constexpr __cust_access::_Begin begin{}; 490 inline constexpr __cust_access::_End end{}; 491 inline constexpr __cust_access::_RBegin rbegin{}; 492 inline constexpr __cust_access::_REnd rend{}; 493 inline constexpr __cust_access::_Size size{}; 494 inline constexpr __cust_access::_SSize ssize{}; 495 inline constexpr __cust_access::_Empty empty{}; 496 inline constexpr __cust_access::_Data data{}; 497 } 498 499 /// [range.range] The range concept. 500 template
501 concept range = requires(_Tp& __t) 502 { 503 ranges::begin(__t); 504 ranges::end(__t); 505 }; 506 507 /// [range.range] The borrowed_range concept. 508 template
509 concept borrowed_range 510 = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>; 511 512 template
513 using iterator_t = std::__detail::__range_iter_t<_Tp>; 514 515 template
516 using sentinel_t = decltype(ranges::end(std::declval<_Range&>())); 517 518 #if __cplusplus > 202002L 519 template
520 using const_iterator_t = const_iterator
>; 521 522 template
523 using const_sentinel_t = const_sentinel
>; 524 525 template
526 using range_const_reference_t = iter_const_reference_t
>; 527 #endif 528 529 template
530 using range_difference_t = iter_difference_t
>; 531 532 template
533 using range_value_t = iter_value_t
>; 534 535 template
536 using range_reference_t = iter_reference_t
>; 537 538 template
539 using range_rvalue_reference_t 540 = iter_rvalue_reference_t
>; 541 542 /// [range.sized] The sized_range concept. 543 template
544 concept sized_range = range<_Tp> 545 && requires(_Tp& __t) { ranges::size(__t); }; 546 547 template
548 using range_size_t = decltype(ranges::size(std::declval<_Range&>())); 549 550 template
551 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> 552 class view_interface; // defined in
553 554 namespace __detail 555 { 556 template
557 requires (!same_as<_Tp, view_interface<_Up>>) 558 void __is_derived_from_view_interface_fn(const _Tp&, 559 const view_interface<_Up>&); // not defined 560 561 // Returns true iff _Tp has exactly one public base class that's a 562 // specialization of view_interface. 563 template
564 concept __is_derived_from_view_interface 565 = requires (_Tp __t) { __is_derived_from_view_interface_fn(__t, __t); }; 566 } // namespace __detail 567 568 /// [range.view] The ranges::view_base type. 569 struct view_base { }; 570 571 /// [range.view] The ranges::enable_view boolean. 572 template
573 inline constexpr bool enable_view = derived_from<_Tp, view_base> 574 || __detail::__is_derived_from_view_interface<_Tp>; 575 576 /// [range.view] The ranges::view concept. 577 template
578 concept view 579 = range<_Tp> && movable<_Tp> && enable_view<_Tp>; 580 581 // [range.refinements] 582 583 /// A range for which ranges::begin returns an output iterator. 584 template
585 concept output_range 586 = range<_Range> && output_iterator
, _Tp>; 587 588 /// A range for which ranges::begin returns an input iterator. 589 template
590 concept input_range = range<_Tp> && input_iterator
>; 591 592 /// A range for which ranges::begin returns a forward iterator. 593 template
594 concept forward_range 595 = input_range<_Tp> && forward_iterator
>; 596 597 /// A range for which ranges::begin returns a bidirectional iterator. 598 template
599 concept bidirectional_range 600 = forward_range<_Tp> && bidirectional_iterator
>; 601 602 /// A range for which ranges::begin returns a random access iterator. 603 template
604 concept random_access_range 605 = bidirectional_range<_Tp> && random_access_iterator
>; 606 607 /// A range for which ranges::begin returns a contiguous iterator. 608 template
609 concept contiguous_range 610 = random_access_range<_Tp> && contiguous_iterator
> 611 && requires(_Tp& __t) 612 { 613 { ranges::data(__t) } -> same_as
>>; 614 }; 615 616 /// A range for which ranges::begin and ranges::end return the same type. 617 template
618 concept common_range 619 = range<_Tp> && same_as
, sentinel_t<_Tp>>; 620 621 #if __cplusplus > 202002L 622 template
623 concept constant_range 624 = input_range<_Tp> && std::__detail::__constant_iterator
>; 625 #endif 626 627 namespace __cust_access 628 { 629 #if __cplusplus > 202020L 630 template
631 constexpr auto& 632 __possibly_const_range(_Range& __r) noexcept 633 { 634 if constexpr (constant_range
&& !constant_range<_Range>) 635 return const_cast
(__r); 636 else 637 return __r; 638 } 639 #else 640 // If _To is an lvalue-reference, return const _Tp&, otherwise const _Tp&&. 641 template
642 constexpr decltype(auto) 643 __as_const(_Tp& __t) noexcept 644 { 645 static_assert(std::is_same_v<_To&, _Tp&>); 646 647 if constexpr (is_lvalue_reference_v<_To>) 648 return const_cast
(__t); 649 else 650 return static_cast
(__t); 651 } 652 #endif 653 654 struct _CBegin 655 { 656 #if __cplusplus > 202002L 657 template<__maybe_borrowed_range _Tp> 658 [[nodiscard]] 659 constexpr auto 660 operator()(_Tp&& __t) const 661 noexcept(noexcept(std::make_const_iterator 662 (ranges::begin(__cust_access::__possibly_const_range(__t))))) 663 requires requires { std::make_const_iterator 664 (ranges::begin(__cust_access::__possibly_const_range(__t))); } 665 { 666 auto& __r = __cust_access::__possibly_const_range(__t); 667 return const_iterator_t
(ranges::begin(__r)); 668 } 669 #else 670 template
671 [[nodiscard]] 672 constexpr auto 673 operator()(_Tp&& __e) const 674 noexcept(noexcept(_Begin{}(__cust_access::__as_const<_Tp>(__e)))) 675 requires requires { _Begin{}(__cust_access::__as_const<_Tp>(__e)); } 676 { 677 return _Begin{}(__cust_access::__as_const<_Tp>(__e)); 678 } 679 #endif 680 }; 681 682 struct _CEnd final 683 { 684 #if __cplusplus > 202002L 685 template<__maybe_borrowed_range _Tp> 686 [[nodiscard]] 687 constexpr auto 688 operator()(_Tp&& __t) const 689 noexcept(noexcept(std::make_const_sentinel 690 (ranges::end(__cust_access::__possibly_const_range(__t))))) 691 requires requires { std::make_const_sentinel 692 (ranges::end(__cust_access::__possibly_const_range(__t))); } 693 { 694 auto& __r = __cust_access::__possibly_const_range(__t); 695 return const_sentinel_t
(ranges::end(__r)); 696 } 697 #else 698 template
699 [[nodiscard]] 700 constexpr auto 701 operator()(_Tp&& __e) const 702 noexcept(noexcept(_End{}(__cust_access::__as_const<_Tp>(__e)))) 703 requires requires { _End{}(__cust_access::__as_const<_Tp>(__e)); } 704 { 705 return _End{}(__cust_access::__as_const<_Tp>(__e)); 706 } 707 #endif 708 }; 709 710 struct _CRBegin 711 { 712 #if __cplusplus > 202002L 713 template<__maybe_borrowed_range _Tp> 714 [[nodiscard]] 715 constexpr auto 716 operator()(_Tp&& __t) const 717 noexcept(noexcept(std::make_const_iterator 718 (ranges::rbegin(__cust_access::__possibly_const_range(__t))))) 719 requires requires { std::make_const_iterator 720 (ranges::rbegin(__cust_access::__possibly_const_range(__t))); } 721 { 722 auto& __r = __cust_access::__possibly_const_range(__t); 723 return const_iterator
(ranges::rbegin(__r)); 724 } 725 #else 726 template
727 [[nodiscard]] 728 constexpr auto 729 operator()(_Tp&& __e) const 730 noexcept(noexcept(_RBegin{}(__cust_access::__as_const<_Tp>(__e)))) 731 requires requires { _RBegin{}(__cust_access::__as_const<_Tp>(__e)); } 732 { 733 return _RBegin{}(__cust_access::__as_const<_Tp>(__e)); 734 } 735 #endif 736 }; 737 738 struct _CREnd 739 { 740 #if __cplusplus > 202002L 741 template<__maybe_borrowed_range _Tp> 742 [[nodiscard]] 743 constexpr auto 744 operator()(_Tp&& __t) const 745 noexcept(noexcept(std::make_const_sentinel 746 (ranges::rend(__cust_access::__possibly_const_range(__t))))) 747 requires requires { std::make_const_sentinel 748 (ranges::rend(__cust_access::__possibly_const_range(__t))); } 749 { 750 auto& __r = __cust_access::__possibly_const_range(__t); 751 return const_sentinel
(ranges::rend(__r)); 752 } 753 #else 754 template
755 [[nodiscard]] 756 constexpr auto 757 operator()(_Tp&& __e) const 758 noexcept(noexcept(_REnd{}(__cust_access::__as_const<_Tp>(__e)))) 759 requires requires { _REnd{}(__cust_access::__as_const<_Tp>(__e)); } 760 { 761 return _REnd{}(__cust_access::__as_const<_Tp>(__e)); 762 } 763 #endif 764 }; 765 766 struct _CData 767 { 768 #if __cplusplus > 202002L 769 template<__maybe_borrowed_range _Tp> 770 [[nodiscard]] 771 constexpr const auto* 772 operator()(_Tp&& __t) const 773 noexcept(noexcept(ranges::data(__cust_access::__possibly_const_range(__t)))) 774 requires requires { ranges::data(__cust_access::__possibly_const_range(__t)); } 775 { return ranges::data(__cust_access::__possibly_const_range(__t)); } 776 #else 777 template
778 [[nodiscard]] 779 constexpr auto 780 operator()(_Tp&& __e) const 781 noexcept(noexcept(_Data{}(__cust_access::__as_const<_Tp>(__e)))) 782 requires requires { _Data{}(__cust_access::__as_const<_Tp>(__e)); } 783 { 784 return _Data{}(__cust_access::__as_const<_Tp>(__e)); 785 } 786 #endif 787 }; 788 789 } // namespace __cust_access 790 791 inline namespace __cust 792 { 793 inline constexpr __cust_access::_CBegin cbegin{}; 794 inline constexpr __cust_access::_CEnd cend{}; 795 inline constexpr __cust_access::_CRBegin crbegin{}; 796 inline constexpr __cust_access::_CREnd crend{}; 797 inline constexpr __cust_access::_CData cdata{}; 798 } 799 800 namespace __detail 801 { 802 template
803 inline constexpr bool __is_initializer_list = false; 804 805 template
806 inline constexpr bool __is_initializer_list
> = true; 807 } // namespace __detail 808 809 /// A range which can be safely converted to a view. 810 template
811 concept viewable_range = range<_Tp> 812 && ((view
> && constructible_from
, _Tp>) 813 || (!view
> 814 && (is_lvalue_reference_v<_Tp> 815 || (movable
> 816 && !__detail::__is_initializer_list
>)))); 817 818 // [range.iter.ops] range iterator operations 819 820 struct __advance_fn final 821 { 822 template
823 constexpr void 824 operator()(_It& __it, iter_difference_t<_It> __n) const 825 { 826 if constexpr (random_access_iterator<_It>) 827 __it += __n; 828 else if constexpr (bidirectional_iterator<_It>) 829 { 830 if (__n > 0) 831 { 832 do 833 { 834 ++__it; 835 } 836 while (--__n); 837 } 838 else if (__n < 0) 839 { 840 do 841 { 842 --__it; 843 } 844 while (++__n); 845 } 846 } 847 else 848 { 849 // cannot decrement a non-bidirectional iterator 850 __glibcxx_assert(__n >= 0); 851 while (__n-- > 0) 852 ++__it; 853 } 854 } 855 856 template
_Sent> 857 constexpr void 858 operator()(_It& __it, _Sent __bound) const 859 { 860 if constexpr (assignable_from<_It&, _Sent>) 861 __it = std::move(__bound); 862 else if constexpr (sized_sentinel_for<_Sent, _It>) 863 (*this)(__it, __bound - __it); 864 else 865 { 866 while (__it != __bound) 867 ++__it; 868 } 869 } 870 871 template
_Sent> 872 constexpr iter_difference_t<_It> 873 operator()(_It& __it, iter_difference_t<_It> __n, _Sent __bound) const 874 { 875 if constexpr (sized_sentinel_for<_Sent, _It>) 876 { 877 const auto __diff = __bound - __it; 878 879 if (__diff == 0) 880 return __n; 881 else if (__diff > 0 ? __n >= __diff : __n <= __diff) 882 { 883 (*this)(__it, __bound); 884 return __n - __diff; 885 } 886 else if (__n != 0) [[likely]] 887 { 888 // n and bound must not lead in opposite directions: 889 __glibcxx_assert((__n < 0) == (__diff < 0)); 890 891 (*this)(__it, __n); 892 return 0; 893 } 894 else 895 return 0; 896 } 897 else if (__it == __bound || __n == 0) 898 return __n; 899 else if (__n > 0) 900 { 901 iter_difference_t<_It> __m = 0; 902 do 903 { 904 ++__it; 905 ++__m; 906 } 907 while (__m != __n && __it != __bound); 908 return __n - __m; 909 } 910 else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>) 911 { 912 iter_difference_t<_It> __m = 0; 913 do 914 { 915 --__it; 916 --__m; 917 } 918 while (__m != __n && __it != __bound); 919 return __n - __m; 920 } 921 else 922 { 923 // cannot decrement a non-bidirectional iterator 924 __glibcxx_assert(__n >= 0); 925 return __n; 926 } 927 } 928 929 void operator&() const = delete; 930 }; 931 932 inline constexpr __advance_fn advance{}; 933 934 struct __distance_fn final 935 { 936 template
_Sent> 937 requires (!sized_sentinel_for<_Sent, _It>) 938 constexpr iter_difference_t<_It> 939 operator()[[nodiscard]](_It __first, _Sent __last) const 940 { 941 iter_difference_t<_It> __n = 0; 942 while (__first != __last) 943 { 944 ++__first; 945 ++__n; 946 } 947 return __n; 948 } 949 950 template
_Sent> 951 [[nodiscard]] 952 constexpr iter_difference_t<_It> 953 operator()(const _It& __first, const _Sent& __last) const 954 { 955 return __last - __first; 956 } 957 958 template
959 [[nodiscard]] 960 constexpr range_difference_t<_Range> 961 operator()(_Range&& __r) const 962 { 963 if constexpr (sized_range<_Range>) 964 return static_cast
>(ranges::size(__r)); 965 else 966 return (*this)(ranges::begin(__r), ranges::end(__r)); 967 } 968 969 void operator&() const = delete; 970 }; 971 972 inline constexpr __distance_fn distance{}; 973 974 struct __next_fn final 975 { 976 template
977 [[nodiscard]] 978 constexpr _It 979 operator()(_It __x) const 980 { 981 ++__x; 982 return __x; 983 } 984 985 template
986 [[nodiscard]] 987 constexpr _It 988 operator()(_It __x, iter_difference_t<_It> __n) const 989 { 990 ranges::advance(__x, __n); 991 return __x; 992 } 993 994 template
_Sent> 995 [[nodiscard]] 996 constexpr _It 997 operator()(_It __x, _Sent __bound) const 998 { 999 ranges::advance(__x, __bound); 1000 return __x; 1001 } 1002 1003 template
_Sent> 1004 [[nodiscard]] 1005 constexpr _It 1006 operator()(_It __x, iter_difference_t<_It> __n, _Sent __bound) const 1007 { 1008 ranges::advance(__x, __n, __bound); 1009 return __x; 1010 } 1011 1012 void operator&() const = delete; 1013 }; 1014 1015 inline constexpr __next_fn next{}; 1016 1017 struct __prev_fn final 1018 { 1019 template
1020 [[nodiscard]] 1021 constexpr _It 1022 operator()(_It __x) const 1023 { 1024 --__x; 1025 return __x; 1026 } 1027 1028 template
1029 [[nodiscard]] 1030 constexpr _It 1031 operator()(_It __x, iter_difference_t<_It> __n) const 1032 { 1033 ranges::advance(__x, -__n); 1034 return __x; 1035 } 1036 1037 template
1038 [[nodiscard]] 1039 constexpr _It 1040 operator()(_It __x, iter_difference_t<_It> __n, _It __bound) const 1041 { 1042 ranges::advance(__x, -__n, __bound); 1043 return __x; 1044 } 1045 1046 void operator&() const = delete; 1047 }; 1048 1049 inline constexpr __prev_fn prev{}; 1050 1051 /// Type returned by algorithms instead of a dangling iterator or subrange. 1052 struct dangling 1053 { 1054 constexpr dangling() noexcept = default; 1055 template
1056 constexpr dangling(_Args&&...) noexcept { } 1057 }; 1058 1059 template
1060 using borrowed_iterator_t = __conditional_t
, 1061 iterator_t<_Range>, 1062 dangling>; 1063 1064 } // namespace ranges 1065 _GLIBCXX_END_NAMESPACE_VERSION 1066 } // namespace std 1067 #endif // library concepts 1068 #endif // C++20 1069 #endif // _GLIBCXX_RANGES_BASE_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™