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;
349 template<
typename _Tp>
350 extern const bool enable_view;
354 template<
integral _Tp>
355 constexpr make_unsigned_t<_Tp>
356 __to_unsigned_like(_Tp __t) noexcept
359 template<
typename _Tp,
bool _MaxDiff = same_as<_Tp, __max_diff_type>>
360 using __make_unsigned_like_t
361 = conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>;
364 template<
typename _Tp>
365 concept __maybe_borrowed_range
366 = is_lvalue_reference_v<_Tp>
367 || enable_borrowed_range<remove_cvref_t<_Tp>>;
371 namespace __cust_access
373 using std::ranges::__detail::__maybe_borrowed_range;
374 using std::__detail::__class_or_enum;
376 template<
typename _Tp>
377 constexpr decay_t<_Tp>
378 __decay_copy(_Tp&& __t)
379 noexcept(is_nothrow_convertible_v<_Tp, decay_t<_Tp>>)
380 {
return std::forward<_Tp>(__t); }
382 template<
typename _Tp>
383 concept __member_begin = requires(_Tp& __t)
385 { __decay_copy(__t.begin()) } -> input_or_output_iterator;
388 void begin(
auto&) =
delete;
389 void begin(
const auto&) =
delete;
391 template<
typename _Tp>
392 concept __adl_begin = __class_or_enum<remove_reference_t<_Tp>>
393 && requires(_Tp& __t)
395 { __decay_copy(
begin(__t)) } -> input_or_output_iterator;
401 template<
typename _Tp>
402 static constexpr
bool
405 if constexpr (is_array_v<remove_reference_t<_Tp>>)
407 else if constexpr (__member_begin<_Tp>)
408 return noexcept(__decay_copy(
std::declval<_Tp&>().
begin()));
410 return noexcept(__decay_copy(
begin(
std::declval<_Tp&>())));
414 template<__maybe_borrowed_range _Tp>
418 operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
420 if constexpr (is_array_v<remove_reference_t<_Tp>>)
422 static_assert(is_lvalue_reference_v<_Tp>);
423 using _Up = remove_all_extents_t<remove_reference_t<_Tp>>;
424 static_assert(
sizeof(_Up) != 0,
"not array of incomplete type");
427 else if constexpr (__member_begin<_Tp>)
434 template<
typename _Tp>
435 concept __member_end = requires(_Tp& __t)
437 { __decay_copy(__t.end()) }
438 -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
441 void end(
auto&) =
delete;
442 void end(
const auto&) =
delete;
444 template<
typename _Tp>
445 concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
446 && requires(_Tp& __t)
448 { __decay_copy(
end(__t)) }
449 -> sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
455 template<
typename _Tp>
456 static constexpr
bool
459 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
461 else if constexpr (__member_end<_Tp>)
462 return noexcept(__decay_copy(
std::declval<_Tp&>().
end()));
464 return noexcept(__decay_copy(
end(
std::declval<_Tp&>())));
468 template<__maybe_borrowed_range _Tp>
472 operator()(_Tp&& __t) const noexcept(_S_noexcept<_Tp>())
474 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
476 static_assert(is_lvalue_reference_v<_Tp>);
477 return __t + extent_v<remove_reference_t<_Tp>>;
479 else if constexpr (__member_end<_Tp>)
486 template<
typename _Tp>
487 constexpr decltype(
auto)
488 __as_const(_Tp&& __t) noexcept
490 if constexpr (is_lvalue_reference_v<_Tp>)
491 return static_cast<const remove_reference_t<_Tp>&
>(__t);
493 return static_cast<const _Tp&&
>(__t);
498 template<
typename _Tp>
500 operator()(_Tp&& __e)
const
501 noexcept(noexcept(_Begin{}(__cust_access::__as_const((_Tp&&)__e))))
502 requires requires { _Begin{}(__cust_access::__as_const((_Tp&&)__e)); }
504 return _Begin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
510 template<
typename _Tp>
512 operator()(_Tp&& __e)
const
513 noexcept(noexcept(_End{}(__cust_access::__as_const((_Tp&&)__e))))
514 requires requires { _End{}(__cust_access::__as_const((_Tp&&)__e)); }
516 return _End{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
520 template<
typename _Tp>
521 concept __member_rbegin = requires(_Tp& __t)
523 { __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
526 void rbegin(
auto&) =
delete;
527 void rbegin(
const auto&) =
delete;
529 template<
typename _Tp>
530 concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
531 && requires(_Tp& __t)
533 { __decay_copy(
rbegin(__t)) } -> input_or_output_iterator;
536 template<
typename _Tp>
537 concept __reversable = requires(_Tp& __t)
539 { _Begin{}(__t) } -> bidirectional_iterator;
540 { _End{}(__t) } -> same_as<decltype(_Begin{}(__t))>;
546 template<
typename _Tp>
547 static constexpr
bool
550 if constexpr (__member_rbegin<_Tp>)
551 return noexcept(__decay_copy(std::declval<_Tp&>().
rbegin()));
552 else if constexpr (__adl_rbegin<_Tp>)
553 return noexcept(__decay_copy(
rbegin(std::declval<_Tp&>())));
556 if constexpr (noexcept(_End{}(std::declval<_Tp&>())))
558 using _It = decltype(_End{}(std::declval<_Tp&>()));
560 return is_nothrow_copy_constructible_v<_It>;
568 template<__maybe_borrowed_range _Tp>
569 requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
571 operator()(_Tp&& __t)
const
572 noexcept(_S_noexcept<_Tp>())
574 if constexpr (__member_rbegin<_Tp>)
576 else if constexpr (__adl_rbegin<_Tp>)
583 template<
typename _Tp>
584 concept __member_rend = requires(_Tp& __t)
586 { __decay_copy(__t.rend()) }
587 -> sentinel_for<decltype(_RBegin{}(__t))>;
590 void rend(
auto&) =
delete;
591 void rend(
const auto&) =
delete;
593 template<
typename _Tp>
594 concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
595 && requires(_Tp& __t)
597 { __decay_copy(
rend(__t)) }
598 -> sentinel_for<decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
604 template<
typename _Tp>
605 static constexpr
bool
608 if constexpr (__member_rend<_Tp>)
609 return noexcept(__decay_copy(std::declval<_Tp&>().
rend()));
610 else if constexpr (__adl_rend<_Tp>)
611 return noexcept(__decay_copy(
rend(std::declval<_Tp&>())));
614 if constexpr (noexcept(_Begin{}(std::declval<_Tp&>())))
616 using _It = decltype(_Begin{}(std::declval<_Tp&>()));
618 return is_nothrow_copy_constructible_v<_It>;
626 template<__maybe_borrowed_range _Tp>
627 requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
629 operator()(_Tp&& __t)
const
630 noexcept(_S_noexcept<_Tp>())
632 if constexpr (__member_rend<_Tp>)
634 else if constexpr (__adl_rend<_Tp>)
643 template<
typename _Tp>
645 operator()(_Tp&& __e)
const
646 noexcept(noexcept(_RBegin{}(__cust_access::__as_const((_Tp&&)__e))))
647 requires requires { _RBegin{}(__cust_access::__as_const((_Tp&&)__e)); }
649 return _RBegin{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
655 template<
typename _Tp>
657 operator()(_Tp&& __e)
const
658 noexcept(noexcept(_REnd{}(__cust_access::__as_const((_Tp&&)__e))))
659 requires requires { _REnd{}(__cust_access::__as_const((_Tp&&)__e)); }
661 return _REnd{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
665 template<
typename _Tp>
666 concept __member_size = !disable_sized_range<remove_cvref_t<_Tp>>
667 && requires(_Tp&& __t)
669 { __decay_copy(std::forward<_Tp>(__t).size()) }
670 -> __detail::__is_integer_like;
673 void size(
auto&) =
delete;
674 void size(
const auto&) =
delete;
676 template<
typename _Tp>
677 concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
678 && !disable_sized_range<remove_cvref_t<_Tp>>
679 && requires(_Tp&& __t)
681 { __decay_copy(size(std::forward<_Tp>(__t))) }
682 -> __detail::__is_integer_like;
685 template<
typename _Tp>
686 concept __sentinel_size = requires(_Tp&& __t)
688 { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
690 { _End{}(std::forward<_Tp>(__t)) }
691 -> sized_sentinel_for<decltype(_Begin{}(std::forward<_Tp>(__t)))>;
697 template<
typename _Tp>
698 static constexpr
bool
701 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
703 else if constexpr (__member_size<_Tp>)
704 return noexcept(__decay_copy(
std::declval<_Tp>().size()));
705 else if constexpr (__adl_size<_Tp>)
706 return noexcept(__decay_copy(size(
std::declval<_Tp>())));
707 else if constexpr (__sentinel_size<_Tp>)
708 return noexcept(_End{}(std::declval<_Tp>())
709 - _Begin{}(std::declval<_Tp>()));
713 template<
typename _Tp>
714 requires is_bounded_array_v<remove_reference_t<_Tp>>
715 || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
717 operator()(_Tp&& __e)
const noexcept(_S_noexcept<_Tp>())
719 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
721 return extent_v<remove_reference_t<_Tp>>;
723 else if constexpr (__member_size<_Tp>)
724 return std::forward<_Tp>(__e).size();
725 else if constexpr (__adl_size<_Tp>)
726 return size(std::forward<_Tp>(__e));
727 else if constexpr (__sentinel_size<_Tp>)
728 return __detail::__to_unsigned_like(
729 _End{}(std::forward<_Tp>(__e))
730 - _Begin{}(std::forward<_Tp>(__e)));
736 template<
typename _Tp>
737 requires requires (_Tp&& __e)
739 _Begin{}(std::forward<_Tp>(__e));
740 _Size{}(std::forward<_Tp>(__e));
743 operator()(_Tp&& __e)
const
744 noexcept(noexcept(_Size{}(std::forward<_Tp>(__e))))
746 using __iter_type = decltype(_Begin{}(std::forward<_Tp>(__e)));
747 using __diff_type = iter_difference_t<__iter_type>;
748 using std::__detail::__int_limits;
749 auto __size = _Size{}(std::forward<_Tp>(__e));
750 if constexpr (integral<__diff_type>)
752 if constexpr (__int_limits<__diff_type>::digits
753 < __int_limits<ptrdiff_t>::digits)
754 return static_cast<ptrdiff_t
>(__size);
756 return static_cast<__diff_type
>(__size);
760 template<
typename _Tp>
761 concept __member_empty = requires(_Tp&& __t)
762 { bool(std::forward<_Tp>(__t).empty()); };
764 template<
typename _Tp>
765 concept __size0_empty = requires(_Tp&& __t)
766 { _Size{}(std::forward<_Tp>(__t)) == 0; };
768 template<
typename _Tp>
769 concept __eq_iter_empty = requires(_Tp&& __t)
771 { _Begin{}(std::forward<_Tp>(__t)) } -> forward_iterator;
772 bool(_Begin{}(std::forward<_Tp>(__t))
773 == _End{}(std::forward<_Tp>(__t)));
779 template<
typename _Tp>
780 static constexpr
bool
783 if constexpr (__member_empty<_Tp>)
784 return noexcept(std::declval<_Tp>().empty());
785 else if constexpr (__size0_empty<_Tp>)
786 return noexcept(_Size{}(std::declval<_Tp>()) == 0);
788 return noexcept(
bool(_Begin{}(std::declval<_Tp>())
789 == _End{}(std::declval<_Tp>())));
793 template<
typename _Tp>
794 requires __member_empty<_Tp> || __size0_empty<_Tp>
795 || __eq_iter_empty<_Tp>
797 operator()(_Tp&& __e)
const noexcept(_S_noexcept<_Tp>())
799 if constexpr (__member_empty<_Tp>)
800 return bool(std::forward<_Tp>(__e).empty());
801 else if constexpr (__size0_empty<_Tp>)
802 return _Size{}(std::forward<_Tp>(__e)) == 0;
804 return bool(_Begin{}(std::forward<_Tp>(__e))
805 == _End{}(std::forward<_Tp>(__e)));
809 template<
typename _Tp>
810 concept __pointer_to_object = is_pointer_v<_Tp>
811 && is_object_v<remove_pointer_t<_Tp>>;
813 template<
typename _Tp>
814 concept __member_data = is_lvalue_reference_v<_Tp>
815 && requires(_Tp __t) { { __t.data() } -> __pointer_to_object; };
817 template<
typename _Tp>
818 concept __begin_data = requires(_Tp&& __t)
819 { { _Begin{}(std::forward<_Tp>(__t)) } -> contiguous_iterator; };
824 template<
typename _Tp>
825 static constexpr
bool
828 if constexpr (__member_data<_Tp>)
829 return noexcept(__decay_copy(std::declval<_Tp>().data()));
831 return noexcept(_Begin{}(std::declval<_Tp>()));
835 template<__maybe_borrowed_range _Tp>
836 requires __member_data<_Tp> || __begin_data<_Tp>
838 operator()(_Tp&& __e)
const noexcept(_S_noexcept<_Tp>())
840 if constexpr (__member_data<_Tp>)
843 return std::to_address(_Begin{}(std::forward<_Tp>(__e)));
849 template<
typename _Tp>
851 operator()(_Tp&& __e)
const
852 noexcept(noexcept(_Data{}(__cust_access::__as_const((_Tp&&)__e))))
853 requires requires { _Data{}(__cust_access::__as_const((_Tp&&)__e)); }
855 return _Data{}(__cust_access::__as_const(std::forward<_Tp>(__e)));
861 inline namespace __cust
863 inline constexpr __cust_access::_Begin
begin{};
864 inline constexpr __cust_access::_End
end{};
865 inline constexpr __cust_access::_CBegin
cbegin{};
866 inline constexpr __cust_access::_CEnd
cend{};
867 inline constexpr __cust_access::_RBegin
rbegin{};
868 inline constexpr __cust_access::_REnd
rend{};
869 inline constexpr __cust_access::_CRBegin
crbegin{};
870 inline constexpr __cust_access::_CREnd
crend{};
871 inline constexpr __cust_access::_Size size{};
872 inline constexpr __cust_access::_SSize ssize{};
873 inline constexpr __cust_access::_Empty empty{};
874 inline constexpr __cust_access::_Data data{};
875 inline constexpr __cust_access::_CData cdata{};
879 template<
typename _Tp>
880 concept range = requires(_Tp& __t)
887 template<
typename _Tp>
888 concept borrowed_range
889 = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
891 template<
typename _Tp>
892 using iterator_t = decltype(
ranges::begin(std::declval<_Tp&>()));
894 template<range _Range>
895 using sentinel_t = decltype(
ranges::end(std::declval<_Range&>()));
897 template<range _Range>
898 using range_difference_t = iter_difference_t<iterator_t<_Range>>;
900 template<range _Range>
901 using range_value_t = iter_value_t<iterator_t<_Range>>;
903 template<range _Range>
904 using range_reference_t = iter_reference_t<iterator_t<_Range>>;
906 template<range _Range>
907 using range_rvalue_reference_t
908 = iter_rvalue_reference_t<iterator_t<_Range>>;
911 template<
typename _Tp>
912 concept sized_range = range<_Tp>
913 && requires(_Tp& __t) { ranges::size(__t); };
915 template<sized_range _Range>
916 using range_size_t = decltype(ranges::size(std::declval<_Range&>()));
921 template<
typename _Range,
typename _Tp>
923 = range<_Range> && output_iterator<iterator_t<_Range>, _Tp>;
926 template<
typename _Tp>
927 concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
930 template<
typename _Tp>
931 concept forward_range
932 = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>;
935 template<
typename _Tp>
936 concept bidirectional_range
937 = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>;
940 template<
typename _Tp>
941 concept random_access_range
942 = bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>;
945 template<
typename _Tp>
946 concept contiguous_range
947 = random_access_range<_Tp> && contiguous_iterator<iterator_t<_Tp>>
948 && requires(_Tp& __t)
950 { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
954 template<
typename _Tp>
956 = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
960 template<input_or_output_iterator _It>
962 advance(_It& __it, iter_difference_t<_It> __n)
964 if constexpr (random_access_iterator<_It>)
966 else if constexpr (bidirectional_iterator<_It>)
987 #ifdef __cpp_lib_is_constant_evaluated
988 if (std::is_constant_evaluated() && __n < 0)
989 throw "attempt to decrement a non-bidirectional iterator";
991 __glibcxx_assert(__n >= 0);
997 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
999 advance(_It& __it, _Sent __bound)
1001 if constexpr (assignable_from<_It&, _Sent>)
1003 else if constexpr (sized_sentinel_for<_Sent, _It>)
1007 while (__it != __bound)
1012 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1013 constexpr iter_difference_t<_It>
1014 advance(_It& __it, iter_difference_t<_It> __n, _Sent __bound)
1016 if constexpr (sized_sentinel_for<_Sent, _It>)
1018 const auto __diff = __bound - __it;
1019 #ifdef __cpp_lib_is_constant_evaluated
1020 if (std::is_constant_evaluated()
1021 && !(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0)))
1022 throw "inconsistent directions for distance and bound";
1025 __glibcxx_assert(__n == 0 || __diff == 0 || (__n < 0 == __diff < 0));
1026 const auto __absdiff = __diff < 0 ? -__diff : __diff;
1027 const auto __absn = __n < 0 ? -__n : __n;;
1028 if (__absn >= __absdiff)
1031 return __n - __diff;
1039 else if (__it == __bound || __n == 0)
1040 return iter_difference_t<_It>(0);
1043 iter_difference_t<_It> __m = 0;
1049 while (__m != __n && __it != __bound);
1052 else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>)
1054 iter_difference_t<_It> __m = 0;
1060 while (__m != __n && __it != __bound);
1065 #ifdef __cpp_lib_is_constant_evaluated
1066 if (std::is_constant_evaluated() && __n < 0)
1067 throw "attempt to decrement a non-bidirectional iterator";
1069 __glibcxx_assert(__n >= 0);
1074 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1075 constexpr iter_difference_t<_It>
1076 distance(_It __first, _Sent __last)
1078 if constexpr (sized_sentinel_for<_Sent, _It>)
1079 return __last - __first;
1082 iter_difference_t<_It> __n = 0;
1083 while (__first != __last)
1092 template<range _Range>
1093 constexpr range_difference_t<_Range>
1096 if constexpr (sized_range<_Range>)
1097 return static_cast<range_difference_t<_Range>
>(ranges::size(__r));
1102 template<input_or_output_iterator _It>
1110 template<input_or_output_iterator _It>
1112 next(_It __x, iter_difference_t<_It> __n)
1118 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1120 next(_It __x, _Sent __bound)
1126 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
1128 next(_It __x, iter_difference_t<_It> __n, _Sent __bound)
1134 template<b
idirectional_iterator _It>
1142 template<b
idirectional_iterator _It>
1144 prev(_It __x, iter_difference_t<_It> __n)
1150 template<b
idirectional_iterator _It>
1152 prev(_It __x, iter_difference_t<_It> __n, _It __bound)
1159 #endif // library concepts
1161 _GLIBCXX_END_NAMESPACE_VERSION
1166 #endif // _GLIBCXX_RANGE_ACCESS_H