30 #ifndef _GLIBCXX_RANGE_ACCESS_H
31 #define _GLIBCXX_RANGE_ACCESS_H 1
33 #pragma GCC system_header
35 #if __cplusplus >= 201103L
40 namespace std _GLIBCXX_VISIBILITY(default)
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49 template<
typename _Container>
50 inline _GLIBCXX17_CONSTEXPR
auto
51 begin(_Container& __cont) -> decltype(__cont.begin())
52 {
return __cont.begin(); }
59 template<
typename _Container>
60 inline _GLIBCXX17_CONSTEXPR
auto
61 begin(
const _Container& __cont) -> decltype(__cont.begin())
62 {
return __cont.begin(); }
69 template<
typename _Container>
70 inline _GLIBCXX17_CONSTEXPR
auto
71 end(_Container& __cont) -> decltype(__cont.end())
72 {
return __cont.end(); }
79 template<
typename _Container>
80 inline _GLIBCXX17_CONSTEXPR
auto
81 end(
const _Container& __cont) -> decltype(__cont.end())
82 {
return __cont.end(); }
88 template<
typename _Tp,
size_t _Nm>
89 inline _GLIBCXX14_CONSTEXPR _Tp*
98 template<
typename _Tp,
size_t _Nm>
99 inline _GLIBCXX14_CONSTEXPR _Tp*
101 {
return __arr + _Nm; }
103 #if __cplusplus >= 201402L
105 template<
typename _Tp>
class valarray;
107 template<
typename _Tp> _Tp*
begin(valarray<_Tp>&);
108 template<
typename _Tp>
const _Tp*
begin(
const valarray<_Tp>&);
109 template<
typename _Tp> _Tp*
end(valarray<_Tp>&);
110 template<
typename _Tp>
const _Tp*
end(
const valarray<_Tp>&);
117 template<
typename _Container>
118 inline constexpr
auto
128 template<
typename _Container>
129 inline constexpr
auto
139 template<
typename _Container>
140 inline _GLIBCXX17_CONSTEXPR
auto
141 rbegin(_Container& __cont) -> decltype(__cont.rbegin())
142 {
return __cont.rbegin(); }
149 template<
typename _Container>
150 inline _GLIBCXX17_CONSTEXPR
auto
151 rbegin(
const _Container& __cont) -> decltype(__cont.rbegin())
152 {
return __cont.rbegin(); }
159 template<
typename _Container>
160 inline _GLIBCXX17_CONSTEXPR
auto
161 rend(_Container& __cont) -> decltype(__cont.rend())
162 {
return __cont.rend(); }
169 template<
typename _Container>
170 inline _GLIBCXX17_CONSTEXPR
auto
171 rend(
const _Container& __cont) -> decltype(__cont.rend())
172 {
return __cont.rend(); }
179 template<
typename _Tp,
size_t _Nm>
180 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
189 template<
typename _Tp,
size_t _Nm>
190 inline _GLIBCXX17_CONSTEXPR reverse_iterator<_Tp*>
199 template<
typename _Tp>
200 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
209 template<
typename _Tp>
210 inline _GLIBCXX17_CONSTEXPR reverse_iterator<const _Tp*>
219 template<
typename _Container>
220 inline _GLIBCXX17_CONSTEXPR
auto
229 template<
typename _Container>
230 inline _GLIBCXX17_CONSTEXPR
auto
236 #if __cplusplus >= 201703L
237 #define __cpp_lib_nonmember_container_access 201411
243 template <
typename _Container>
245 size(
const _Container& __cont) noexcept(noexcept(__cont.size()))
246 -> decltype(__cont.size())
247 {
return __cont.size(); }
252 template <
typename _Tp,
size_t _Nm>
254 size(
const _Tp (&)[_Nm]) noexcept
261 template <
typename _Container>
262 [[nodiscard]] constexpr
auto
263 empty(
const _Container& __cont) noexcept(noexcept(__cont.empty()))
264 -> decltype(__cont.empty())
265 {
return __cont.empty(); }
270 template <
typename _Tp,
size_t _Nm>
271 [[nodiscard]] constexpr
bool
272 empty(
const _Tp (&)[_Nm]) noexcept
279 template <
typename _Tp>
280 [[nodiscard]] constexpr
bool
281 empty(initializer_list<_Tp> __il) noexcept
282 {
return __il.size() == 0;}
288 template <
typename _Container>
290 data(_Container& __cont) noexcept(noexcept(__cont.data()))
291 -> decltype(__cont.data())
292 {
return __cont.data(); }
298 template <
typename _Container>
300 data(
const _Container& __cont) noexcept(noexcept(__cont.data()))
301 -> decltype(__cont.data())
302 {
return __cont.data(); }
308 template <
typename _Tp,
size_t _Nm>
310 data(_Tp (&__array)[_Nm]) noexcept
317 template <
typename _Tp>
319 data(initializer_list<_Tp> __il) noexcept
320 {
return __il.begin(); }
324 #if __cplusplus > 201703L
325 template<
typename _Container>
327 ssize(
const _Container& __cont)
328 noexcept(noexcept(__cont.size()))
332 return static_cast<common_type_t<ptrdiff_t, type>
>(__cont.size());
335 template<
typename _Tp, ptrdiff_t _Num>
337 ssize(
const _Tp (&)[_Num]) noexcept
340 #ifdef __cpp_lib_concepts
344 inline constexpr
bool disable_sized_range =
false;
346 template<
typename _Tp>
347 inline constexpr
bool enable_borrowed_range =
false;
351 template<
integral _Tp>
352 constexpr make_unsigned_t<_Tp>
353 __to_unsigned_like(_Tp __t) noexcept
356 template<
typename _Tp,
bool _MaxDiff = same_as<_Tp, __max_diff_type>>
357 using __make_unsigned_like_t
358 = conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>;
361 template<
typename _Tp>
362 concept __maybe_borrowed_range
363 = is_lvalue_reference_v<_Tp>
364 || enable_borrowed_range<remove_cvref_t<_Tp>>;
368 namespace __cust_access
370 using std::ranges::__detail::__maybe_borrowed_range;
371 using std::__detail::__class_or_enum;
373 template<
typename _Tp>
374 constexpr decay_t<_Tp>
375 __decay_copy(_Tp&& __t)
376 noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>)
377 {
return std::forward<_Tp>(__t); }
379 template<
typename _Tp>
380 concept __member_begin = requires(_Tp& __t)
382 { __decay_copy(__t.begin()) } -> input_or_output_iterator;
385 void begin(
auto&) =
delete;
386 void begin(
const auto&) =
delete;
388 template<
typename _Tp>
389 concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>>
390 && requires(_Tp& __t)
392 { __decay_copy(
begin(__t)) } -> input_or_output_iterator;
398 template<
typename _Tp>
399 static constexpr
bool
402 if constexpr (is_array_v<remove_reference_t<_Tp>>)
404 else if constexpr (__member_begin<_Tp>)
405 return noexcept(__decay_copy(
std::declval<_Tp&>().
begin()));
407 return noexcept(__decay_copy(
begin(
std::declval<_Tp&>())));
411 template<__maybe_borrowed_range _Tp>
415 operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
417 if constexpr (is_array_v<remove_reference_t<_Tp>>)
419 static_assert(is_lvalue_reference_v<_Tp>);
420 using _Up = remove_all_extents_t<remove_reference_t<_Tp>>;
421 static_assert(
sizeof(_Up) != 0,
"not array of incomplete type");
424 else if constexpr (__member_begin<_Tp>)
431 template<
typename _Tp>
432 concept __member_end = requires(_Tp& __t)
434 { __decay_copy(__t.end()) }
435 -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
438 void end(
auto&) =
delete;
439 void end(
const auto&) =
delete;
441 template<
typename _Tp>
442 concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
443 && requires(_Tp& __t)
445 { __decay_copy(
end(__t)) }
446 -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
452 template<
typename _Tp>
453 static constexpr
bool
456 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
458 else if constexpr (__member_end<_Tp>)
459 return noexcept(__decay_copy(
std::declval<_Tp&>().
end()));
461 return noexcept(__decay_copy(
end(
std::declval<_Tp&>())));
465 template<__maybe_borrowed_range _Tp>
469 operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
471 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
473 static_assert(is_lvalue_reference_v<_Tp>);
474 return __t + extent_v<remove_reference_t<_Tp>>;
476 else if constexpr (__member_end<_Tp>)
483 template<
typename _Tp>
484 constexpr decltype(
auto)
485 __as_const(_Tp&& __t) noexcept
487 if constexpr (is_lvalue_reference_v<_Tp>)
488 return static_cast<const remove_reference_t<_Tp>&
>(__t);
490 return static_cast<const _Tp&&>(__t);
495 template<
typename _Tp>
497 operator()(_Tp&& __e)
const
498 noexcept(noexcept(_Begin{}(__cust_access::__as_const((_Tp&&)__e))))
499 requires requires { _Begin{}(__cust_access::__as_const((_Tp&&)__e)); }
501 return _Begin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
507 template<
typename _Tp>
509 operator()(_Tp&& __e)
const
510 noexcept(noexcept(_End{}(__cust_access::__as_const((_Tp&&)__e))))
511 requires requires { _End{}(__cust_access::__as_const((_Tp&&)__e)); }
513 return _End{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
517 template<
typename _Tp>
518 concept __member_rbegin = requires(_Tp& __t)
520 { __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
523 void rbegin(
auto&) =
delete;
524 void rbegin(
const auto&) =
delete;
526 template<
typename _Tp>
527 concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
528 && requires(_Tp& __t)
530 { __decay_copy(
rbegin(__t)) } -> input_or_output_iterator;
533 template<
typename _Tp>
534 concept __reversable = requires(_Tp& __t)
536 { _Begin{}(__t) } -> bidirectional_iterator;
537 { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
543 template<
typename _Tp>
544 static constexpr
bool
547 if constexpr (__member_rbegin<_Tp>)
548 return noexcept(__decay_copy(std::declval<_Tp&>().
rbegin()));
549 else if constexpr (__adl_rbegin<_Tp>)
550 return noexcept(__decay_copy(
rbegin(std::declval<_Tp&>())));
553 if constexpr (noexcept(_End{}(std::declval<_Tp&>())))
555 using _It = decltype(_End{}(std::declval<_Tp&>()));
557 return is_nothrow_copy_constructible_v<_It>;
565 template<__maybe_borrowed_range _Tp>
566 requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
568 operator()(_Tp&& __t)
const
569 noexcept(_S_noexcept<_Tp>())
571 if constexpr (__member_rbegin<_Tp>)
573 else if constexpr (__adl_rbegin<_Tp>)
580 template<
typename _Tp>
581 concept __member_rend = requires(_Tp& __t)
583 { __decay_copy(__t.rend()) }
584 -> sentinel_for<decltype(_RBegin{}(__t))>;
587 void rend(
auto&) =
delete;
588 void rend(
const auto&) =
delete;
590 template<
typename _Tp>
591 concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
592 && requires(_Tp& __t)
594 { __decay_copy(
rend(__t)) }
595 -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
601 template<
typename _Tp>
602 static constexpr
bool
605 if constexpr (__member_rend<_Tp>)
606 return noexcept(__decay_copy(std::declval<_Tp&>().
rend()));
607 else if constexpr (__adl_rend<_Tp>)
608 return noexcept(__decay_copy(
rend(std::declval<_Tp&>())));
611 if constexpr (noexcept(_Begin{}(std::declval<_Tp&>())))
613 using _It = decltype(_Begin{}(std::declval<_Tp&>()));
615 return is_nothrow_copy_constructible_v<_It>;
623 template<__maybe_borrowed_range _Tp>
624 requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
626 operator()(_Tp&& __t)
const
627 noexcept(_S_noexcept<_Tp>())
629 if constexpr (__member_rend<_Tp>)
631 else if constexpr (__adl_rend<_Tp>)
640 template<
typename _Tp>
642 operator()(_Tp&& __e)
const
643 noexcept(noexcept(_RBegin{}(__cust_access::__as_const((_Tp&&)__e))))
644 requires requires { _RBegin{}(__cust_access::__as_const((_Tp&&)__e)); }
646 return _RBegin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
652 template<
typename _Tp>
654 operator()(_Tp&& __e)
const
655 noexcept(noexcept(_REnd{}(__cust_access::__as_const((_Tp&&)__e))))
656 requires requires { _REnd{}(__cust_access::__as_const((_Tp&&)__e)); }
658 return _REnd{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
662 template<
typename _Tp>
663 concept __member_size = !disable_sized_range<remove_cvref_t<_Tp>>
664 && requires(_Tp&& __t)
666 { __decay_copy(std::forward<_Tp>(__t).size()) }
667 -> __detail::__is_integer_like;
670 void size(
auto&) =
delete;
671 void size(
const auto&) =
delete;
673 template<
typename _Tp>
674 concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
675 && !disable_sized_range<remove_cvref_t<_Tp>>
676 && requires(_Tp&& __t)
678 { __decay_copy(size(std::forward<_Tp>(__t))) }
679 -> __detail::__is_integer_like;
682 template<
typename _Tp>
683 concept __sentinel_size = requires(_Tp&& __t)
685 { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
687 { _End{}(std::forward<_Tp>(__t)) }
688 -> sized_sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
694 template<
typename _Tp>
695 static constexpr
bool
698 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
700 else if constexpr (__member_size<_Tp>)
701 return noexcept(__decay_copy(
std::declval<_Tp>().size()));
702 else if constexpr (__adl_size<_Tp>)
703 return noexcept(__decay_copy(size(
std::declval<_Tp>())));
704 else if constexpr (__sentinel_size<_Tp>)
705 return noexcept(_End{}(std::declval<_Tp>())
706 - _Begin{}(std::declval<_Tp>()));
710 template<
typename _Tp>
711 requires is_bounded_array_v<remove_reference_t<_Tp>>
712 || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
714 operator()(_Tp&& __e)
const noexcept(_S_noexcept<_Tp>())
716 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
718 return extent_v<remove_reference_t<_Tp>>;
720 else if constexpr (__member_size<_Tp>)
721 return std::forward<_Tp>(__e).size();
722 else if constexpr (__adl_size<_Tp>)
723 return size(std::forward<_Tp>(__e));
724 else if constexpr (__sentinel_size<_Tp>)
725 return __detail::__to_unsigned_like(
726 _End{}(std::forward<_Tp>(__e))
727 - _Begin{}(std::forward<_Tp>(__e)));
733 template<
typename _Tp>
734 requires requires (_Tp&& __e)
736 _Begin{}(std::forward<_Tp>(__e));
737 _Size{}(std::forward<_Tp>(__e));
740 operator()(_Tp&& __e)
const
741 noexcept(noexcept(_Size{}(std::forward<_Tp>(__e))))
743 using __iter_type = decltype(_Begin{}(std::forward<_Tp>(__e)));
744 using __diff_type = iter_difference_t<__iter_type>;
745 using std::__detail::__int_limits;
746 auto __size = _Size{}(std::forward<_Tp>(__e));
747 if constexpr (integral<__diff_type>)
749 if constexpr (__int_limits<__diff_type>::digits
750 < __int_limits<ptrdiff_t>::digits)
751 return static_cast<ptrdiff_t>(__size);
753 return static_cast<__diff_type>(__size);
757 template<
typename _Tp>
758 concept __member_empty = requires(_Tp&& __t)
759 { bool(std::forward<_Tp>(__t).empty()); };
761 template<
typename _Tp>
762 concept __size0_empty = requires(_Tp&& __t)
763 { _Size{}(std::forward<_Tp>(__t)) == 0; };
765 template<
typename _Tp>
766 concept __eq_iter_empty = requires(_Tp&& __t)
768 { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
769 bool(_Begin{}(std::forward<_Tp>(__t))
770 == _End{}(std::forward<_Tp>(__t)));
776 template<
typename _Tp>
777 static constexpr
bool
780 if constexpr (__member_empty<_Tp>)
781 return noexcept(std::declval<_Tp>().empty());
782 else if constexpr (__size0_empty<_Tp>)
783 return noexcept(_Size{}(std::declval<_Tp>()) == 0);
785 return noexcept(
bool(_Begin{}(std::declval<_Tp>())
786 == _End{}(std::declval<_Tp>())));
790 template<
typename _Tp>
791 requires __member_empty<_Tp> || __size0_empty<_Tp>
792 || __eq_iter_empty<_Tp>
794 operator()(_Tp&& __e)
const noexcept(_S_noexcept<_Tp>())
796 if constexpr (__member_empty<_Tp>)
797 return bool(std::forward<_Tp>(__e).empty());
798 else if constexpr (__size0_empty<_Tp>)
799 return _Size{}(std::forward<_Tp>(__e)) == 0;
801 return bool(_Begin{}(std::forward<_Tp>(__e))
802 == _End{}(std::forward<_Tp>(__e)));
806 template<
typename _Tp>
807 concept __pointer_to_object = is_pointer_v<_Tp>
808 && is_object_v<remove_pointer_t<_Tp>>;
810 template<
typename _Tp>
811 concept __member_data = is_lvalue_reference_v<_Tp>
812 && requires(_Tp __t) { { __t.data() } -> __pointer_to_object; };
814 template<
typename _Tp>
815 concept __begin_data = requires(_Tp&& __t)
816 { { _Begin{}(std::forward<_Tp>(__t)) } -> contiguous_iterator; };
821 template<
typename _Tp>
822 static constexpr
bool
825 if constexpr (__member_data<_Tp>)
826 return noexcept(__decay_copy(std::declval<_Tp>().data()));
828 return noexcept(_Begin{}(std::declval<_Tp>()));
832 template<__maybe_borrowed_range _Tp>
833 requires __member_data<_Tp> || __begin_data<_Tp>
835 operator()(_Tp&& __e)
const noexcept(_S_noexcept<_Tp>())
837 if constexpr (__member_data<_Tp>)
840 return std::to_address(_Begin{}(std::forward<_Tp>(__e)));
846 template<
typename _Tp>
848 operator()(_Tp&& __e)
const
849 noexcept(noexcept(_Data{}(__cust_access::__as_const((_Tp&&)__e))))
850 requires requires { _Data{}(__cust_access::__as_const((_Tp&&)__e)); }
852 return _Data{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
858 inline namespace __cust
860 inline constexpr __cust_access::_Begin
begin{};
861 inline constexpr __cust_access::_End
end{};
862 inline constexpr __cust_access::_CBegin
cbegin{};
863 inline constexpr __cust_access::_CEnd
cend{};
864 inline constexpr __cust_access::_RBegin
rbegin{};
865 inline constexpr __cust_access::_REnd
rend{};
866 inline constexpr __cust_access::_CRBegin
crbegin{};
867 inline constexpr __cust_access::_CREnd
crend{};
868 inline constexpr __cust_access::_Size size{};
869 inline constexpr __cust_access::_SSize ssize{};
870 inline constexpr __cust_access::_Empty empty{};
871 inline constexpr __cust_access::_Data data{};
872 inline constexpr __cust_access::_CData cdata{};
876 template<
typename _Tp>
877 concept range = requires(_Tp& __t)
884 template<
typename _Tp>
885 concept borrowed_range
886 = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
888 template<
typename _Tp>
889 using iterator_t = decltype(
ranges::begin(std::declval<_Tp&>()));
891 template<range _Range>
892 using sentinel_t = decltype(
ranges::end(std::declval<_Range&>()));
894 template<range _Range>
895 using range_difference_t = iter_difference_t<iterator_t<_Range>>;
897 template<range _Range>
898 using range_value_t = iter_value_t<iterator_t<_Range>>;
900 template<range _Range>
901 using range_reference_t = iter_reference_t<iterator_t<_Range>>;
903 template<range _Range>
904 using range_rvalue_reference_t
905 = iter_rvalue_reference_t<iterator_t<_Range>>;
908 template<
typename _Tp>
909 concept sized_range = range<_Tp>
910 && requires(_Tp& __t) { ranges::size(__t); };
912 template<sized_range _Range>
913 using range_size_t = decltype(ranges::size(std::declval<_Range&>()));
918 template<
typename _Range,
typename _Tp>
920 = range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
923 template<
typename _Tp>
924 concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
927 template<
typename _Tp>
928 concept forward_range
929 = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
932 template<
typename _Tp>
933 concept bidirectional_range
934 = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
937 template<
typename _Tp>
938 concept random_access_range
939 = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
942 template<
typename _Tp>
943 concept contiguous_range
944 = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
945 && requires(_Tp& __t)
947 { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
951 template<
typename _Tp>
953 = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
957 template<input_or_output_iterator _It>
959 advance(_It& __it, iter_difference_t<_It> __n)
961 if constexpr (random_access_iterator<_It>)
963 else if constexpr (bidirectional_iterator<_It>)
984 #ifdef __cpp_lib_is_constant_evaluated
985 if (std::is_constant_evaluated() && __n < 0)
986 throw "attempt to decrement a non-bidirectional iterator";
988 __glibcxx_assert(__n >= 0);
994 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
996 advance(_It& __it, _Sent __bound)
998 if constexpr (assignable_from<_It&, _Sent>)
1000 else if constexpr (sized_sentinel_for<_Sent, _It>)
1004 while (__it != __bound)
1009 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1010 constexpr iter_difference_t<_It>
1011 advance(_It& __it, iter_difference_t<_It> __n, _Sent __bound)
1013 if constexpr (sized_sentinel_for<_Sent, _It>)
1015 const auto __diff = __bound - __it;
1016 #ifdef __cpp_lib_is_constant_evaluated
1017 if (std::is_constant_evaluated()
1018 && !(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0)))
1019 throw "inconsistent directions for distance and bound";
1022 __glibcxx_assert(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0));
1023 const auto __absdiff = __diff < 0 ? -__diff : __diff;
1024 const auto __absn = __n < 0 ? -__n : __n;;
1025 if (__absn >= __absdiff)
1028 return __n - __diff;
1036 else if (__it == __bound || __n == 0)
1037 return iter_difference_t<_It>(0);
1040 iter_difference_t<_It> __m = 0;
1046 while (__m != __n && __it != __bound);
1049 else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>)
1051 iter_difference_t<_It> __m = 0;
1057 while (__m != __n && __it != __bound);
1062 #ifdef __cpp_lib_is_constant_evaluated
1063 if (std::is_constant_evaluated() && __n < 0)
1064 throw "attempt to decrement a non-bidirectional iterator";
1066 __glibcxx_assert(__n >= 0);
1071 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1072 constexpr iter_difference_t<_It>
1073 distance(_It __first, _Sent __last)
1075 if constexpr (sized_sentinel_for<_Sent, _It>)
1076 return __last - __first;
1079 iter_difference_t<_It> __n = 0;
1080 while (__first != __last)
1089 template<range _Range>
1090 constexpr range_difference_t<_Range>
1093 if constexpr (sized_range<_Range>)
1094 return static_cast<range_difference_t<_Range>
>(ranges::size(__r));
1099 template<input_or_output_iterator _It>
1107 template<input_or_output_iterator _It>
1109 next(_It __x, iter_difference_t<_It> __n)
1115 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1117 next(_It __x, _Sent __bound)
1123 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1125 next(_It __x, iter_difference_t<_It> __n, _Sent __bound)
1131 template<b
idirectional_iterator _It>
1139 template<b
idirectional_iterator _It>
1141 prev(_It __x, iter_difference_t<_It> __n)
1147 template<b
idirectional_iterator _It>
1149 prev(_It __x, iter_difference_t<_It> __n, _It __bound)
1156 #endif // library concepts
1158 _GLIBCXX_END_NAMESPACE_VERSION
1163 #endif // _GLIBCXX_RANGE_ACCESS_H