30#ifndef _GLIBCXX_RANGES_BASE_H
31#define _GLIBCXX_RANGES_BASE_H 1
33#pragma GCC system_header
35#if __cplusplus > 201703L
40#ifdef __cpp_lib_concepts
41namespace std _GLIBCXX_VISIBILITY(default)
43_GLIBCXX_BEGIN_NAMESPACE_VERSION
47 inline constexpr bool disable_sized_range =
false;
49 template<
typename _Tp>
50 inline constexpr bool enable_borrowed_range =
false;
54 constexpr __max_size_type
55 __to_unsigned_like(__max_size_type __t)
noexcept
58 constexpr __max_size_type
59 __to_unsigned_like(__max_diff_type __t)
noexcept
60 {
return __max_size_type(__t); }
62 template<
integral _Tp>
64 __to_unsigned_like(_Tp __t)
noexcept
65 {
return static_cast<make_unsigned_t<_Tp>
>(__t); }
67#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
68 constexpr unsigned __int128
69 __to_unsigned_like(__int128 __t)
noexcept
72 constexpr unsigned __int128
73 __to_unsigned_like(
unsigned __int128 __t)
noexcept
77 template<
typename _Tp>
78 using __make_unsigned_like_t
79 =
decltype(__detail::__to_unsigned_like(std::declval<_Tp>()));
82 template<
typename _Tp>
83 concept __maybe_borrowed_range
84 = is_lvalue_reference_v<_Tp>
85 || enable_borrowed_range<remove_cvref_t<_Tp>>;
89 namespace __cust_access
91 using std::ranges::__detail::__maybe_borrowed_range;
92 using std::__detail::__range_iter_t;
97 template<
typename _Tp>
101 if constexpr (is_array_v<remove_reference_t<_Tp>>)
103 else if constexpr (__member_begin<_Tp>)
104 return noexcept(__decay_copy(std::declval<_Tp&>().begin()));
106 return noexcept(__decay_copy(begin(std::declval<_Tp&>())));
110 template<__maybe_borrowed_range _Tp>
111 requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
114 operator()[[nodiscard]](_Tp&& __t)
const noexcept(_S_noexcept<_Tp&>())
116 if constexpr (is_array_v<remove_reference_t<_Tp>>)
118 static_assert(is_lvalue_reference_v<_Tp>);
121 else if constexpr (__member_begin<_Tp>)
128 template<
typename _Tp>
129 concept __member_end =
requires(_Tp& __t)
131 { __decay_copy(__t.end()) } -> sentinel_for<__range_iter_t<_Tp>>;
135 void end(
auto&) =
delete;
136 void end(
const auto&) =
delete;
138 template<
typename _Tp>
139 concept __adl_end = __class_or_enum<remove_reference_t<_Tp>>
140 &&
requires(_Tp& __t)
142 { __decay_copy(end(__t)) } -> sentinel_for<__range_iter_t<_Tp>>;
148 template<
typename _Tp>
149 static constexpr bool
152 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
154 else if constexpr (__member_end<_Tp>)
155 return noexcept(__decay_copy(std::declval<_Tp&>().end()));
157 return noexcept(__decay_copy(end(std::declval<_Tp&>())));
161 template<__maybe_borrowed_range _Tp>
162 requires is_bounded_array_v<remove_reference_t<_Tp>>
163 || __member_end<_Tp> || __adl_end<_Tp>
165 operator()[[nodiscard]](_Tp&& __t)
const noexcept(_S_noexcept<_Tp&>())
167 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
169 static_assert(is_lvalue_reference_v<_Tp>);
170 return __t + extent_v<remove_reference_t<_Tp>>;
172 else if constexpr (__member_end<_Tp>)
180 template<
typename _To,
typename _Tp>
181 constexpr decltype(
auto)
182 __as_const(_Tp& __t)
noexcept
184 static_assert(std::is_same_v<_To&, _Tp&>);
186 if constexpr (is_lvalue_reference_v<_To>)
187 return const_cast<const _Tp&
>(__t);
189 return static_cast<const _Tp&&
>(__t);
194 template<
typename _Tp>
197 operator()(_Tp&& __e)
const
198 noexcept(
noexcept(_Begin{}(__cust_access::__as_const<_Tp>(__e))))
199 requires requires { _Begin{}(__cust_access::__as_const<_Tp>(__e)); }
201 return _Begin{}(__cust_access::__as_const<_Tp>(__e));
207 template<
typename _Tp>
210 operator()(_Tp&& __e)
const
211 noexcept(
noexcept(_End{}(__cust_access::__as_const<_Tp>(__e))))
212 requires requires { _End{}(__cust_access::__as_const<_Tp>(__e)); }
214 return _End{}(__cust_access::__as_const<_Tp>(__e));
218 template<
typename _Tp>
219 concept __member_rbegin =
requires(_Tp& __t)
221 { __decay_copy(__t.rbegin()) } -> input_or_output_iterator;
224 void rbegin(
auto&) =
delete;
225 void rbegin(
const auto&) =
delete;
227 template<
typename _Tp>
228 concept __adl_rbegin = __class_or_enum<remove_reference_t<_Tp>>
229 &&
requires(_Tp& __t)
231 { __decay_copy(rbegin(__t)) } -> input_or_output_iterator;
234 template<
typename _Tp>
235 concept __reversable =
requires(_Tp& __t)
237 { _Begin{}(__t) } -> bidirectional_iterator;
238 { _End{}(__t) } -> same_as<
decltype(_Begin{}(__t))>;
244 template<
typename _Tp>
245 static constexpr bool
248 if constexpr (__member_rbegin<_Tp>)
249 return noexcept(__decay_copy(std::declval<_Tp&>().rbegin()));
250 else if constexpr (__adl_rbegin<_Tp>)
251 return noexcept(__decay_copy(rbegin(std::declval<_Tp&>())));
254 if constexpr (
noexcept(_End{}(std::declval<_Tp&>())))
256 using _It =
decltype(_End{}(std::declval<_Tp&>()));
258 return is_nothrow_copy_constructible_v<_It>;
266 template<__maybe_borrowed_range _Tp>
267 requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
269 operator()[[nodiscard]](_Tp&& __t)
const
270 noexcept(_S_noexcept<_Tp&>())
272 if constexpr (__member_rbegin<_Tp>)
274 else if constexpr (__adl_rbegin<_Tp>)
281 template<
typename _Tp>
282 concept __member_rend =
requires(_Tp& __t)
284 { __decay_copy(__t.rend()) }
285 -> sentinel_for<
decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
288 void rend(
auto&) =
delete;
289 void rend(
const auto&) =
delete;
291 template<
typename _Tp>
292 concept __adl_rend = __class_or_enum<remove_reference_t<_Tp>>
293 &&
requires(_Tp& __t)
295 { __decay_copy(rend(__t)) }
296 -> sentinel_for<
decltype(_RBegin{}(std::forward<_Tp>(__t)))>;
302 template<
typename _Tp>
303 static constexpr bool
306 if constexpr (__member_rend<_Tp>)
307 return noexcept(__decay_copy(std::declval<_Tp&>().rend()));
308 else if constexpr (__adl_rend<_Tp>)
309 return noexcept(__decay_copy(rend(std::declval<_Tp&>())));
312 if constexpr (
noexcept(_Begin{}(std::declval<_Tp&>())))
314 using _It =
decltype(_Begin{}(std::declval<_Tp&>()));
316 return is_nothrow_copy_constructible_v<_It>;
324 template<__maybe_borrowed_range _Tp>
325 requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
327 operator()[[nodiscard]](_Tp&& __t)
const
328 noexcept(_S_noexcept<_Tp&>())
330 if constexpr (__member_rend<_Tp>)
332 else if constexpr (__adl_rend<_Tp>)
341 template<
typename _Tp>
344 operator()(_Tp&& __e)
const
345 noexcept(
noexcept(_RBegin{}(__cust_access::__as_const<_Tp>(__e))))
346 requires requires { _RBegin{}(__cust_access::__as_const<_Tp>(__e)); }
348 return _RBegin{}(__cust_access::__as_const<_Tp>(__e));
354 template<
typename _Tp>
357 operator()(_Tp&& __e)
const
358 noexcept(
noexcept(_REnd{}(__cust_access::__as_const<_Tp>(__e))))
359 requires requires { _REnd{}(__cust_access::__as_const<_Tp>(__e)); }
361 return _REnd{}(__cust_access::__as_const<_Tp>(__e));
365 template<
typename _Tp>
366 concept __member_size = !disable_sized_range<remove_cvref_t<_Tp>>
367 &&
requires(_Tp& __t)
369 { __decay_copy(__t.size()) } -> __detail::__is_integer_like;
372 void size(
auto&) =
delete;
373 void size(
const auto&) =
delete;
375 template<
typename _Tp>
376 concept __adl_size = __class_or_enum<remove_reference_t<_Tp>>
377 && !disable_sized_range<remove_cvref_t<_Tp>>
378 &&
requires(_Tp& __t)
380 { __decay_copy(size(__t)) } -> __detail::__is_integer_like;
383 template<
typename _Tp>
384 concept __sentinel_size =
requires(_Tp& __t)
386 requires (!is_unbounded_array_v<remove_reference_t<_Tp>>);
388 { _Begin{}(__t) } -> forward_iterator;
390 { _End{}(__t) } -> sized_sentinel_for<
decltype(_Begin{}(__t))>;
392 __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
398 template<
typename _Tp>
399 static constexpr bool
402 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
404 else if constexpr (__member_size<_Tp>)
405 return noexcept(__decay_copy(std::declval<_Tp&>().size()));
406 else if constexpr (__adl_size<_Tp>)
407 return noexcept(__decay_copy(size(std::declval<_Tp&>())));
408 else if constexpr (__sentinel_size<_Tp>)
409 return noexcept(_End{}(std::declval<_Tp&>())
410 - _Begin{}(std::declval<_Tp&>()));
414 template<
typename _Tp>
415 requires is_bounded_array_v<remove_reference_t<_Tp>>
416 || __member_size<_Tp> || __adl_size<_Tp> || __sentinel_size<_Tp>
418 operator()[[nodiscard]](_Tp&& __t)
const noexcept(_S_noexcept<_Tp&>())
420 if constexpr (is_bounded_array_v<remove_reference_t<_Tp>>)
421 return extent_v<remove_reference_t<_Tp>>;
422 else if constexpr (__member_size<_Tp>)
424 else if constexpr (__adl_size<_Tp>)
426 else if constexpr (__sentinel_size<_Tp>)
427 return __detail::__to_unsigned_like(_End{}(__t) - _Begin{}(__t));
435 template<
typename _Tp>
436 requires requires (_Tp& __t) { _Size{}(__t); }
438 operator()[[nodiscard]](_Tp&& __t)
const noexcept(
noexcept(_Size{}(__t)))
440 auto __size = _Size{}(__t);
441 using __size_type =
decltype(__size);
443 if constexpr (integral<__size_type>)
446 if constexpr (__int_traits<__size_type>::__digits
447 < __int_traits<ptrdiff_t>::__digits)
448 return static_cast<ptrdiff_t
>(__size);
450 return static_cast<make_signed_t<__size_type>
>(__size);
452#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
454 else if constexpr (__detail::__is_int128<__size_type>)
455 return static_cast<__int128
>(__size);
458 return __detail::__max_diff_type(__size);
462 template<
typename _Tp>
463 concept __member_empty =
requires(_Tp& __t) { bool(__t.empty()); };
465 template<
typename _Tp>
466 concept __size0_empty =
requires(_Tp& __t) { _Size{}(__t) == 0; };
468 template<
typename _Tp>
469 concept __eq_iter_empty =
requires(_Tp& __t)
471 requires (!is_unbounded_array_v<remove_reference_t<_Tp>>);
473 { _Begin{}(__t) } -> forward_iterator;
475 bool(_Begin{}(__t) == _End{}(__t));
481 template<
typename _Tp>
482 static constexpr bool
485 if constexpr (__member_empty<_Tp>)
486 return noexcept(
bool(std::declval<_Tp&>().
empty()));
487 else if constexpr (__size0_empty<_Tp>)
488 return noexcept(_Size{}(std::declval<_Tp&>()) == 0);
490 return noexcept(bool(_Begin{}(std::declval<_Tp&>())
491 == _End{}(std::declval<_Tp&>())));
495 template<
typename _Tp>
496 requires __member_empty<_Tp> || __size0_empty<_Tp>
497 || __eq_iter_empty<_Tp>
499 operator()[[nodiscard]](_Tp&& __t)
const noexcept(_S_noexcept<_Tp&>())
501 if constexpr (__member_empty<_Tp>)
502 return bool(__t.empty());
503 else if constexpr (__size0_empty<_Tp>)
504 return _Size{}(__t) == 0;
506 return bool(_Begin{}(__t) == _End{}(__t));
510 template<
typename _Tp>
511 concept __pointer_to_object = is_pointer_v<_Tp>
512 && is_object_v<remove_pointer_t<_Tp>>;
514 template<
typename _Tp>
515 concept __member_data =
requires(_Tp& __t)
517 { __decay_copy(__t.data()) } -> __pointer_to_object;
520 template<
typename _Tp>
521 concept __begin_data = contiguous_iterator<__range_iter_t<_Tp>>;
526 template<
typename _Tp>
527 static constexpr bool
530 if constexpr (__member_data<_Tp>)
531 return noexcept(__decay_copy(std::declval<_Tp&>().
data()));
533 return noexcept(_Begin{}(std::declval<_Tp&>()));
537 template<__maybe_borrowed_range _Tp>
538 requires __member_data<_Tp> || __begin_data<_Tp>
540 operator()[[nodiscard]](_Tp&& __t)
const noexcept(_S_noexcept<_Tp>())
542 if constexpr (__member_data<_Tp>)
551 template<
typename _Tp>
554 operator()(_Tp&& __e)
const
555 noexcept(
noexcept(_Data{}(__cust_access::__as_const<_Tp>(__e))))
556 requires requires { _Data{}(__cust_access::__as_const<_Tp>(__e)); }
558 return _Data{}(__cust_access::__as_const<_Tp>(__e));
564 inline namespace __cust
566 inline constexpr __cust_access::_Begin begin{};
567 inline constexpr __cust_access::_End end{};
568 inline constexpr __cust_access::_CBegin cbegin{};
569 inline constexpr __cust_access::_CEnd cend{};
570 inline constexpr __cust_access::_RBegin rbegin{};
571 inline constexpr __cust_access::_REnd rend{};
572 inline constexpr __cust_access::_CRBegin crbegin{};
573 inline constexpr __cust_access::_CREnd crend{};
574 inline constexpr __cust_access::_Size size{};
575 inline constexpr __cust_access::_SSize ssize{};
576 inline constexpr __cust_access::_Empty empty{};
577 inline constexpr __cust_access::_Data data{};
578 inline constexpr __cust_access::_CData cdata{};
582 template<
typename _Tp>
590 template<
typename _Tp>
592 =
range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
594 template<
typename _Tp>
595 using iterator_t = std::__detail::__range_iter_t<_Tp>;
597 template<range _Range>
598 using sentinel_t =
decltype(ranges::end(std::declval<_Range&>()));
600 template<range _Range>
601 using range_difference_t = iter_difference_t<iterator_t<_Range>>;
603 template<range _Range>
604 using range_value_t = iter_value_t<iterator_t<_Range>>;
606 template<range _Range>
607 using range_reference_t = iter_reference_t<iterator_t<_Range>>;
609 template<range _Range>
610 using range_rvalue_reference_t
611 = iter_rvalue_reference_t<iterator_t<_Range>>;
614 template<
typename _Tp>
616 &&
requires(_Tp& __t) { ranges::size(__t); };
618 template<sized_range _Range>
619 using range_size_t =
decltype(ranges::size(std::declval<_Range&>()));
621 template<
typename _Derived>
627 template<
typename _Tp,
typename _Up>
629 void __is_derived_from_view_interface_fn(
const _Tp&,
634 template<
typename _Tp>
635 concept __is_derived_from_view_interface
636 =
requires (_Tp __t) { __is_derived_from_view_interface_fn(__t, __t); };
643 template<
typename _Tp>
645 || __detail::__is_derived_from_view_interface<_Tp>;
648 template<
typename _Tp>
650 =
range<_Tp> && movable<_Tp> && enable_view<_Tp>;
655 template<
typename _Range,
typename _Tp>
660 template<
typename _Tp>
664 template<
typename _Tp>
669 template<
typename _Tp>
674 template<
typename _Tp>
679 template<
typename _Tp>
682 &&
requires(_Tp& __t)
688 template<
typename _Tp>
694 template<
typename _Tp>
695 inline constexpr bool __is_initializer_list =
false;
697 template<
typename _Tp>
698 inline constexpr bool __is_initializer_list<initializer_list<_Tp>> =
true;
702 template<
typename _Tp>
705 || (!
view<remove_cvref_t<_Tp>>
706 && (is_lvalue_reference_v<_Tp>
707 || (movable<remove_reference_t<_Tp>>
708 && !__detail::__is_initializer_list<remove_cvref_t<_Tp>>))));
712 struct __advance_fn final
714 template<input_or_output_iterator _It>
716 operator()(_It& __it, iter_difference_t<_It> __n)
const
718 if constexpr (random_access_iterator<_It>)
720 else if constexpr (bidirectional_iterator<_It>)
742 __glibcxx_assert(__n >= 0);
748 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
750 operator()(_It& __it, _Sent __bound)
const
752 if constexpr (assignable_from<_It&, _Sent>)
754 else if constexpr (sized_sentinel_for<_Sent, _It>)
755 (*
this)(__it, __bound - __it);
758 while (__it != __bound)
763 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
764 constexpr iter_difference_t<_It>
765 operator()(_It& __it, iter_difference_t<_It> __n, _Sent __bound)
const
767 if constexpr (sized_sentinel_for<_Sent, _It>)
769 const auto __diff = __bound - __it;
773 else if (__diff > 0 ? __n >= __diff : __n <= __diff)
775 (*this)(__it, __bound);
778 else if (__n != 0) [[likely]]
781 __glibcxx_assert(__n < 0 == __diff < 0);
789 else if (__it == __bound || __n == 0)
793 iter_difference_t<_It> __m = 0;
799 while (__m != __n && __it != __bound);
802 else if constexpr (bidirectional_iterator<_It> && same_as<_It, _Sent>)
804 iter_difference_t<_It> __m = 0;
810 while (__m != __n && __it != __bound);
816 __glibcxx_assert(__n >= 0);
824 inline constexpr __advance_fn advance{};
826 struct __distance_fn final
828 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
829 requires (!sized_sentinel_for<_Sent, _It>)
830 constexpr iter_difference_t<_It>
831 operator()[[nodiscard]](_It __first, _Sent __last)
const
833 iter_difference_t<_It> __n = 0;
834 while (__first != __last)
842 template<input_or_output_iterator _It, sized_sentinel_for<_It> _Sent>
844 constexpr iter_difference_t<_It>
845 operator()(
const _It& __first,
const _Sent& __last)
const
847 return __last - __first;
850 template<range _Range>
852 constexpr range_difference_t<_Range>
853 operator()(_Range&& __r)
const
855 if constexpr (sized_range<_Range>)
856 return static_cast<range_difference_t<_Range>
>(ranges::size(__r));
858 return (*
this)(ranges::begin(__r), ranges::end(__r));
864 inline constexpr __distance_fn distance{};
866 struct __next_fn final
868 template<input_or_output_iterator _It>
871 operator()(_It __x)
const
877 template<input_or_output_iterator _It>
880 operator()(_It __x, iter_difference_t<_It> __n)
const
882 ranges::advance(__x, __n);
886 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
889 operator()(_It __x, _Sent __bound)
const
891 ranges::advance(__x, __bound);
895 template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
898 operator()(_It __x, iter_difference_t<_It> __n, _Sent __bound)
const
900 ranges::advance(__x, __n, __bound);
907 inline constexpr __next_fn next{};
909 struct __prev_fn final
911 template<b
idirectional_iterator _It>
914 operator()(_It __x)
const
920 template<b
idirectional_iterator _It>
923 operator()(_It __x, iter_difference_t<_It> __n)
const
925 ranges::advance(__x, -__n);
929 template<b
idirectional_iterator _It>
932 operator()(_It __x, iter_difference_t<_It> __n, _It __bound)
const
934 ranges::advance(__x, -__n, __bound);
941 inline constexpr __prev_fn prev{};
946 constexpr dangling()
noexcept =
default;
947 template<
typename... _Args>
948 constexpr dangling(_Args&&...)
noexcept { }
951 template<range _Range>
952 using borrowed_iterator_t = __conditional_t<borrowed_range<_Range>,
957_GLIBCXX_END_NAMESPACE_VERSION
constexpr bool enable_view
[range.view] The ranges::enable_view boolean.
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr reverse_iterator< _Iterator > make_reverse_iterator(_Iterator __i)
Generator function for reverse_iterator.
ISO C++ entities toplevel namespace is std.
bitset< _Nb > operator&(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.
__numeric_traits_integer< _Tp > __int_traits
Convenience alias for __numeric_traits<integer-type>.
The ranges::view_interface class template.
[range.view] The ranges::view_base type.
Type returned by algorithms instead of a dangling iterator or subrange.
[concept.same], concept same_as
[concept.derived], concept derived_from
[concept.constructible], concept constructible_from
[range.range] The range concept.
[range.range] The borrowed_range concept.
[range.sized] The sized_range concept.
[range.view] The ranges::view concept.
A range for which ranges::begin returns an output iterator.
A range for which ranges::begin returns an input iterator.
A range for which ranges::begin returns a forward iterator.
A range for which ranges::begin returns a bidirectional iterator.
A range for which ranges::begin returns a random access iterator.
A range for which ranges::begin returns a contiguous iterator.
A range for which ranges::begin and ranges::end return the same type.
A range which can be safely converted to a view.