Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/bits/iterator_concepts.h
$ cat -n /usr/include/c++/13/bits/iterator_concepts.h 1 // Concepts and traits for use with iterators -*- 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/iterator_concepts.h 26 * This is an internal header file, included by other library headers. 27 * Do not attempt to use it directly. @headername{iterator} 28 */ 29 30 #ifndef _ITERATOR_CONCEPTS_H 31 #define _ITERATOR_CONCEPTS_H 1 32 33 #pragma GCC system_header 34 35 #if __cplusplus >= 202002L 36 #include
37 #include
// to_address 38 #include
// identity, ranges::less 39 40 namespace std _GLIBCXX_VISIBILITY(default) 41 { 42 _GLIBCXX_BEGIN_NAMESPACE_VERSION 43 44 /** A sentinel type that can be used to check for the end of a range. 45 * 46 * For some iterator types the past-the-end sentinel value is independent 47 * of the underlying sequence, and a default sentinel can be used with them. 48 * For example, a `std::counted_iterator` keeps a count of how many elements 49 * remain, and so checking for the past-the-end value only requires checking 50 * if that count has reached zero. A past-the-end `std::istream_iterator` is 51 * equal to the default-constructed value, which can be easily checked. 52 * 53 * Comparing iterators of these types to `std::default_sentinel` is a 54 * convenient way to check if the end has been reached. 55 * 56 * @since C++20 57 */ 58 struct default_sentinel_t { }; 59 60 /// A default sentinel value. 61 inline constexpr default_sentinel_t default_sentinel{}; 62 63 #if __cpp_lib_concepts 64 struct input_iterator_tag; 65 struct output_iterator_tag; 66 struct forward_iterator_tag; 67 struct bidirectional_iterator_tag; 68 struct random_access_iterator_tag; 69 struct contiguous_iterator_tag; 70 71 template
72 struct iterator_traits; 73 74 template
requires is_object_v<_Tp> 75 struct iterator_traits<_Tp*>; 76 77 template
78 struct __iterator_traits; 79 80 namespace __detail 81 { 82 template
83 using __with_ref = _Tp&; 84 85 template
86 concept __can_reference = requires { typename __with_ref<_Tp>; }; 87 88 template
89 concept __dereferenceable = requires(_Tp& __t) 90 { 91 { *__t } -> __can_reference; 92 }; 93 } // namespace __detail 94 95 template<__detail::__dereferenceable _Tp> 96 using iter_reference_t = decltype(*std::declval<_Tp&>()); 97 98 namespace ranges 99 { 100 namespace __cust_imove 101 { 102 void iter_move(); 103 104 template
105 concept __adl_imove 106 = (std::__detail::__class_or_enum
>) 107 && requires(_Tp&& __t) { iter_move(static_cast<_Tp&&>(__t)); }; 108 109 struct _IMove 110 { 111 private: 112 template
113 struct __result 114 { using type = iter_reference_t<_Tp>; }; 115 116 template
117 requires __adl_imove<_Tp> 118 struct __result<_Tp> 119 { using type = decltype(iter_move(std::declval<_Tp>())); }; 120 121 template
122 requires (!__adl_imove<_Tp>) 123 && is_lvalue_reference_v
> 124 struct __result<_Tp> 125 { using type = remove_reference_t
>&&; }; 126 127 template
128 static constexpr bool 129 _S_noexcept() 130 { 131 if constexpr (__adl_imove<_Tp>) 132 return noexcept(iter_move(std::declval<_Tp>())); 133 else 134 return noexcept(*std::declval<_Tp>()); 135 } 136 137 public: 138 // The result type of iter_move(std::declval<_Tp>()) 139 template
140 using __type = typename __result<_Tp>::type; 141 142 template
143 [[nodiscard]] 144 constexpr __type<_Tp> 145 operator()(_Tp&& __e) const 146 noexcept(_S_noexcept<_Tp>()) 147 { 148 if constexpr (__adl_imove<_Tp>) 149 return iter_move(static_cast<_Tp&&>(__e)); 150 else if constexpr (is_lvalue_reference_v
>) 151 return static_cast<__type<_Tp>>(*__e); 152 else 153 return *__e; 154 } 155 }; 156 } // namespace __cust_imove 157 158 inline namespace __cust 159 { 160 inline constexpr __cust_imove::_IMove iter_move{}; 161 } // inline namespace __cust 162 } // namespace ranges 163 164 template<__detail::__dereferenceable _Tp> 165 requires __detail:: 166 __can_reference
> 167 using iter_rvalue_reference_t 168 = ranges::__cust_imove::_IMove::__type<_Tp&>; 169 170 template
struct incrementable_traits { }; 171 172 template
requires is_object_v<_Tp> 173 struct incrementable_traits<_Tp*> 174 { using difference_type = ptrdiff_t; }; 175 176 template
177 struct incrementable_traits
178 : incrementable_traits<_Iter> { }; 179 180 template
requires requires { typename _Tp::difference_type; } 181 struct incrementable_traits<_Tp> 182 { using difference_type = typename _Tp::difference_type; }; 183 184 template
185 requires (!requires { typename _Tp::difference_type; } 186 && requires(const _Tp& __a, const _Tp& __b) 187 { { __a - __b } -> integral; }) 188 struct incrementable_traits<_Tp> 189 { 190 using difference_type 191 = make_signed_t
() - std::declval<_Tp>())>; 192 }; 193 194 #if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ 195 // __int128 is incrementable even if !integral<__int128> 196 template<> 197 struct incrementable_traits<__int128> 198 { using difference_type = __int128; }; 199 200 template<> 201 struct incrementable_traits
202 { using difference_type = __int128; }; 203 #endif 204 205 namespace __detail 206 { 207 // An iterator such that iterator_traits<_Iter> names a specialization 208 // generated from the primary template. 209 template
210 concept __primary_traits_iter 211 = __is_base_of(__iterator_traits<_Iter, void>, iterator_traits<_Iter>); 212 213 template
214 struct __iter_traits_impl 215 { using type = iterator_traits<_Iter>; }; 216 217 template
218 requires __primary_traits_iter<_Iter> 219 struct __iter_traits_impl<_Iter, _Tp> 220 { using type = _Tp; }; 221 222 // ITER_TRAITS 223 template
224 using __iter_traits = typename __iter_traits_impl<_Iter, _Tp>::type; 225 226 template
227 using __iter_diff_t = typename 228 __iter_traits<_Tp, incrementable_traits<_Tp>>::difference_type; 229 } // namespace __detail 230 231 template
232 using iter_difference_t = __detail::__iter_diff_t
>; 233 234 namespace __detail 235 { 236 template
struct __cond_value_type { }; 237 238 template
requires is_object_v<_Tp> 239 struct __cond_value_type<_Tp> 240 { using value_type = remove_cv_t<_Tp>; }; 241 242 template
243 concept __has_member_value_type 244 = requires { typename _Tp::value_type; }; 245 246 template
247 concept __has_member_element_type 248 = requires { typename _Tp::element_type; }; 249 250 } // namespace __detail 251 252 template
struct indirectly_readable_traits { }; 253 254 template
255 struct indirectly_readable_traits<_Tp*> 256 : __detail::__cond_value_type<_Tp> 257 { }; 258 259 template
requires is_array_v<_Iter> 260 struct indirectly_readable_traits<_Iter> 261 { using value_type = remove_cv_t
>; }; 262 263 template
264 struct indirectly_readable_traits
265 : indirectly_readable_traits<_Iter> 266 { }; 267 268 template<__detail::__has_member_value_type _Tp> 269 struct indirectly_readable_traits<_Tp> 270 : __detail::__cond_value_type
271 { }; 272 273 template<__detail::__has_member_element_type _Tp> 274 struct indirectly_readable_traits<_Tp> 275 : __detail::__cond_value_type
276 { }; 277 278 // _GLIBCXX_RESOLVE_LIB_DEFECTS 279 // 3446. indirectly_readable_traits ambiguity for types with both [...] 280 template<__detail::__has_member_value_type _Tp> 281 requires __detail::__has_member_element_type<_Tp> 282 && same_as
, 283 remove_cv_t
> 284 struct indirectly_readable_traits<_Tp> 285 : __detail::__cond_value_type
286 { }; 287 288 // _GLIBCXX_RESOLVE_LIB_DEFECTS 289 // 3541. indirectly_readable_traits should be SFINAE-friendly for all types 290 template<__detail::__has_member_value_type _Tp> 291 requires __detail::__has_member_element_type<_Tp> 292 struct indirectly_readable_traits<_Tp> 293 { }; 294 295 namespace __detail 296 { 297 template
298 using __iter_value_t = typename 299 __iter_traits<_Tp, indirectly_readable_traits<_Tp>>::value_type; 300 } // namespace __detail 301 302 template
303 using iter_value_t = __detail::__iter_value_t
>; 304 305 namespace __detail 306 { 307 // _GLIBCXX_RESOLVE_LIB_DEFECTS 308 // 3420. cpp17-iterator should check [type] looks like an iterator first 309 template
310 concept __cpp17_iterator = requires(_Iter __it) 311 { 312 { *__it } -> __can_reference; 313 { ++__it } -> same_as<_Iter&>; 314 { *__it++ } -> __can_reference; 315 } && copyable<_Iter>; 316 317 template
318 concept __cpp17_input_iterator = __cpp17_iterator<_Iter> 319 && equality_comparable<_Iter> 320 && requires(_Iter __it) 321 { 322 typename incrementable_traits<_Iter>::difference_type; 323 typename indirectly_readable_traits<_Iter>::value_type; 324 typename common_reference_t
&&, 325 typename indirectly_readable_traits<_Iter>::value_type&>; 326 typename common_reference_t
::value_type&>; 328 requires signed_integral< 329 typename incrementable_traits<_Iter>::difference_type>; 330 }; 331 332 template
333 concept __cpp17_fwd_iterator = __cpp17_input_iterator<_Iter> 334 && constructible_from<_Iter> 335 && is_lvalue_reference_v
> 336 && same_as
>, 337 typename indirectly_readable_traits<_Iter>::value_type> 338 && requires(_Iter __it) 339 { 340 { __it++ } -> convertible_to
; 341 { *__it++ } -> same_as
>; 342 }; 343 344 template
345 concept __cpp17_bidi_iterator = __cpp17_fwd_iterator<_Iter> 346 && requires(_Iter __it) 347 { 348 { --__it } -> same_as<_Iter&>; 349 { __it-- } -> convertible_to
; 350 { *__it-- } -> same_as
>; 351 }; 352 353 template
354 concept __cpp17_randacc_iterator = __cpp17_bidi_iterator<_Iter> 355 && totally_ordered<_Iter> 356 && requires(_Iter __it, 357 typename incrementable_traits<_Iter>::difference_type __n) 358 { 359 { __it += __n } -> same_as<_Iter&>; 360 { __it -= __n } -> same_as<_Iter&>; 361 { __it + __n } -> same_as<_Iter>; 362 { __n + __it } -> same_as<_Iter>; 363 { __it - __n } -> same_as<_Iter>; 364 { __it - __it } -> same_as
; 365 { __it[__n] } -> convertible_to
>; 366 }; 367 368 template
369 concept __iter_with_nested_types = requires { 370 typename _Iter::iterator_category; 371 typename _Iter::value_type; 372 typename _Iter::difference_type; 373 typename _Iter::reference; 374 }; 375 376 template
377 concept __iter_without_nested_types = !__iter_with_nested_types<_Iter>; 378 379 template
380 concept __iter_without_category 381 = !requires { typename _Iter::iterator_category; }; 382 383 } // namespace __detail 384 385 template
386 requires __detail::__iter_with_nested_types<_Iterator> 387 struct __iterator_traits<_Iterator, void> 388 { 389 private: 390 template
391 struct __ptr 392 { using type = void; }; 393 394 template
requires requires { typename _Iter::pointer; } 395 struct __ptr<_Iter> 396 { using type = typename _Iter::pointer; }; 397 398 public: 399 using iterator_category = typename _Iterator::iterator_category; 400 using value_type = typename _Iterator::value_type; 401 using difference_type = typename _Iterator::difference_type; 402 using pointer = typename __ptr<_Iterator>::type; 403 using reference = typename _Iterator::reference; 404 }; 405 406 template
407 requires __detail::__iter_without_nested_types<_Iterator> 408 && __detail::__cpp17_input_iterator<_Iterator> 409 struct __iterator_traits<_Iterator, void> 410 { 411 private: 412 template
413 struct __cat 414 { using type = input_iterator_tag; }; 415 416 template
417 requires requires { typename _Iter::iterator_category; } 418 struct __cat<_Iter> 419 { using type = typename _Iter::iterator_category; }; 420 421 template
422 requires __detail::__iter_without_category<_Iter> 423 && __detail::__cpp17_randacc_iterator<_Iter> 424 struct __cat<_Iter> 425 { using type = random_access_iterator_tag; }; 426 427 template
428 requires __detail::__iter_without_category<_Iter> 429 && __detail::__cpp17_bidi_iterator<_Iter> 430 struct __cat<_Iter> 431 { using type = bidirectional_iterator_tag; }; 432 433 template
434 requires __detail::__iter_without_category<_Iter> 435 && __detail::__cpp17_fwd_iterator<_Iter> 436 struct __cat<_Iter> 437 { using type = forward_iterator_tag; }; 438 439 template
440 struct __ptr 441 { using type = void; }; 442 443 template
requires requires { typename _Iter::pointer; } 444 struct __ptr<_Iter> 445 { using type = typename _Iter::pointer; }; 446 447 template
448 requires (!requires { typename _Iter::pointer; } 449 && requires(_Iter& __it) { __it.operator->(); }) 450 struct __ptr<_Iter> 451 { using type = decltype(std::declval<_Iter&>().operator->()); }; 452 453 template
454 struct __ref 455 { using type = iter_reference_t<_Iter>; }; 456 457 template
requires requires { typename _Iter::reference; } 458 struct __ref<_Iter> 459 { using type = typename _Iter::reference; }; 460 461 public: 462 using iterator_category = typename __cat<_Iterator>::type; 463 using value_type 464 = typename indirectly_readable_traits<_Iterator>::value_type; 465 using difference_type 466 = typename incrementable_traits<_Iterator>::difference_type; 467 using pointer = typename __ptr<_Iterator>::type; 468 using reference = typename __ref<_Iterator>::type; 469 }; 470 471 template
472 requires __detail::__iter_without_nested_types<_Iterator> 473 && __detail::__cpp17_iterator<_Iterator> 474 struct __iterator_traits<_Iterator, void> 475 { 476 private: 477 template
478 struct __diff 479 { using type = void; }; 480 481 template
482 requires requires 483 { typename incrementable_traits<_Iter>::difference_type; } 484 struct __diff<_Iter> 485 { 486 using type = typename incrementable_traits<_Iter>::difference_type; 487 }; 488 489 public: 490 using iterator_category = output_iterator_tag; 491 using value_type = void; 492 using difference_type = typename __diff<_Iterator>::type; 493 using pointer = void; 494 using reference = void; 495 }; 496 497 namespace __detail 498 { 499 template
500 struct __iter_concept_impl; 501 502 // ITER_CONCEPT(I) is ITER_TRAITS(I)::iterator_concept if that is valid. 503 template
504 requires requires { typename __iter_traits<_Iter>::iterator_concept; } 505 struct __iter_concept_impl<_Iter> 506 { using type = typename __iter_traits<_Iter>::iterator_concept; }; 507 508 // Otherwise, ITER_TRAITS(I)::iterator_category if that is valid. 509 template
510 requires (!requires { typename __iter_traits<_Iter>::iterator_concept; } 511 && requires { typename __iter_traits<_Iter>::iterator_category; }) 512 struct __iter_concept_impl<_Iter> 513 { using type = typename __iter_traits<_Iter>::iterator_category; }; 514 515 // Otherwise, random_access_tag if iterator_traits
is not specialized. 516 template
517 requires (!requires { typename __iter_traits<_Iter>::iterator_concept; } 518 && !requires { typename __iter_traits<_Iter>::iterator_category; } 519 && __primary_traits_iter<_Iter>) 520 struct __iter_concept_impl<_Iter> 521 { using type = random_access_iterator_tag; }; 522 523 // Otherwise, there is no ITER_CONCEPT(I) type. 524 template
525 struct __iter_concept_impl 526 { }; 527 528 // ITER_CONCEPT 529 template
530 using __iter_concept = typename __iter_concept_impl<_Iter>::type; 531 532 template
533 concept __indirectly_readable_impl = requires 534 { 535 typename iter_value_t<_In>; 536 typename iter_reference_t<_In>; 537 typename iter_rvalue_reference_t<_In>; 538 requires same_as
, 539 iter_reference_t<_In>>; 540 requires same_as
, 541 iter_rvalue_reference_t<_In>>; 542 } 543 && common_reference_with
&&, iter_value_t<_In>&> 544 && common_reference_with
&&, 545 iter_rvalue_reference_t<_In>&&> 546 && common_reference_with
&&, 547 const iter_value_t<_In>&>; 548 549 } // namespace __detail 550 551 /// Requirements for types that are readable by applying operator*. 552 template
553 concept indirectly_readable 554 = __detail::__indirectly_readable_impl
>; 555 556 template
557 using iter_common_reference_t 558 = common_reference_t
, iter_value_t<_Tp>&>; 559 560 /// Requirements for writing a value into an iterator's referenced object. 561 template
562 concept indirectly_writable = requires(_Out&& __o, _Tp&& __t) 563 { 564 *__o = std::forward<_Tp>(__t); 565 *std::forward<_Out>(__o) = std::forward<_Tp>(__t); 566 const_cast
&&>(*__o) 567 = std::forward<_Tp>(__t); 568 const_cast
&&>(*std::forward<_Out>(__o)) 569 = std::forward<_Tp>(__t); 570 }; 571 572 namespace ranges::__detail 573 { 574 class __max_diff_type; 575 class __max_size_type; 576 577 __extension__ 578 template
579 concept __is_signed_int128 580 #if __SIZEOF_INT128__ 581 = same_as<_Tp, __int128>; 582 #else 583 = false; 584 #endif 585 586 __extension__ 587 template
588 concept __is_unsigned_int128 589 #if __SIZEOF_INT128__ 590 = same_as<_Tp, unsigned __int128>; 591 #else 592 = false; 593 #endif 594 595 template
596 concept __cv_bool = same_as
; 597 598 template
599 concept __integral_nonbool = integral<_Tp> && !__cv_bool<_Tp>; 600 601 template
602 concept __is_int128 = __is_signed_int128<_Tp> || __is_unsigned_int128<_Tp>; 603 604 template
605 concept __is_integer_like = __integral_nonbool<_Tp> 606 || __is_int128<_Tp> 607 || same_as<_Tp, __max_diff_type> || same_as<_Tp, __max_size_type>; 608 609 template
610 concept __is_signed_integer_like = signed_integral<_Tp> 611 || __is_signed_int128<_Tp> 612 || same_as<_Tp, __max_diff_type>; 613 614 } // namespace ranges::__detail 615 616 namespace __detail { using ranges::__detail::__is_signed_integer_like; } 617 618 /// Requirements on types that can be incremented with ++. 619 template
620 concept weakly_incrementable = movable<_Iter> 621 && requires(_Iter __i) 622 { 623 typename iter_difference_t<_Iter>; 624 requires __detail::__is_signed_integer_like
>; 625 { ++__i } -> same_as<_Iter&>; 626 __i++; 627 }; 628 629 template
630 concept incrementable = regular<_Iter> && weakly_incrementable<_Iter> 631 && requires(_Iter __i) { { __i++ } -> same_as<_Iter>; }; 632 633 template
634 concept input_or_output_iterator 635 = requires(_Iter __i) { { *__i } -> __detail::__can_reference; } 636 && weakly_incrementable<_Iter>; 637 638 template
639 concept sentinel_for = semiregular<_Sent> 640 && input_or_output_iterator<_Iter> 641 && __detail::__weakly_eq_cmp_with<_Sent, _Iter>; 642 643 template
644 inline constexpr bool disable_sized_sentinel_for = false; 645 646 template
647 concept sized_sentinel_for = sentinel_for<_Sent, _Iter> 648 && !disable_sized_sentinel_for
, remove_cv_t<_Iter>> 649 && requires(const _Iter& __i, const _Sent& __s) 650 { 651 { __s - __i } -> same_as
>; 652 { __i - __s } -> same_as
>; 653 }; 654 655 template
656 concept input_iterator = input_or_output_iterator<_Iter> 657 && indirectly_readable<_Iter> 658 && requires { typename __detail::__iter_concept<_Iter>; } 659 && derived_from<__detail::__iter_concept<_Iter>, input_iterator_tag>; 660 661 template
662 concept output_iterator = input_or_output_iterator<_Iter> 663 && indirectly_writable<_Iter, _Tp> 664 && requires(_Iter __i, _Tp&& __t) { *__i++ = std::forward<_Tp>(__t); }; 665 666 template
667 concept forward_iterator = input_iterator<_Iter> 668 && derived_from<__detail::__iter_concept<_Iter>, forward_iterator_tag> 669 && incrementable<_Iter> && sentinel_for<_Iter, _Iter>; 670 671 template
672 concept bidirectional_iterator = forward_iterator<_Iter> 673 && derived_from<__detail::__iter_concept<_Iter>, 674 bidirectional_iterator_tag> 675 && requires(_Iter __i) 676 { 677 { --__i } -> same_as<_Iter&>; 678 { __i-- } -> same_as<_Iter>; 679 }; 680 681 template
682 concept random_access_iterator = bidirectional_iterator<_Iter> 683 && derived_from<__detail::__iter_concept<_Iter>, 684 random_access_iterator_tag> 685 && totally_ordered<_Iter> && sized_sentinel_for<_Iter, _Iter> 686 && requires(_Iter __i, const _Iter __j, 687 const iter_difference_t<_Iter> __n) 688 { 689 { __i += __n } -> same_as<_Iter&>; 690 { __j + __n } -> same_as<_Iter>; 691 { __n + __j } -> same_as<_Iter>; 692 { __i -= __n } -> same_as<_Iter&>; 693 { __j - __n } -> same_as<_Iter>; 694 { __j[__n] } -> same_as
>; 695 }; 696 697 template
698 concept contiguous_iterator = random_access_iterator<_Iter> 699 && derived_from<__detail::__iter_concept<_Iter>, contiguous_iterator_tag> 700 && is_lvalue_reference_v
> 701 && same_as
, remove_cvref_t
>> 702 && requires(const _Iter& __i) 703 { 704 { std::to_address(__i) } 705 -> same_as
>>; 706 }; 707 708 // [indirectcallable], indirect callable requirements 709 710 // [indirectcallable.indirectinvocable], indirect callables 711 712 template
713 concept indirectly_unary_invocable = indirectly_readable<_Iter> 714 && copy_constructible<_Fn> && invocable<_Fn&, iter_value_t<_Iter>&> 715 && invocable<_Fn&, iter_reference_t<_Iter>> 716 && invocable<_Fn&, iter_common_reference_t<_Iter>> 717 && common_reference_with
&>, 718 invoke_result_t<_Fn&, iter_reference_t<_Iter>>>; 719 720 template
721 concept indirectly_regular_unary_invocable = indirectly_readable<_Iter> 722 && copy_constructible<_Fn> 723 && regular_invocable<_Fn&, iter_value_t<_Iter>&> 724 && regular_invocable<_Fn&, iter_reference_t<_Iter>> 725 && regular_invocable<_Fn&, iter_common_reference_t<_Iter>> 726 && common_reference_with
&>, 727 invoke_result_t<_Fn&, iter_reference_t<_Iter>>>; 728 729 template
730 concept indirect_unary_predicate = indirectly_readable<_Iter> 731 && copy_constructible<_Fn> && predicate<_Fn&, iter_value_t<_Iter>&> 732 && predicate<_Fn&, iter_reference_t<_Iter>> 733 && predicate<_Fn&, iter_common_reference_t<_Iter>>; 734 735 template
736 concept indirect_binary_predicate 737 = indirectly_readable<_I1> && indirectly_readable<_I2> 738 && copy_constructible<_Fn> 739 && predicate<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&> 740 && predicate<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>> 741 && predicate<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&> 742 && predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>> 743 && predicate<_Fn&, iter_common_reference_t<_I1>, 744 iter_common_reference_t<_I2>>; 745 746 template
747 concept indirect_equivalence_relation 748 = indirectly_readable<_I1> && indirectly_readable<_I2> 749 && copy_constructible<_Fn> 750 && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&> 751 && equivalence_relation<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>> 752 && equivalence_relation<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&> 753 && equivalence_relation<_Fn&, iter_reference_t<_I1>, 754 iter_reference_t<_I2>> 755 && equivalence_relation<_Fn&, iter_common_reference_t<_I1>, 756 iter_common_reference_t<_I2>>; 757 758 template
759 concept indirect_strict_weak_order 760 = indirectly_readable<_I1> && indirectly_readable<_I2> 761 && copy_constructible<_Fn> 762 && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_value_t<_I2>&> 763 && strict_weak_order<_Fn&, iter_value_t<_I1>&, iter_reference_t<_I2>> 764 && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_value_t<_I2>&> 765 && strict_weak_order<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>> 766 && strict_weak_order<_Fn&, iter_common_reference_t<_I1>, 767 iter_common_reference_t<_I2>>; 768 769 template
770 requires (indirectly_readable<_Is> && ...) 771 && invocable<_Fn, iter_reference_t<_Is>...> 772 using indirect_result_t = invoke_result_t<_Fn, iter_reference_t<_Is>...>; 773 774 namespace __detail 775 { 776 template
777 struct __projected 778 { 779 struct __type 780 { 781 using value_type = remove_cvref_t
>; 782 indirect_result_t<_Proj&, _Iter> operator*() const; // not defined 783 }; 784 }; 785 786 template
787 struct __projected<_Iter, _Proj> 788 { 789 struct __type 790 { 791 using value_type = remove_cvref_t
>; 792 using difference_type = iter_difference_t<_Iter>; 793 indirect_result_t<_Proj&, _Iter> operator*() const; // not defined 794 }; 795 }; 796 } // namespace __detail 797 798 /// [projected], projected 799 template
_Proj> 801 using projected = typename __detail::__projected<_Iter, _Proj>::__type; 802 803 // [alg.req], common algorithm requirements 804 805 /// [alg.req.ind.move], concept `indirectly_movable` 806 807 template
808 concept indirectly_movable = indirectly_readable<_In> 809 && indirectly_writable<_Out, iter_rvalue_reference_t<_In>>; 810 811 template
812 concept indirectly_movable_storable = indirectly_movable<_In, _Out> 813 && indirectly_writable<_Out, iter_value_t<_In>> 814 && movable
> 815 && constructible_from
, iter_rvalue_reference_t<_In>> 816 && assignable_from
&, iter_rvalue_reference_t<_In>>; 817 818 /// [alg.req.ind.copy], concept `indirectly_copyable` 819 template
820 concept indirectly_copyable = indirectly_readable<_In> 821 && indirectly_writable<_Out, iter_reference_t<_In>>; 822 823 template
824 concept indirectly_copyable_storable = indirectly_copyable<_In, _Out> 825 && indirectly_writable<_Out, iter_value_t<_In>&> 826 && indirectly_writable<_Out, const iter_value_t<_In>&> 827 && indirectly_writable<_Out, iter_value_t<_In>&&> 828 && indirectly_writable<_Out, const iter_value_t<_In>&&> 829 && copyable
> 830 && constructible_from
, iter_reference_t<_In>> 831 && assignable_from
&, iter_reference_t<_In>>; 832 833 namespace ranges 834 { 835 namespace __cust_iswap 836 { 837 template
838 void iter_swap(_It1, _It2) = delete; 839 840 template
841 concept __adl_iswap 842 = (std::__detail::__class_or_enum
> 843 || std::__detail::__class_or_enum
>) 844 && requires(_Tp&& __t, _Up&& __u) { 845 iter_swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u)); 846 }; 847 848 template
849 constexpr iter_value_t<_Xp> 850 __iter_exchange_move(_Xp&& __x, _Yp&& __y) 851 noexcept(noexcept(iter_value_t<_Xp>(iter_move(__x))) 852 && noexcept(*__x = iter_move(__y))) 853 { 854 iter_value_t<_Xp> __old_value(iter_move(__x)); 855 *__x = iter_move(__y); 856 return __old_value; 857 } 858 859 struct _IterSwap 860 { 861 private: 862 template
863 static constexpr bool 864 _S_noexcept() 865 { 866 if constexpr (__adl_iswap<_Tp, _Up>) 867 return noexcept(iter_swap(std::declval<_Tp>(), 868 std::declval<_Up>())); 869 else if constexpr (indirectly_readable<_Tp> 870 && indirectly_readable<_Up> 871 && swappable_with
, iter_reference_t<_Up>>) 872 return noexcept(ranges::swap(*std::declval<_Tp>(), 873 *std::declval<_Up>())); 874 else 875 return noexcept(*std::declval<_Tp>() 876 = __iter_exchange_move(std::declval<_Up>(), 877 std::declval<_Tp>())); 878 } 879 880 public: 881 template
882 requires __adl_iswap<_Tp, _Up> 883 || (indirectly_readable
> 884 && indirectly_readable
> 885 && swappable_with
, iter_reference_t<_Up>>) 886 || (indirectly_movable_storable<_Tp, _Up> 887 && indirectly_movable_storable<_Up, _Tp>) 888 constexpr void 889 operator()(_Tp&& __e1, _Up&& __e2) const 890 noexcept(_S_noexcept<_Tp, _Up>()) 891 { 892 if constexpr (__adl_iswap<_Tp, _Up>) 893 iter_swap(static_cast<_Tp&&>(__e1), static_cast<_Up&&>(__e2)); 894 else if constexpr (indirectly_readable<_Tp> 895 && indirectly_readable<_Up> 896 && swappable_with
, iter_reference_t<_Up>>) 897 ranges::swap(*__e1, *__e2); 898 else 899 *__e1 = __iter_exchange_move(__e2, __e1); 900 } 901 }; 902 } // namespace __cust_iswap 903 904 inline namespace __cust 905 { 906 inline constexpr __cust_iswap::_IterSwap iter_swap{}; 907 } // inline namespace __cust 908 909 } // namespace ranges 910 911 /// [alg.req.ind.swap], concept `indirectly_swappable` 912 template
913 concept indirectly_swappable 914 = indirectly_readable<_I1> && indirectly_readable<_I2> 915 && requires(const _I1 __i1, const _I2 __i2) 916 { 917 ranges::iter_swap(__i1, __i1); 918 ranges::iter_swap(__i2, __i2); 919 ranges::iter_swap(__i1, __i2); 920 ranges::iter_swap(__i2, __i1); 921 }; 922 923 /// [alg.req.ind.cmp], concept `indirectly_comparable` 924 template
926 concept indirectly_comparable 927 = indirect_binary_predicate<_Rel, projected<_I1, _P1>, 928 projected<_I2, _P2>>; 929 930 /// [alg.req.permutable], concept `permutable` 931 template
932 concept permutable = forward_iterator<_Iter> 933 && indirectly_movable_storable<_Iter, _Iter> 934 && indirectly_swappable<_Iter, _Iter>; 935 936 /// [alg.req.mergeable], concept `mergeable` 937 template
940 concept mergeable = input_iterator<_I1> && input_iterator<_I2> 941 && weakly_incrementable<_Out> && indirectly_copyable<_I1, _Out> 942 && indirectly_copyable<_I2, _Out> 943 && indirect_strict_weak_order<_Rel, projected<_I1, _P1>, 944 projected<_I2, _P2>>; 945 946 /// [alg.req.sortable], concept `sortable` 947 template
949 concept sortable = permutable<_Iter> 950 && indirect_strict_weak_order<_Rel, projected<_Iter, _Proj>>; 951 952 struct unreachable_sentinel_t 953 { 954 template
955 friend constexpr bool 956 operator==(unreachable_sentinel_t, const _It&) noexcept 957 { return false; } 958 }; 959 960 inline constexpr unreachable_sentinel_t unreachable_sentinel{}; 961 962 // This is the namespace for [range.access] CPOs. 963 namespace ranges::__cust_access 964 { 965 using std::__detail::__class_or_enum; 966 967 struct _Decay_copy final 968 { 969 template
970 constexpr decay_t<_Tp> 971 operator()(_Tp&& __t) const 972 noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>) 973 { return std::forward<_Tp>(__t); } 974 } inline constexpr __decay_copy{}; 975 976 template
977 concept __member_begin = requires(_Tp& __t) 978 { 979 { __decay_copy(__t.begin()) } -> input_or_output_iterator; 980 }; 981 982 // Poison pills so that unqualified lookup doesn't find std::begin. 983 void begin(auto&) = delete; 984 void begin(const auto&) = delete; 985 986 template
987 concept __adl_begin = __class_or_enum
> 988 && requires(_Tp& __t) 989 { 990 { __decay_copy(begin(__t)) } -> input_or_output_iterator; 991 }; 992 993 // Simplified version of std::ranges::begin that only supports lvalues, 994 // for use by __range_iter_t below. 995 template
996 requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&> 997 auto 998 __begin(_Tp& __t) 999 { 1000 if constexpr (is_array_v<_Tp>) 1001 return __t + 0; 1002 else if constexpr (__member_begin<_Tp&>) 1003 return __t.begin(); 1004 else 1005 return begin(__t); 1006 } 1007 } // namespace ranges::__cust_access 1008 1009 namespace __detail 1010 { 1011 // Implementation of std::ranges::iterator_t, without using ranges::begin. 1012 template
1013 using __range_iter_t 1014 = decltype(ranges::__cust_access::__begin(std::declval<_Tp&>())); 1015 1016 } // namespace __detail 1017 1018 #endif // C++20 library concepts 1019 _GLIBCXX_END_NAMESPACE_VERSION 1020 } // namespace std 1021 #endif // C++20 1022 #endif // _ITERATOR_CONCEPTS_H
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™