30#ifndef _GLIBCXX_RANGES
31#define _GLIBCXX_RANGES 1
33#if __cplusplus > 201703L
35#pragma GCC system_header
48#if __cplusplus > 202002L
60namespace std _GLIBCXX_VISIBILITY(default)
62_GLIBCXX_BEGIN_NAMESPACE_VERSION
77 template<
typename _Tp>
requires is_object_v<_Tp>
82 static constexpr _Tp* begin()
noexcept {
return nullptr; }
83 static constexpr _Tp* end()
noexcept {
return nullptr; }
84 static constexpr _Tp* data()
noexcept {
return nullptr; }
85 static constexpr size_t size()
noexcept {
return 0; }
86 static constexpr bool empty()
noexcept {
return true; }
89 template<
typename _Tp>
90 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> =
true;
94 template<
typename _Tp>
97 template<__boxable _Tp>
104 noexcept(is_nothrow_default_constructible_v<_Tp>)
109 __box(
const __box&) =
default;
110 __box(__box&&) =
default;
118 operator=(
const __box& __that)
119 noexcept(is_nothrow_copy_constructible_v<_Tp>)
120 requires (!copyable<_Tp>)
125 this->emplace(*__that);
133 operator=(__box&& __that)
134 noexcept(is_nothrow_move_constructible_v<_Tp>)
135 requires (!movable<_Tp>)
152 template<__boxable _Tp>
153 requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
154 && is_nothrow_copy_constructible_v<_Tp>)
158 [[no_unique_address]] _Tp _M_value = _Tp();
161 __box()
requires default_initializable<_Tp> = default;
164 __box(const _Tp& __t)
165 noexcept(is_nothrow_copy_constructible_v<_Tp>)
171 noexcept(is_nothrow_move_constructible_v<_Tp>)
175 template<
typename... _Args>
176 requires constructible_from<_Tp, _Args...>
178 __box(in_place_t, _Args&&... __args)
179 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
180 : _M_value(std::forward<_Args>(__args)...)
183 __box(
const __box&) =
default;
184 __box(__box&&) =
default;
185 __box& operator=(
const __box&)
requires copyable<_Tp> =
default;
186 __box& operator=(__box&&)
requires copyable<_Tp> = default;
191 operator=(const __box& __that) noexcept
193 static_assert(is_nothrow_copy_constructible_v<_Tp>);
204 operator=(__box&& __that)
noexcept
206 static_assert(is_nothrow_move_constructible_v<_Tp>);
216 has_value() const noexcept
228 operator->() noexcept
232 operator->() const noexcept
238 template<copy_constructible _Tp>
requires is_object_v<_Tp>
246 noexcept(is_nothrow_copy_constructible_v<_Tp>)
252 noexcept(is_nothrow_move_constructible_v<_Tp>)
258 template<
typename... _Args>
262 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
263 : _M_value{in_place, std::forward<_Args>(__args)...}
271 begin()
const noexcept
276 {
return data() + 1; }
280 {
return data() + 1; }
282 static constexpr size_t
288 {
return _M_value.operator->(); }
291 data()
const noexcept
292 {
return _M_value.operator->(); }
295 [[no_unique_address]] __detail::__box<_Tp> _M_value;
298 template<
typename _Tp>
303 template<
typename _Wp>
304 constexpr auto __to_signed_like(_Wp __w)
noexcept
306 if constexpr (!integral<_Wp>)
307 return iter_difference_t<_Wp>();
308 else if constexpr (
sizeof(iter_difference_t<_Wp>) >
sizeof(_Wp))
309 return iter_difference_t<_Wp>(__w);
310 else if constexpr (
sizeof(ptrdiff_t) >
sizeof(_Wp))
311 return ptrdiff_t(__w);
312 else if constexpr (
sizeof(
long long) >
sizeof(_Wp))
313 return (
long long)(__w);
314#ifdef __SIZEOF_INT128__
315 else if constexpr (__SIZEOF_INT128__ >
sizeof(_Wp))
316 return __int128(__w);
319 return __max_diff_type(__w);
322 template<
typename _Wp>
323 using __iota_diff_t =
decltype(__to_signed_like(std::declval<_Wp>()));
325 template<
typename _It>
326 concept __decrementable = incrementable<_It>
329 { --__i } -> same_as<_It&>;
330 { __i-- } -> same_as<_It>;
333 template<
typename _It>
334 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
335 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
337 { __i += __n } -> same_as<_It&>;
338 { __i -= __n } -> same_as<_It&>;
342 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
345 template<
typename _Winc>
346 struct __iota_view_iter_cat
349 template<incrementable _Winc>
350 struct __iota_view_iter_cat<_Winc>
351 {
using iterator_category = input_iterator_tag; };
354 template<weakly_incrementable _Winc,
355 semiregular _Bound = unreachable_sentinel_t>
356 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
358 class iota_view :
public view_interface<iota_view<_Winc, _Bound>>
363 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
369 using namespace __detail;
370 if constexpr (__advanceable<_Winc>)
371 return random_access_iterator_tag{};
372 else if constexpr (__decrementable<_Winc>)
373 return bidirectional_iterator_tag{};
374 else if constexpr (incrementable<_Winc>)
375 return forward_iterator_tag{};
377 return input_iterator_tag{};
381 using iterator_concept =
decltype(_S_iter_concept());
383 using value_type = _Winc;
384 using difference_type = __detail::__iota_diff_t<_Winc>;
386 _Iterator()
requires default_initializable<_Winc> = default;
389 _Iterator(_Winc __value)
390 : _M_value(__value) { }
393 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
408 operator++(
int)
requires incrementable<_Winc>
416 operator--()
requires __detail::__decrementable<_Winc>
423 operator--(
int)
requires __detail::__decrementable<_Winc>
431 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
433 using __detail::__is_integer_like;
434 using __detail::__is_signed_integer_like;
435 if constexpr (__is_integer_like<_Winc>
436 && !__is_signed_integer_like<_Winc>)
438 if (__n >= difference_type(0))
439 _M_value +=
static_cast<_Winc
>(__n);
441 _M_value -=
static_cast<_Winc
>(-__n);
449 operator-=(difference_type __n)
requires __detail::__advanceable<_Winc>
451 using __detail::__is_integer_like;
452 using __detail::__is_signed_integer_like;
453 if constexpr (__is_integer_like<_Winc>
454 && !__is_signed_integer_like<_Winc>)
456 if (__n >= difference_type(0))
457 _M_value -=
static_cast<_Winc
>(__n);
459 _M_value +=
static_cast<_Winc
>(-__n);
467 operator[](difference_type __n)
const
468 requires __detail::__advanceable<_Winc>
469 {
return _Winc(_M_value + __n); }
471 friend constexpr bool
472 operator==(
const _Iterator& __x,
const _Iterator& __y)
473 requires equality_comparable<_Winc>
474 {
return __x._M_value == __y._M_value; }
476 friend constexpr bool
477 operator<(
const _Iterator& __x,
const _Iterator& __y)
478 requires totally_ordered<_Winc>
479 {
return __x._M_value < __y._M_value; }
481 friend constexpr bool
482 operator>(
const _Iterator& __x,
const _Iterator& __y)
483 requires totally_ordered<_Winc>
484 {
return __y < __x; }
486 friend constexpr bool
487 operator<=(
const _Iterator& __x,
const _Iterator& __y)
488 requires totally_ordered<_Winc>
489 {
return !(__y < __x); }
491 friend constexpr bool
492 operator>=(
const _Iterator& __x,
const _Iterator& __y)
493 requires totally_ordered<_Winc>
494 {
return !(__x < __y); }
496#ifdef __cpp_lib_three_way_comparison
497 friend constexpr auto
498 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
499 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
500 {
return __x._M_value <=> __y._M_value; }
503 friend constexpr _Iterator
504 operator+(_Iterator __i, difference_type __n)
505 requires __detail::__advanceable<_Winc>
511 friend constexpr _Iterator
512 operator+(difference_type __n, _Iterator __i)
513 requires __detail::__advanceable<_Winc>
514 {
return __i += __n; }
516 friend constexpr _Iterator
517 operator-(_Iterator __i, difference_type __n)
518 requires __detail::__advanceable<_Winc>
524 friend constexpr difference_type
525 operator-(
const _Iterator& __x,
const _Iterator& __y)
526 requires __detail::__advanceable<_Winc>
528 using __detail::__is_integer_like;
529 using __detail::__is_signed_integer_like;
530 using _Dt = difference_type;
531 if constexpr (__is_integer_like<_Winc>)
533 if constexpr (__is_signed_integer_like<_Winc>)
534 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
536 return (__y._M_value > __x._M_value)
537 ? _Dt(-_Dt(__y._M_value - __x._M_value))
538 : _Dt(__x._M_value - __y._M_value);
541 return __x._M_value - __y._M_value;
545 _Winc _M_value = _Winc();
555 _M_equal(
const _Iterator& __x)
const
556 {
return __x._M_value == _M_bound; }
559 _M_distance_from(
const _Iterator& __x)
const
560 {
return _M_bound - __x._M_value; }
562 _Bound _M_bound = _Bound();
565 _Sentinel() =
default;
568 _Sentinel(_Bound __bound)
569 : _M_bound(__bound) { }
571 friend constexpr bool
572 operator==(
const _Iterator& __x,
const _Sentinel& __y)
573 {
return __y._M_equal(__x); }
575 friend constexpr iter_difference_t<_Winc>
576 operator-(
const _Iterator& __x,
const _Sentinel& __y)
577 requires sized_sentinel_for<_Bound, _Winc>
578 {
return -__y._M_distance_from(__x); }
580 friend constexpr iter_difference_t<_Winc>
581 operator-(
const _Sentinel& __x,
const _Iterator& __y)
582 requires sized_sentinel_for<_Bound, _Winc>
583 {
return __x._M_distance_from(__y); }
588 _Winc _M_value = _Winc();
589 [[no_unique_address]] _Bound _M_bound = _Bound();
592 iota_view()
requires default_initializable<_Winc> = default;
595 iota_view(_Winc __value)
600 iota_view(type_identity_t<_Winc> __value,
601 type_identity_t<_Bound> __bound)
602 : _M_value(__value), _M_bound(__bound)
604 if constexpr (totally_ordered_with<_Winc, _Bound>)
605 __glibcxx_assert(
bool(__value <= __bound) );
609 iota_view(_Iterator __first, _Iterator __last)
610 requires same_as<_Winc, _Bound>
611 : iota_view(__first._M_value, __last._M_value)
615 iota_view(_Iterator __first, unreachable_sentinel_t __last)
616 requires same_as<_Bound, unreachable_sentinel_t>
617 : iota_view(__first._M_value, __last)
621 iota_view(_Iterator __first, _Sentinel __last)
622 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
623 : iota_view(__first._M_value, __last._M_bound)
627 begin()
const {
return _Iterator{_M_value}; }
632 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
633 return unreachable_sentinel;
635 return _Sentinel{_M_bound};
639 end() const requires same_as<_Winc, _Bound>
640 {
return _Iterator{_M_bound}; }
644 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
645 || (integral<_Winc> && integral<_Bound>)
646 || sized_sentinel_for<_Bound, _Winc>
648 using __detail::__is_integer_like;
649 using __detail::__to_unsigned_like;
650 if constexpr (integral<_Winc> && integral<_Bound>)
653 return _Up(_M_bound) - _Up(_M_value);
655 else if constexpr (__is_integer_like<_Winc>)
656 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
658 return __to_unsigned_like(_M_bound - _M_value);
662 template<
typename _Winc,
typename _Bound>
663 requires (!__detail::__is_integer_like<_Winc>
664 || !__detail::__is_integer_like<_Bound>
665 || (__detail::__is_signed_integer_like<_Winc>
666 == __detail::__is_signed_integer_like<_Bound>))
667 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
669 template<
typename _Winc,
typename _Bound>
670 inline constexpr bool
671 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
675 template<
typename _Tp>
676 inline constexpr empty_view<_Tp>
empty{};
680 template<
typename _Tp>
683 operator()(_Tp&& __e)
const
684 noexcept(
noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
685 {
return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
688 inline constexpr _Single single{};
692 template<
typename _Tp>
695 operator()(_Tp&& __e)
const
696 {
return iota_view(std::forward<_Tp>(__e)); }
698 template<
typename _Tp,
typename _Up>
701 operator()(_Tp&& __e, _Up&& __f)
const
702 {
return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
705 inline constexpr _Iota
iota{};
711 template<
typename _Val,
typename _CharT,
typename _Traits>
712 concept __stream_extractable
713 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
716 template<movable _Val,
typename _CharT,
717 typename _Traits = char_traits<_CharT>>
718 requires default_initializable<_Val>
719 && __detail::__stream_extractable<_Val, _CharT, _Traits>
720 class basic_istream_view
721 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
725 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
732 *_M_stream >> _M_object;
733 return _Iterator{
this};
736 constexpr default_sentinel_t
741 basic_istream<_CharT, _Traits>* _M_stream;
742 _Val _M_object = _Val();
747 using iterator_concept = input_iterator_tag;
748 using difference_type = ptrdiff_t;
749 using value_type = _Val;
752 _Iterator(basic_istream_view* __parent) noexcept
753 : _M_parent(__parent)
756 _Iterator(
const _Iterator&) =
delete;
757 _Iterator(_Iterator&&) =
default;
758 _Iterator& operator=(
const _Iterator&) =
delete;
759 _Iterator& operator=(_Iterator&&) =
default;
764 *_M_parent->_M_stream >> _M_parent->_M_object;
774 {
return _M_parent->_M_object; }
777 operator==(
const _Iterator& __x, default_sentinel_t)
778 {
return __x._M_at_end(); }
781 basic_istream_view* _M_parent;
785 {
return !*_M_parent->_M_stream; }
791 template<
typename _Val>
792 using istream_view = basic_istream_view<_Val, char>;
794 template<
typename _Val>
795 using wistream_view = basic_istream_view<_Val, wchar_t>;
799 template<
typename _Tp>
802 template<
typename _CharT,
typename _Traits>
805 operator()(basic_istream<_CharT, _Traits>& __e)
const
806 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
809 template<
typename _Tp>
810 inline constexpr _Istream<_Tp>
istream;
824 template<
bool _Present,
typename _Tp>
825 using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;
828 template<
bool _Const,
typename _Tp>
829 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
834using __detail::__maybe_const_t;
836namespace views::__adaptor
839 template<
typename _Adaptor,
typename... _Args>
840 concept __adaptor_invocable
841 =
requires { std::declval<_Adaptor>()(declval<_Args>()...); };
845 template<
typename _Adaptor,
typename... _Args>
846 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
847 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
848 && (constructible_from<decay_t<_Args>, _Args> && ...);
850 template<
typename _Adaptor,
typename... _Args>
853 template<
typename _Lhs,
typename _Rhs>
861 struct _RangeAdaptorClosure
864 template<
typename _Self,
typename _Range>
865 requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
866 && __adaptor_invocable<_Self, _Range>
867 friend constexpr auto
869 {
return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
873 template<
typename _Lhs,
typename _Rhs>
874 requires derived_from<_Lhs, _RangeAdaptorClosure>
875 && derived_from<_Rhs, _RangeAdaptorClosure>
876 friend constexpr auto
892 template<
typename _Derived>
897 template<
typename... _Args>
898 requires __adaptor_partial_app_viable<_Derived, _Args...>
900 operator()(_Args&&... __args)
const
902 return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
909 template<
typename _Adaptor>
910 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
914 template<
typename _Adaptor,
typename... _Args>
915 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
916 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
920 template<
typename _Adaptor,
typename... _Args>
921 struct _Partial : _RangeAdaptorClosure
923 tuple<_Args...> _M_args;
926 _Partial(_Args... __args)
927 : _M_args(
std::
move(__args)...)
932 template<
typename _Range>
933 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
935 operator()(_Range&& __r)
const &
937 auto __forwarder = [&__r] (
const auto&... __args) {
938 return _Adaptor{}(std::forward<_Range>(__r), __args...);
940 return std::apply(__forwarder, _M_args);
943 template<
typename _Range>
944 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
946 operator()(_Range&& __r) &&
948 auto __forwarder = [&__r] (
auto&... __args) {
949 return _Adaptor{}(std::forward<_Range>(__r),
std::move(__args)...);
951 return std::apply(__forwarder, _M_args);
954 template<
typename _Range>
956 operator()(_Range&& __r)
const && =
delete;
961 template<
typename _Adaptor,
typename _Arg>
962 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
971 template<
typename _Range>
972 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
974 operator()(_Range&& __r)
const &
975 {
return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
977 template<
typename _Range>
978 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
980 operator()(_Range&& __r) &&
981 {
return _Adaptor{}(std::forward<_Range>(__r),
std::move(_M_arg)); }
983 template<
typename _Range>
985 operator()(_Range&& __r)
const && =
delete;
992 template<
typename _Adaptor,
typename... _Args>
993 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
994 && (is_trivially_copyable_v<_Args> && ...)
995 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
997 tuple<_Args...> _M_args;
1000 _Partial(_Args... __args)
1001 : _M_args(
std::
move(__args)...)
1006 template<
typename _Range>
1007 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1009 operator()(_Range&& __r)
const
1011 auto __forwarder = [&__r] (
const auto&... __args) {
1012 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1014 return std::apply(__forwarder, _M_args);
1017 static constexpr bool _S_has_simple_call_op =
true;
1022 template<
typename _Adaptor,
typename _Arg>
1023 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1024 && is_trivially_copyable_v<_Arg>
1025 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
1030 _Partial(_Arg __arg)
1034 template<
typename _Range>
1035 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1037 operator()(_Range&& __r)
const
1038 {
return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1040 static constexpr bool _S_has_simple_call_op =
true;
1043 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1044 concept __pipe_invocable
1045 =
requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1049 template<
typename _Lhs,
typename _Rhs>
1050 struct _Pipe : _RangeAdaptorClosure
1052 [[no_unique_address]] _Lhs _M_lhs;
1053 [[no_unique_address]] _Rhs _M_rhs;
1056 _Pipe(_Lhs __lhs, _Rhs __rhs)
1062 template<
typename _Range>
1063 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1065 operator()(_Range&& __r)
const &
1066 {
return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1068 template<
typename _Range>
1069 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1071 operator()(_Range&& __r) &&
1074 template<
typename _Range>
1076 operator()(_Range&& __r)
const && =
delete;
1083 template<
typename _Lhs,
typename _Rhs>
1084 requires __closure_has_simple_call_op<_Lhs>
1085 && __closure_has_simple_call_op<_Rhs>
1086 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
1088 [[no_unique_address]] _Lhs _M_lhs;
1089 [[no_unique_address]] _Rhs _M_rhs;
1092 _Pipe(_Lhs __lhs, _Rhs __rhs)
1096 template<
typename _Range>
1097 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1099 operator()(_Range&& __r)
const
1100 {
return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1102 static constexpr bool _S_has_simple_call_op =
true;
1106 template<range _Range>
requires is_object_v<_Range>
1107 class ref_view :
public view_interface<ref_view<_Range>>
1112 static void _S_fun(_Range&);
1113 static void _S_fun(_Range&&) =
delete;
1116 template<__detail::__different_from<ref_view> _Tp>
1117 requires convertible_to<_Tp, _Range&>
1118 &&
requires { _S_fun(declval<_Tp>()); }
1121 noexcept(
noexcept(
static_cast<_Range&
>(std::declval<_Tp>())))
1129 constexpr iterator_t<_Range>
1131 {
return ranges::begin(*_M_r); }
1133 constexpr sentinel_t<_Range>
1135 {
return ranges::end(*_M_r); }
1138 empty() const requires requires { ranges::empty(*_M_r); }
1139 {
return ranges::empty(*_M_r); }
1142 size() const requires sized_range<_Range>
1143 {
return ranges::size(*_M_r); }
1146 data() const requires contiguous_range<_Range>
1147 {
return ranges::data(*_M_r); }
1150 template<
typename _Range>
1151 ref_view(_Range&) -> ref_view<_Range>;
1153 template<
typename _Tp>
1154 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1156 template<range _Range>
1157 requires movable<_Range>
1158 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1159 class owning_view :
public view_interface<owning_view<_Range>>
1162 _Range _M_r = _Range();
1165 owning_view()
requires default_initializable<_Range> = default;
1168 owning_view(_Range&& __t)
1169 noexcept(is_nothrow_move_constructible_v<_Range>)
1173 owning_view(owning_view&&) =
default;
1174 owning_view& operator=(owning_view&&) =
default;
1180 constexpr const _Range&
1181 base() const& noexcept
1188 constexpr const _Range&&
1189 base() const&& noexcept
1192 constexpr iterator_t<_Range>
1194 {
return ranges::begin(_M_r); }
1196 constexpr sentinel_t<_Range>
1198 {
return ranges::end(_M_r); }
1201 begin() const requires range<const _Range>
1202 {
return ranges::begin(_M_r); }
1205 end() const requires range<const _Range>
1206 {
return ranges::end(_M_r); }
1209 empty()
requires requires { ranges::empty(_M_r); }
1210 {
return ranges::empty(_M_r); }
1213 empty() const requires requires { ranges::empty(_M_r); }
1214 {
return ranges::empty(_M_r); }
1217 size()
requires sized_range<_Range>
1218 {
return ranges::size(_M_r); }
1221 size() const requires sized_range<const _Range>
1222 {
return ranges::size(_M_r); }
1225 data()
requires contiguous_range<_Range>
1226 {
return ranges::data(_M_r); }
1229 data() const requires contiguous_range<const _Range>
1230 {
return ranges::data(_M_r); }
1233 template<
typename _Tp>
1234 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1235 = enable_borrowed_range<_Tp>;
1241 template<
typename _Range>
1242 concept __can_ref_view =
requires { ref_view{std::declval<_Range>()}; };
1244 template<
typename _Range>
1245 concept __can_owning_view =
requires { owning_view{std::declval<_Range>()}; };
1248 struct _All : __adaptor::_RangeAdaptorClosure
1250 template<
typename _Range>
1251 static constexpr bool
1254 if constexpr (view<decay_t<_Range>>)
1255 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1256 else if constexpr (__detail::__can_ref_view<_Range>)
1259 return noexcept(owning_view{std::declval<_Range>()});
1262 template<viewable_range _Range>
1263 requires view<decay_t<_Range>>
1264 || __detail::__can_ref_view<_Range>
1265 || __detail::__can_owning_view<_Range>
1267 operator() [[nodiscard]] (_Range&& __r)
const
1268 noexcept(_S_noexcept<_Range>())
1270 if constexpr (view<decay_t<_Range>>)
1271 return std::forward<_Range>(__r);
1272 else if constexpr (__detail::__can_ref_view<_Range>)
1273 return ref_view{std::forward<_Range>(__r)};
1275 return owning_view{std::forward<_Range>(__r)};
1278 static constexpr bool _S_has_simple_call_op =
true;
1281 inline constexpr _All all;
1283 template<viewable_range _Range>
1284 using all_t =
decltype(all(std::declval<_Range>()));
1289 template<
typename _Tp>
1290 struct __non_propagating_cache
1298 template<
typename _Tp>
1299 requires is_object_v<_Tp>
1300 struct __non_propagating_cache<_Tp>
1301 :
protected _Optional_base<_Tp>
1303 __non_propagating_cache() =
default;
1306 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1310 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1311 { __other._M_reset(); }
1313 constexpr __non_propagating_cache&
1314 operator=(
const __non_propagating_cache& __other)
noexcept
1321 constexpr __non_propagating_cache&
1322 operator=(__non_propagating_cache&& __other)
noexcept
1329 constexpr __non_propagating_cache&
1330 operator=(_Tp __val)
1333 this->_M_payload._M_construct(
std::move(__val));
1338 operator bool() const noexcept
1339 {
return this->_M_is_engaged(); }
1343 {
return this->_M_get(); }
1345 constexpr const _Tp&
1347 {
return this->_M_get(); }
1349 template<
typename _Iter>
1351 _M_emplace_deref(
const _Iter& __i)
1354 auto __f = [] (
auto& __x) {
return *__x; };
1355 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1356 return this->_M_get();
1360 template<range _Range>
1361 struct _CachedPosition
1364 _M_has_value()
const
1367 constexpr iterator_t<_Range>
1368 _M_get(
const _Range&)
const
1370 __glibcxx_assert(
false);
1371 __builtin_unreachable();
1375 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1379 template<forward_range _Range>
1380 struct _CachedPosition<_Range>
1381 :
protected __non_propagating_cache<iterator_t<_Range>>
1384 _M_has_value()
const
1385 {
return this->_M_is_engaged(); }
1387 constexpr iterator_t<_Range>
1388 _M_get(
const _Range&)
const
1390 __glibcxx_assert(_M_has_value());
1395 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1397 __glibcxx_assert(!_M_has_value());
1400 this->_M_payload._M_engaged =
true;
1404 template<random_access_range _Range>
1405 requires (
sizeof(range_difference_t<_Range>)
1406 <=
sizeof(iterator_t<_Range>))
1407 struct _CachedPosition<_Range>
1410 range_difference_t<_Range> _M_offset = -1;
1413 _CachedPosition() =
default;
1416 _CachedPosition(
const _CachedPosition&) =
default;
1419 _CachedPosition(_CachedPosition&& __other)
noexcept
1422 constexpr _CachedPosition&
1423 operator=(
const _CachedPosition&) =
default;
1425 constexpr _CachedPosition&
1426 operator=(_CachedPosition&& __other)
noexcept
1429 _M_offset = __other._M_offset;
1430 __other._M_offset = -1;
1435 _M_has_value()
const
1436 {
return _M_offset >= 0; }
1438 constexpr iterator_t<_Range>
1439 _M_get(_Range& __r)
const
1441 __glibcxx_assert(_M_has_value());
1442 return ranges::begin(__r) + _M_offset;
1446 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1448 __glibcxx_assert(!_M_has_value());
1449 _M_offset = __it - ranges::begin(__r);
1456 template<
typename _Base>
1457 struct __filter_view_iter_cat
1460 template<forward_range _Base>
1461 struct __filter_view_iter_cat<_Base>
1467 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1468 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1469 return bidirectional_iterator_tag{};
1470 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1471 return forward_iterator_tag{};
1476 using iterator_category =
decltype(_S_iter_cat());
1480 template<input_range _Vp,
1481 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1482 requires view<_Vp> && is_object_v<_Pred>
1483 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1488 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1491 static constexpr auto
1494 if constexpr (bidirectional_range<_Vp>)
1495 return bidirectional_iterator_tag{};
1496 else if constexpr (forward_range<_Vp>)
1497 return forward_iterator_tag{};
1499 return input_iterator_tag{};
1504 using _Vp_iter = iterator_t<_Vp>;
1506 _Vp_iter _M_current = _Vp_iter();
1507 filter_view* _M_parent =
nullptr;
1510 using iterator_concept =
decltype(_S_iter_concept());
1512 using value_type = range_value_t<_Vp>;
1513 using difference_type = range_difference_t<_Vp>;
1515 _Iterator()
requires default_initializable<_Vp_iter> = default;
1518 _Iterator(filter_view* __parent, _Vp_iter __current)
1519 : _M_current(
std::
move(__current)),
1523 constexpr const _Vp_iter&
1524 base() const & noexcept
1525 {
return _M_current; }
1531 constexpr range_reference_t<_Vp>
1533 {
return *_M_current; }
1537 requires __detail::__has_arrow<_Vp_iter>
1538 && copyable<_Vp_iter>
1539 {
return _M_current; }
1541 constexpr _Iterator&
1544 _M_current = ranges::find_if(
std::move(++_M_current),
1545 ranges::end(_M_parent->_M_base),
1546 std::ref(*_M_parent->_M_pred));
1555 operator++(
int)
requires forward_range<_Vp>
1562 constexpr _Iterator&
1563 operator--()
requires bidirectional_range<_Vp>
1572 operator--(
int)
requires bidirectional_range<_Vp>
1579 friend constexpr bool
1580 operator==(
const _Iterator& __x,
const _Iterator& __y)
1581 requires equality_comparable<_Vp_iter>
1582 {
return __x._M_current == __y._M_current; }
1584 friend constexpr range_rvalue_reference_t<_Vp>
1585 iter_move(
const _Iterator& __i)
1586 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1587 {
return ranges::iter_move(__i._M_current); }
1589 friend constexpr void
1590 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1591 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1592 requires indirectly_swappable<_Vp_iter>
1593 { ranges::iter_swap(__x._M_current, __y._M_current); }
1599 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1602 __equal(
const _Iterator& __i)
const
1603 {
return __i._M_current == _M_end; }
1606 _Sentinel() =
default;
1609 _Sentinel(filter_view* __parent)
1610 : _M_end(ranges::
end(__parent->_M_base))
1613 constexpr sentinel_t<_Vp>
1617 friend constexpr bool
1618 operator==(
const _Iterator& __x,
const _Sentinel& __y)
1619 {
return __y.__equal(__x); }
1622 _Vp _M_base = _Vp();
1623 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1624 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1627 filter_view()
requires (default_initializable<_Vp>
1628 && default_initializable<_Pred>)
1632 filter_view(_Vp
__base, _Pred __pred)
1637 base() const& requires copy_constructible<_Vp>
1644 constexpr const _Pred&
1646 {
return *_M_pred; }
1651 if (_M_cached_begin._M_has_value())
1652 return {
this, _M_cached_begin._M_get(_M_base)};
1654 __glibcxx_assert(_M_pred.has_value());
1655 auto __it = ranges::find_if(ranges::begin(_M_base),
1656 ranges::end(_M_base),
1657 std::ref(*_M_pred));
1658 _M_cached_begin._M_set(_M_base, __it);
1665 if constexpr (common_range<_Vp>)
1666 return _Iterator{
this, ranges::end(_M_base)};
1668 return _Sentinel{
this};
1672 template<
typename _Range,
typename _Pred>
1673 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1679 template<
typename _Range,
typename _Pred>
1680 concept __can_filter_view
1681 =
requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1684 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1686 template<viewable_range _Range,
typename _Pred>
1687 requires __detail::__can_filter_view<_Range, _Pred>
1689 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1691 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1694 using _RangeAdaptor<_Filter>::operator();
1695 static constexpr int _S_arity = 2;
1696 static constexpr bool _S_has_simple_extra_args =
true;
1699 inline constexpr _Filter filter;
1702 template<input_range _Vp, copy_constructible _Fp>
1703 requires view<_Vp> && is_object_v<_Fp>
1704 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1706 range_reference_t<_Vp>>>
1707 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
1710 template<
bool _Const>
1711 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1713 template<
bool _Const>
1717 template<
bool _Const>
1718 requires forward_range<_Base<_Const>>
1719 struct __iter_cat<_Const>
1725 using _Base = transform_view::_Base<_Const>;
1726 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1727 if constexpr (is_lvalue_reference_v<_Res>)
1730 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1731 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1732 return random_access_iterator_tag{};
1737 return input_iterator_tag{};
1740 using iterator_category =
decltype(_S_iter_cat());
1743 template<
bool _Const>
1746 template<
bool _Const>
1747 struct _Iterator : __iter_cat<_Const>
1750 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1751 using _Base = transform_view::_Base<_Const>;
1756 if constexpr (random_access_range<_Base>)
1757 return random_access_iterator_tag{};
1758 else if constexpr (bidirectional_range<_Base>)
1759 return bidirectional_iterator_tag{};
1760 else if constexpr (forward_range<_Base>)
1761 return forward_iterator_tag{};
1763 return input_iterator_tag{};
1766 using _Base_iter = iterator_t<_Base>;
1768 _Base_iter _M_current = _Base_iter();
1769 _Parent* _M_parent =
nullptr;
1772 using iterator_concept =
decltype(_S_iter_concept());
1775 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1776 using difference_type = range_difference_t<_Base>;
1778 _Iterator()
requires default_initializable<_Base_iter> = default;
1781 _Iterator(_Parent* __parent, _Base_iter __current)
1782 : _M_current(
std::
move(__current)),
1787 _Iterator(_Iterator<!_Const> __i)
1789 && convertible_to<iterator_t<_Vp>, _Base_iter>
1790 : _M_current(
std::move(__i._M_current)), _M_parent(__i._M_parent)
1793 constexpr const _Base_iter&
1794 base() const & noexcept
1795 {
return _M_current; }
1797 constexpr _Base_iter
1801 constexpr decltype(
auto)
1803 noexcept(
noexcept(
std::__invoke(*_M_parent->_M_fun, *_M_current)))
1806 constexpr _Iterator&
1818 operator++(
int)
requires forward_range<_Base>
1825 constexpr _Iterator&
1826 operator--()
requires bidirectional_range<_Base>
1833 operator--(
int)
requires bidirectional_range<_Base>
1840 constexpr _Iterator&
1841 operator+=(difference_type __n)
requires random_access_range<_Base>
1847 constexpr _Iterator&
1848 operator-=(difference_type __n)
requires random_access_range<_Base>
1854 constexpr decltype(
auto)
1855 operator[](difference_type __n)
const
1856 requires random_access_range<_Base>
1857 {
return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1859 friend constexpr bool
1860 operator==(
const _Iterator& __x,
const _Iterator& __y)
1861 requires equality_comparable<_Base_iter>
1862 {
return __x._M_current == __y._M_current; }
1864 friend constexpr bool
1865 operator<(
const _Iterator& __x,
const _Iterator& __y)
1866 requires random_access_range<_Base>
1867 {
return __x._M_current < __y._M_current; }
1869 friend constexpr bool
1870 operator>(
const _Iterator& __x,
const _Iterator& __y)
1871 requires random_access_range<_Base>
1872 {
return __y < __x; }
1874 friend constexpr bool
1875 operator<=(
const _Iterator& __x,
const _Iterator& __y)
1876 requires random_access_range<_Base>
1877 {
return !(__y < __x); }
1879 friend constexpr bool
1880 operator>=(
const _Iterator& __x,
const _Iterator& __y)
1881 requires random_access_range<_Base>
1882 {
return !(__x < __y); }
1884#ifdef __cpp_lib_three_way_comparison
1885 friend constexpr auto
1886 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
1887 requires random_access_range<_Base>
1888 && three_way_comparable<_Base_iter>
1889 {
return __x._M_current <=> __y._M_current; }
1892 friend constexpr _Iterator
1893 operator+(_Iterator __i, difference_type __n)
1894 requires random_access_range<_Base>
1895 {
return {__i._M_parent, __i._M_current + __n}; }
1897 friend constexpr _Iterator
1898 operator+(difference_type __n, _Iterator __i)
1899 requires random_access_range<_Base>
1900 {
return {__i._M_parent, __i._M_current + __n}; }
1902 friend constexpr _Iterator
1903 operator-(_Iterator __i, difference_type __n)
1904 requires random_access_range<_Base>
1905 {
return {__i._M_parent, __i._M_current - __n}; }
1909 friend constexpr difference_type
1910 operator-(
const _Iterator& __x,
const _Iterator& __y)
1911 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1912 {
return __x._M_current - __y._M_current; }
1914 friend constexpr decltype(
auto)
1915 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
1917 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
1923 friend _Iterator<!_Const>;
1924 template<
bool>
friend struct _Sentinel;
1927 template<
bool _Const>
1931 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1932 using _Base = transform_view::_Base<_Const>;
1934 template<
bool _Const2>
1936 __distance_from(
const _Iterator<_Const2>& __i)
const
1937 {
return _M_end - __i._M_current; }
1939 template<
bool _Const2>
1941 __equal(
const _Iterator<_Const2>& __i)
const
1942 {
return __i._M_current == _M_end; }
1944 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1947 _Sentinel() =
default;
1950 _Sentinel(sentinel_t<_Base> __end)
1955 _Sentinel(_Sentinel<!_Const> __i)
1957 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1961 constexpr sentinel_t<_Base>
1965 template<
bool _Const2>
1966 requires sentinel_for<sentinel_t<_Base>,
1967 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1968 friend constexpr bool
1969 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
1970 {
return __y.__equal(__x); }
1972 template<
bool _Const2,
1973 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1974 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1975 friend constexpr range_difference_t<_Base2>
1976 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
1977 {
return -__y.__distance_from(__x); }
1979 template<
bool _Const2,
1980 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1981 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1982 friend constexpr range_difference_t<_Base2>
1983 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
1984 {
return __y.__distance_from(__x); }
1986 friend _Sentinel<!_Const>;
1989 _Vp _M_base = _Vp();
1990 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
1993 transform_view()
requires (default_initializable<_Vp>
1994 && default_initializable<_Fp>)
1998 transform_view(_Vp
__base, _Fp __fun)
2003 base() const& requires copy_constructible<_Vp>
2004 {
return _M_base ; }
2010 constexpr _Iterator<false>
2012 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2014 constexpr _Iterator<true>
2016 requires range<const _Vp>
2017 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2018 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2020 constexpr _Sentinel<false>
2022 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2024 constexpr _Iterator<false>
2025 end()
requires common_range<_Vp>
2026 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2028 constexpr _Sentinel<true>
2030 requires range<const _Vp>
2031 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2032 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2034 constexpr _Iterator<true>
2036 requires common_range<const _Vp>
2037 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2038 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2041 size()
requires sized_range<_Vp>
2042 {
return ranges::size(_M_base); }
2045 size() const requires sized_range<const _Vp>
2046 {
return ranges::size(_M_base); }
2049 template<
typename _Range,
typename _Fp>
2050 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2056 template<
typename _Range,
typename _Fp>
2057 concept __can_transform_view
2058 =
requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2061 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2063 template<viewable_range _Range,
typename _Fp>
2064 requires __detail::__can_transform_view<_Range, _Fp>
2066 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2068 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2071 using _RangeAdaptor<_Transform>::operator();
2072 static constexpr int _S_arity = 2;
2073 static constexpr bool _S_has_simple_extra_args =
true;
2076 inline constexpr _Transform transform;
2080 class take_view :
public view_interface<take_view<_Vp>>
2083 template<
bool _Const>
2084 using _CI = counted_iterator<
2085 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2087 template<
bool _Const>
2091 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2092 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2095 _Sentinel() =
default;
2098 _Sentinel(sentinel_t<_Base> __end)
2103 _Sentinel(_Sentinel<!_Const> __s)
2104 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2108 constexpr sentinel_t<_Base>
2112 friend constexpr bool
2113 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2114 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2116 template<
bool _OtherConst = !_Const,
2117 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2118 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2119 friend constexpr bool
2120 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2121 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2123 friend _Sentinel<!_Const>;
2126 _Vp _M_base = _Vp();
2127 range_difference_t<_Vp> _M_count = 0;
2130 take_view()
requires default_initializable<_Vp> = default;
2133 take_view(_Vp
__base, range_difference_t<_Vp> __count)
2138 base() const& requires copy_constructible<_Vp>
2146 begin()
requires (!__detail::__simple_view<_Vp>)
2148 if constexpr (sized_range<_Vp>)
2150 if constexpr (random_access_range<_Vp>)
2151 return ranges::begin(_M_base);
2155 return counted_iterator(ranges::begin(_M_base), __sz);
2159 return counted_iterator(ranges::begin(_M_base), _M_count);
2163 begin() const requires range<const _Vp>
2165 if constexpr (sized_range<const _Vp>)
2167 if constexpr (random_access_range<const _Vp>)
2168 return ranges::begin(_M_base);
2172 return counted_iterator(ranges::begin(_M_base), __sz);
2176 return counted_iterator(ranges::begin(_M_base), _M_count);
2180 end()
requires (!__detail::__simple_view<_Vp>)
2182 if constexpr (sized_range<_Vp>)
2184 if constexpr (random_access_range<_Vp>)
2185 return ranges::begin(_M_base) +
size();
2190 return _Sentinel<false>{ranges::end(_M_base)};
2194 end() const requires range<const _Vp>
2196 if constexpr (sized_range<const _Vp>)
2198 if constexpr (random_access_range<const _Vp>)
2199 return ranges::begin(_M_base) +
size();
2204 return _Sentinel<true>{ranges::end(_M_base)};
2208 size()
requires sized_range<_Vp>
2210 auto __n = ranges::size(_M_base);
2211 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2215 size() const requires sized_range<const _Vp>
2217 auto __n = ranges::size(_M_base);
2218 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2225 template<
typename _Range>
2226 take_view(_Range&&, range_difference_t<_Range>)
2227 -> take_view<views::all_t<_Range>>;
2229 template<
typename _Tp>
2230 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2231 = enable_borrowed_range<_Tp>;
2237 template<
typename _Range>
2238 inline constexpr bool __is_empty_view =
false;
2240 template<
typename _Tp>
2241 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2243 template<
typename _Range>
2244 inline constexpr bool __is_basic_string_view =
false;
2246 template<
typename _CharT,
typename _Traits>
2247 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2250 template<
typename _Range>
2251 inline constexpr bool __is_subrange =
false;
2253 template<
typename _Iter,
typename _Sent, subrange_kind _Kind>
2254 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> =
true;
2256 template<
typename _Range>
2257 inline constexpr bool __is_iota_view =
false;
2259 template<
typename _Winc,
typename _Bound>
2260 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2262 template<
typename _Range>
2263 inline constexpr bool __is_repeat_view =
false;
2265 template<
typename _Range>
2267 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2269 template<
typename _Range,
typename _Dp>
2270 concept __can_take_view
2271 =
requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2274 struct _Take : __adaptor::_RangeAdaptor<_Take>
2276 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2277 requires __detail::__can_take_view<_Range, _Dp>
2279 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2281 using _Tp = remove_cvref_t<_Range>;
2282 if constexpr (__detail::__is_empty_view<_Tp>)
2284 else if constexpr (random_access_range<_Tp>
2286 && (std::__detail::__is_span<_Tp>
2287 || __detail::__is_basic_string_view<_Tp>
2288 || __detail::__is_subrange<_Tp>
2289 || __detail::__is_iota_view<_Tp>))
2291 __n = std::min<_Dp>(ranges::distance(__r), __n);
2292 auto __begin = ranges::begin(__r);
2293 auto __end = __begin + __n;
2294 if constexpr (std::__detail::__is_span<_Tp>)
2295 return span<typename _Tp::element_type>(__begin, __end);
2296 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2297 return _Tp(__begin, __end);
2298 else if constexpr (__detail::__is_subrange<_Tp>)
2299 return subrange<iterator_t<_Tp>>(__begin, __end);
2301 return iota_view(*__begin, *__end);
2303 else if constexpr (__detail::__is_repeat_view<_Tp>)
2304 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2306 return take_view(std::forward<_Range>(__r), __n);
2309 using _RangeAdaptor<_Take>::operator();
2310 static constexpr int _S_arity = 2;
2314 template<
typename _Tp>
2315 static constexpr bool _S_has_simple_extra_args
2316 = ranges::__detail::__is_integer_like<_Tp>;
2319 inline constexpr _Take take;
2322 template<view _Vp,
typename _Pred>
2323 requires input_range<_Vp> && is_object_v<_Pred>
2324 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2325 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2327 template<
bool _Const>
2331 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2333 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2334 const _Pred* _M_pred =
nullptr;
2337 _Sentinel() =
default;
2340 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2341 : _M_end(__end), _M_pred(__pred)
2345 _Sentinel(_Sentinel<!_Const> __s)
2346 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2347 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2350 constexpr sentinel_t<_Base>
2351 base()
const {
return _M_end; }
2353 friend constexpr bool
2354 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2355 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2357 template<
bool _OtherConst = !_Const,
2358 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2359 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2360 friend constexpr bool
2361 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2362 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2364 friend _Sentinel<!_Const>;
2367 _Vp _M_base = _Vp();
2368 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2371 take_while_view()
requires (default_initializable<_Vp>
2372 && default_initializable<_Pred>)
2376 take_while_view(_Vp
__base, _Pred __pred)
2381 base() const& requires copy_constructible<_Vp>
2388 constexpr const _Pred&
2390 {
return *_M_pred; }
2393 begin()
requires (!__detail::__simple_view<_Vp>)
2394 {
return ranges::begin(_M_base); }
2397 begin() const requires range<const _Vp>
2398 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2399 {
return ranges::begin(_M_base); }
2402 end()
requires (!__detail::__simple_view<_Vp>)
2403 {
return _Sentinel<false>(ranges::end(_M_base),
2407 end() const requires range<const _Vp>
2408 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2409 {
return _Sentinel<true>(ranges::end(_M_base),
2413 template<
typename _Range,
typename _Pred>
2414 take_while_view(_Range&&, _Pred)
2415 -> take_while_view<views::all_t<_Range>, _Pred>;
2421 template<
typename _Range,
typename _Pred>
2422 concept __can_take_while_view
2423 =
requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2426 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2428 template<viewable_range _Range,
typename _Pred>
2429 requires __detail::__can_take_while_view<_Range, _Pred>
2431 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2433 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2436 using _RangeAdaptor<_TakeWhile>::operator();
2437 static constexpr int _S_arity = 2;
2438 static constexpr bool _S_has_simple_extra_args =
true;
2441 inline constexpr _TakeWhile take_while;
2445 class drop_view :
public view_interface<drop_view<_Vp>>
2448 _Vp _M_base = _Vp();
2449 range_difference_t<_Vp> _M_count = 0;
2453 static constexpr bool _S_needs_cached_begin
2454 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2455 [[no_unique_address]]
2456 __detail::__maybe_present_t<_S_needs_cached_begin,
2457 __detail::_CachedPosition<_Vp>>
2461 drop_view()
requires default_initializable<_Vp> = default;
2464 drop_view(_Vp
__base, range_difference_t<_Vp> __count)
2466 { __glibcxx_assert(__count >= 0); }
2469 base() const& requires copy_constructible<_Vp>
2479 requires (!(__detail::__simple_view<_Vp>
2480 && random_access_range<const _Vp>
2481 && sized_range<const _Vp>))
2483 if constexpr (_S_needs_cached_begin)
2484 if (_M_cached_begin._M_has_value())
2485 return _M_cached_begin._M_get(_M_base);
2487 auto __it = ranges::next(ranges::begin(_M_base),
2488 _M_count, ranges::end(_M_base));
2489 if constexpr (_S_needs_cached_begin)
2490 _M_cached_begin._M_set(_M_base, __it);
2498 requires random_access_range<const _Vp> && sized_range<const _Vp>
2500 return ranges::next(ranges::begin(_M_base), _M_count,
2501 ranges::end(_M_base));
2505 end()
requires (!__detail::__simple_view<_Vp>)
2506 {
return ranges::end(_M_base); }
2509 end() const requires range<const _Vp>
2510 {
return ranges::end(_M_base); }
2513 size()
requires sized_range<_Vp>
2515 const auto __s = ranges::size(_M_base);
2516 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2517 return __s < __c ? 0 : __s - __c;
2521 size() const requires sized_range<const _Vp>
2523 const auto __s = ranges::size(_M_base);
2524 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2525 return __s < __c ? 0 : __s - __c;
2529 template<
typename _Range>
2530 drop_view(_Range&&, range_difference_t<_Range>)
2531 -> drop_view<views::all_t<_Range>>;
2533 template<
typename _Tp>
2534 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2535 = enable_borrowed_range<_Tp>;
2541 template<
typename _Range>
2543 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2545 template<
typename _Range,
typename _Dp>
2546 concept __can_drop_view
2547 =
requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2550 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2552 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2553 requires __detail::__can_drop_view<_Range, _Dp>
2555 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2557 using _Tp = remove_cvref_t<_Range>;
2558 if constexpr (__detail::__is_empty_view<_Tp>)
2560 else if constexpr (random_access_range<_Tp>
2562 && (std::__detail::__is_span<_Tp>
2563 || __detail::__is_basic_string_view<_Tp>
2564 || __detail::__is_iota_view<_Tp>
2565 || __detail::__is_subrange<_Tp>))
2567 __n = std::min<_Dp>(ranges::distance(__r), __n);
2568 auto __begin = ranges::begin(__r) + __n;
2569 auto __end = ranges::end(__r);
2570 if constexpr (std::__detail::__is_span<_Tp>)
2571 return span<typename _Tp::element_type>(__begin, __end);
2572 else if constexpr (__detail::__is_subrange<_Tp>)
2574 if constexpr (_Tp::_S_store_size)
2576 using ranges::__detail::__to_unsigned_like;
2577 auto __m = ranges::distance(__r) - __n;
2578 return _Tp(__begin, __end, __to_unsigned_like(__m));
2581 return _Tp(__begin, __end);
2584 return _Tp(__begin, __end);
2586 else if constexpr (__detail::__is_repeat_view<_Tp>)
2587 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2589 return drop_view(std::forward<_Range>(__r), __n);
2592 using _RangeAdaptor<_Drop>::operator();
2593 static constexpr int _S_arity = 2;
2594 template<
typename _Tp>
2595 static constexpr bool _S_has_simple_extra_args
2596 = _Take::_S_has_simple_extra_args<_Tp>;
2599 inline constexpr _Drop drop;
2602 template<view _Vp,
typename _Pred>
2603 requires input_range<_Vp> && is_object_v<_Pred>
2604 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2605 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2608 _Vp _M_base = _Vp();
2609 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2610 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2613 drop_while_view()
requires (default_initializable<_Vp>
2614 && default_initializable<_Pred>)
2618 drop_while_view(_Vp
__base, _Pred __pred)
2623 base() const& requires copy_constructible<_Vp>
2630 constexpr const _Pred&
2632 {
return *_M_pred; }
2637 if (_M_cached_begin._M_has_value())
2638 return _M_cached_begin._M_get(_M_base);
2640 __glibcxx_assert(_M_pred.has_value());
2641 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2642 ranges::end(_M_base),
2643 std::cref(*_M_pred));
2644 _M_cached_begin._M_set(_M_base, __it);
2650 {
return ranges::end(_M_base); }
2653 template<
typename _Range,
typename _Pred>
2654 drop_while_view(_Range&&, _Pred)
2655 -> drop_while_view<views::all_t<_Range>, _Pred>;
2657 template<
typename _Tp,
typename _Pred>
2658 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2659 = enable_borrowed_range<_Tp>;
2665 template<
typename _Range,
typename _Pred>
2666 concept __can_drop_while_view
2667 =
requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2670 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2672 template<viewable_range _Range,
typename _Pred>
2673 requires __detail::__can_drop_while_view<_Range, _Pred>
2675 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2677 return drop_while_view(std::forward<_Range>(__r),
2678 std::forward<_Pred>(__p));
2681 using _RangeAdaptor<_DropWhile>::operator();
2682 static constexpr int _S_arity = 2;
2683 static constexpr bool _S_has_simple_extra_args =
true;
2686 inline constexpr _DropWhile drop_while;
2689 template<input_range _Vp>
2690 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2691 class join_view :
public view_interface<join_view<_Vp>>
2694 using _InnerRange = range_reference_t<_Vp>;
2696 template<
bool _Const>
2697 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2699 template<
bool _Const>
2700 using _Outer_iter = iterator_t<_Base<_Const>>;
2702 template<
bool _Const>
2703 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2705 template<
bool _Const>
2706 static constexpr bool _S_ref_is_glvalue
2707 = is_reference_v<range_reference_t<_Base<_Const>>>;
2709 template<
bool _Const>
2713 template<
bool _Const>
2714 requires _S_ref_is_glvalue<_Const>
2715 && forward_range<_Base<_Const>>
2716 && forward_range<range_reference_t<_Base<_Const>>>
2717 struct __iter_cat<_Const>
2720 static constexpr auto
2723 using _Outer_iter = join_view::_Outer_iter<_Const>;
2724 using _Inner_iter = join_view::_Inner_iter<_Const>;
2725 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
2726 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
2727 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2728 && derived_from<_InnerCat, bidirectional_iterator_tag>
2729 && common_range<range_reference_t<_Base<_Const>>>)
2730 return bidirectional_iterator_tag{};
2731 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2732 && derived_from<_InnerCat, forward_iterator_tag>)
2733 return forward_iterator_tag{};
2735 return input_iterator_tag{};
2738 using iterator_category =
decltype(_S_iter_cat());
2741 template<
bool _Const>
2744 template<
bool _Const>
2745 struct _Iterator : __iter_cat<_Const>
2748 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2749 using _Base = join_view::_Base<_Const>;
2751 static constexpr bool _S_ref_is_glvalue
2752 = join_view::_S_ref_is_glvalue<_Const>;
2757 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
2758 if constexpr (_S_ref_is_glvalue)
2761 return _M_parent->_M_inner._M_emplace_deref(__x);
2764 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2766 auto&& __inner = __update_inner(_M_outer);
2767 _M_inner = ranges::begin(__inner);
2768 if (_M_inner != ranges::end(__inner))
2772 if constexpr (_S_ref_is_glvalue)
2776 static constexpr auto
2779 if constexpr (_S_ref_is_glvalue
2780 && bidirectional_range<_Base>
2781 && bidirectional_range<range_reference_t<_Base>>
2782 && common_range<range_reference_t<_Base>>)
2783 return bidirectional_iterator_tag{};
2784 else if constexpr (_S_ref_is_glvalue
2785 && forward_range<_Base>
2786 && forward_range<range_reference_t<_Base>>)
2787 return forward_iterator_tag{};
2789 return input_iterator_tag{};
2792 using _Outer_iter = join_view::_Outer_iter<_Const>;
2793 using _Inner_iter = join_view::_Inner_iter<_Const>;
2795 _Outer_iter _M_outer = _Outer_iter();
2796 optional<_Inner_iter> _M_inner;
2797 _Parent* _M_parent =
nullptr;
2800 using iterator_concept =
decltype(_S_iter_concept());
2802 using value_type = range_value_t<range_reference_t<_Base>>;
2803 using difference_type
2804 = common_type_t<range_difference_t<_Base>,
2805 range_difference_t<range_reference_t<_Base>>>;
2807 _Iterator()
requires default_initializable<_Outer_iter> = default;
2810 _Iterator(_Parent* __parent, _Outer_iter __outer)
2811 : _M_outer(
std::
move(__outer)),
2816 _Iterator(_Iterator<!_Const> __i)
2818 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2819 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2821 _M_parent(__i._M_parent)
2824 constexpr decltype(
auto)
2826 {
return **_M_inner; }
2830 constexpr _Inner_iter
2832 requires __detail::__has_arrow<_Inner_iter>
2833 && copyable<_Inner_iter>
2834 {
return *_M_inner; }
2836 constexpr _Iterator&
2839 auto&& __inner_range = [
this] () ->
auto&& {
2840 if constexpr (_S_ref_is_glvalue)
2843 return *_M_parent->_M_inner;
2845 if (++*_M_inner == ranges::end(__inner_range))
2859 requires _S_ref_is_glvalue && forward_range<_Base>
2860 && forward_range<range_reference_t<_Base>>
2867 constexpr _Iterator&
2869 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2870 && bidirectional_range<range_reference_t<_Base>>
2871 && common_range<range_reference_t<_Base>>
2873 if (_M_outer == ranges::end(_M_parent->_M_base))
2874 _M_inner = ranges::end(*--_M_outer);
2875 while (*_M_inner == ranges::begin(*_M_outer))
2876 *_M_inner = ranges::end(*--_M_outer);
2883 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2884 && bidirectional_range<range_reference_t<_Base>>
2885 && common_range<range_reference_t<_Base>>
2892 friend constexpr bool
2893 operator==(
const _Iterator& __x,
const _Iterator& __y)
2894 requires _S_ref_is_glvalue
2895 && equality_comparable<_Outer_iter>
2896 && equality_comparable<_Inner_iter>
2898 return (__x._M_outer == __y._M_outer
2899 && __x._M_inner == __y._M_inner);
2902 friend constexpr decltype(
auto)
2903 iter_move(
const _Iterator& __i)
2904 noexcept(
noexcept(ranges::iter_move(*__i._M_inner)))
2905 {
return ranges::iter_move(*__i._M_inner); }
2907 friend constexpr void
2908 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
2909 noexcept(
noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
2910 requires indirectly_swappable<_Inner_iter>
2911 {
return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
2913 friend _Iterator<!_Const>;
2914 template<
bool>
friend struct _Sentinel;
2917 template<
bool _Const>
2921 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2922 using _Base = join_view::_Base<_Const>;
2924 template<
bool _Const2>
2926 __equal(
const _Iterator<_Const2>& __i)
const
2927 {
return __i._M_outer == _M_end; }
2929 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2932 _Sentinel() =
default;
2935 _Sentinel(_Parent* __parent)
2936 : _M_end(ranges::
end(__parent->_M_base))
2940 _Sentinel(_Sentinel<!_Const> __s)
2941 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2945 template<
bool _Const2>
2946 requires sentinel_for<sentinel_t<_Base>,
2947 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2948 friend constexpr bool
2949 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2950 {
return __y.__equal(__x); }
2952 friend _Sentinel<!_Const>;
2955 _Vp _M_base = _Vp();
2956 [[no_unique_address]]
2957 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2960 join_view()
requires default_initializable<_Vp> = default;
2968 base() const& requires copy_constructible<_Vp>
2978 constexpr bool __use_const
2979 = (__detail::__simple_view<_Vp>
2980 && is_reference_v<range_reference_t<_Vp>>);
2981 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
2986 requires input_range<const _Vp>
2987 && is_reference_v<range_reference_t<const _Vp>>
2989 return _Iterator<true>{
this, ranges::begin(_M_base)};
2995 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2996 && forward_range<_InnerRange>
2997 && common_range<_Vp> && common_range<_InnerRange>)
2998 return _Iterator<__detail::__simple_view<_Vp>>{
this,
2999 ranges::end(_M_base)};
3001 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3006 requires input_range<const _Vp>
3007 && is_reference_v<range_reference_t<const _Vp>>
3009 if constexpr (forward_range<const _Vp>
3010 && is_reference_v<range_reference_t<const _Vp>>
3011 && forward_range<range_reference_t<const _Vp>>
3012 && common_range<const _Vp>
3013 && common_range<range_reference_t<const _Vp>>)
3014 return _Iterator<true>{
this, ranges::end(_M_base)};
3016 return _Sentinel<true>{
this};
3020 template<
typename _Range>
3021 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3027 template<
typename _Range>
3028 concept __can_join_view
3029 =
requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3032 struct _Join : __adaptor::_RangeAdaptorClosure
3034 template<viewable_range _Range>
3035 requires __detail::__can_join_view<_Range>
3037 operator() [[nodiscard]] (_Range&& __r)
const
3041 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3044 static constexpr bool _S_has_simple_call_op =
true;
3047 inline constexpr _Join join;
3053 struct __require_constant;
3055 template<
typename _Range>
3056 concept __tiny_range = sized_range<_Range>
3058 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3059 && (remove_reference_t<_Range>::size() <= 1);
3061 template<
typename _Base>
3062 struct __lazy_split_view_outer_iter_cat
3065 template<forward_range _Base>
3066 struct __lazy_split_view_outer_iter_cat<_Base>
3067 {
using iterator_category = input_iterator_tag; };
3069 template<
typename _Base>
3070 struct __lazy_split_view_inner_iter_cat
3073 template<forward_range _Base>
3074 struct __lazy_split_view_inner_iter_cat<_Base>
3077 static constexpr auto
3080 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3081 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3082 return forward_iterator_tag{};
3087 using iterator_category =
decltype(_S_iter_cat());
3091 template<input_range _Vp, forward_range _Pattern>
3092 requires view<_Vp> && view<_Pattern>
3093 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3095 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3096 class lazy_split_view :
public view_interface<lazy_split_view<_Vp, _Pattern>>
3099 template<
bool _Const>
3100 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3102 template<
bool _Const>
3105 template<
bool _Const>
3107 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3110 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3111 using _Base = lazy_split_view::_Base<_Const>;
3115 {
return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3122 __current() noexcept
3124 if constexpr (forward_range<_Vp>)
3127 return *_M_parent->_M_current;
3131 __current() const noexcept
3133 if constexpr (forward_range<_Vp>)
3136 return *_M_parent->_M_current;
3139 _Parent* _M_parent =
nullptr;
3141 [[no_unique_address]]
3142 __detail::__maybe_present_t<forward_range<_Vp>,
3143 iterator_t<_Base>> _M_current;
3144 bool _M_trailing_empty =
false;
3147 using iterator_concept = __conditional_t<forward_range<_Base>,
3148 forward_iterator_tag,
3149 input_iterator_tag>;
3151 using difference_type = range_difference_t<_Base>;
3153 struct value_type : view_interface<value_type>
3156 _OuterIter _M_i = _OuterIter();
3159 value_type() =
default;
3162 value_type(_OuterIter __i)
3166 constexpr _InnerIter<_Const>
3168 {
return _InnerIter<_Const>{_M_i}; }
3170 constexpr default_sentinel_t
3171 end() const noexcept
3175 _OuterIter() =
default;
3178 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3179 : _M_parent(__parent)
3183 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3184 requires forward_range<_Base>
3185 : _M_parent(__parent),
3190 _OuterIter(_OuterIter<!_Const> __i)
3192 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3193 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current))
3196 constexpr value_type
3198 {
return value_type{*
this}; }
3200 constexpr _OuterIter&
3205 const auto __end = ranges::end(_M_parent->_M_base);
3206 if (__current() == __end)
3208 _M_trailing_empty =
false;
3211 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3212 if (__pbegin == __pend)
3214 else if constexpr (__detail::__tiny_range<_Pattern>)
3216 __current() = ranges::find(
std::move(__current()), __end,
3218 if (__current() != __end)
3221 if (__current() == __end)
3222 _M_trailing_empty =
true;
3229 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3233 if (__current() == __end)
3234 _M_trailing_empty =
true;
3237 }
while (++__current() != __end);
3241 constexpr decltype(
auto)
3244 if constexpr (forward_range<_Base>)
3254 friend constexpr bool
3255 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3256 requires forward_range<_Base>
3258 return __x._M_current == __y._M_current
3259 && __x._M_trailing_empty == __y._M_trailing_empty;
3262 friend constexpr bool
3263 operator==(
const _OuterIter& __x, default_sentinel_t)
3264 {
return __x.__at_end(); };
3266 friend _OuterIter<!_Const>;
3267 friend _InnerIter<_Const>;
3270 template<
bool _Const>
3272 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3275 using _Base = lazy_split_view::_Base<_Const>;
3280 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3281 auto __end = ranges::end(_M_i._M_parent->_M_base);
3282 if constexpr (__detail::__tiny_range<_Pattern>)
3284 const auto& __cur = _M_i_current();
3287 if (__pcur == __pend)
3288 return _M_incremented;
3289 return *__cur == *__pcur;
3293 auto __cur = _M_i_current();
3296 if (__pcur == __pend)
3297 return _M_incremented;
3300 if (*__cur != *__pcur)
3302 if (++__pcur == __pend)
3304 }
while (++__cur != __end);
3310 _M_i_current() noexcept
3311 {
return _M_i.__current(); }
3314 _M_i_current() const noexcept
3315 {
return _M_i.__current(); }
3317 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3318 bool _M_incremented =
false;
3321 using iterator_concept
3322 =
typename _OuterIter<_Const>::iterator_concept;
3324 using value_type = range_value_t<_Base>;
3325 using difference_type = range_difference_t<_Base>;
3327 _InnerIter() =
default;
3330 _InnerIter(_OuterIter<_Const> __i)
3334 constexpr const iterator_t<_Base>&
3335 base() const& noexcept
3336 {
return _M_i_current(); }
3338 constexpr iterator_t<_Base>
3339 base() &&
requires forward_range<_Vp>
3342 constexpr decltype(
auto)
3344 {
return *_M_i_current(); }
3346 constexpr _InnerIter&
3349 _M_incremented =
true;
3350 if constexpr (!forward_range<_Base>)
3351 if constexpr (_Pattern::size() == 0)
3357 constexpr decltype(
auto)
3360 if constexpr (forward_range<_Base>)
3370 friend constexpr bool
3371 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3372 requires forward_range<_Base>
3373 {
return __x._M_i == __y._M_i; }
3375 friend constexpr bool
3376 operator==(
const _InnerIter& __x, default_sentinel_t)
3377 {
return __x.__at_end(); }
3379 friend constexpr decltype(
auto)
3380 iter_move(
const _InnerIter& __i)
3381 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3382 {
return ranges::iter_move(__i._M_i_current()); }
3384 friend constexpr void
3385 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3386 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3387 __y._M_i_current())))
3388 requires indirectly_swappable<iterator_t<_Base>>
3389 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3392 _Vp _M_base = _Vp();
3393 _Pattern _M_pattern = _Pattern();
3394 [[no_unique_address]]
3395 __detail::__maybe_present_t<!forward_range<_Vp>,
3396 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3400 lazy_split_view()
requires (default_initializable<_Vp>
3401 && default_initializable<_Pattern>)
3405 lazy_split_view(_Vp
__base, _Pattern __pattern)
3409 template<input_range _Range>
3410 requires constructible_from<_Vp, views::all_t<_Range>>
3411 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3413 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3414 : _M_base(views::all(
std::
forward<_Range>(__r))),
3415 _M_pattern(views::single(
std::
move(__e)))
3419 base() const& requires copy_constructible<_Vp>
3429 if constexpr (forward_range<_Vp>)
3431 constexpr bool __simple
3432 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3433 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3437 _M_current = ranges::begin(_M_base);
3438 return _OuterIter<false>{
this};
3443 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3445 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3449 end()
requires forward_range<_Vp> && common_range<_Vp>
3451 constexpr bool __simple
3452 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3453 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3459 if constexpr (forward_range<_Vp>
3460 && forward_range<const _Vp>
3461 && common_range<const _Vp>)
3462 return _OuterIter<true>{
this, ranges::end(_M_base)};
3468 template<
typename _Range,
typename _Pattern>
3469 lazy_split_view(_Range&&, _Pattern&&)
3470 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3472 template<input_range _Range>
3473 lazy_split_view(_Range&&, range_value_t<_Range>)
3474 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3480 template<
typename _Range,
typename _Pattern>
3481 concept __can_lazy_split_view
3482 =
requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3485 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3487 template<viewable_range _Range,
typename _Pattern>
3488 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3490 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3492 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3495 using _RangeAdaptor<_LazySplit>::operator();
3496 static constexpr int _S_arity = 2;
3501 template<
typename _Pattern>
3502 static constexpr bool _S_has_simple_extra_args
3503 = is_scalar_v<_Pattern> || (view<_Pattern>
3504 && copy_constructible<_Pattern>);
3507 inline constexpr _LazySplit lazy_split;
3510 template<forward_range _Vp, forward_range _Pattern>
3511 requires view<_Vp> && view<_Pattern>
3512 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3514 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3517 _Vp _M_base = _Vp();
3518 _Pattern _M_pattern = _Pattern();
3519 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3525 split_view()
requires (default_initializable<_Vp>
3526 && default_initializable<_Pattern>)
3530 split_view(_Vp
__base, _Pattern __pattern)
3534 template<forward_range _Range>
3535 requires constructible_from<_Vp, views::all_t<_Range>>
3536 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3538 split_view(_Range&& __r, range_value_t<_Range> __e)
3539 : _M_base(views::all(
std::
forward<_Range>(__r))),
3540 _M_pattern(views::single(
std::
move(__e)))
3544 base() const& requires copy_constructible<_Vp>
3554 if (!_M_cached_begin)
3555 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3556 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3562 if constexpr (common_range<_Vp>)
3563 return _Iterator{
this, ranges::end(_M_base), {}};
3565 return _Sentinel{
this};
3568 constexpr subrange<iterator_t<_Vp>>
3569 _M_find_next(iterator_t<_Vp> __it)
3571 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3572 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3584 split_view* _M_parent =
nullptr;
3585 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3586 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3587 bool _M_trailing_empty =
false;
3589 friend struct _Sentinel;
3592 using iterator_concept = forward_iterator_tag;
3593 using iterator_category = input_iterator_tag;
3594 using value_type = subrange<iterator_t<_Vp>>;
3595 using difference_type = range_difference_t<_Vp>;
3597 _Iterator() =
default;
3600 _Iterator(split_view* __parent,
3601 iterator_t<_Vp> __current,
3602 subrange<iterator_t<_Vp>> __next)
3603 : _M_parent(__parent),
3608 constexpr iterator_t<_Vp>
3612 constexpr value_type
3614 {
return {_M_cur, _M_next.begin()}; }
3616 constexpr _Iterator&
3619 _M_cur = _M_next.begin();
3620 if (_M_cur != ranges::end(_M_parent->_M_base))
3622 _M_cur = _M_next.end();
3623 if (_M_cur == ranges::end(_M_parent->_M_base))
3625 _M_trailing_empty =
true;
3626 _M_next = {_M_cur, _M_cur};
3629 _M_next = _M_parent->_M_find_next(_M_cur);
3632 _M_trailing_empty =
false;
3644 friend constexpr bool
3645 operator==(
const _Iterator& __x,
const _Iterator& __y)
3647 return __x._M_cur == __y._M_cur
3648 && __x._M_trailing_empty == __y._M_trailing_empty;
3655 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3658 _M_equal(
const _Iterator& __x)
const
3659 {
return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3662 _Sentinel() =
default;
3665 _Sentinel(split_view* __parent)
3666 : _M_end(ranges::
end(__parent->_M_base))
3669 friend constexpr bool
3670 operator==(
const _Iterator& __x,
const _Sentinel& __y)
3671 {
return __y._M_equal(__x); }
3675 template<
typename _Range,
typename _Pattern>
3676 split_view(_Range&&, _Pattern&&)
3677 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3679 template<forward_range _Range>
3680 split_view(_Range&&, range_value_t<_Range>)
3681 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3687 template<
typename _Range,
typename _Pattern>
3688 concept __can_split_view
3689 =
requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3692 struct _Split : __adaptor::_RangeAdaptor<_Split>
3694 template<viewable_range _Range,
typename _Pattern>
3695 requires __detail::__can_split_view<_Range, _Pattern>
3697 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3699 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3702 using _RangeAdaptor<_Split>::operator();
3703 static constexpr int _S_arity = 2;
3704 template<
typename _Pattern>
3705 static constexpr bool _S_has_simple_extra_args
3706 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3709 inline constexpr _Split split;
3716 template<input_or_output_iterator _Iter>
3718 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
3720 if constexpr (contiguous_iterator<_Iter>)
3721 return span(std::__to_address(__i), __n);
3722 else if constexpr (random_access_iterator<_Iter>)
3723 return subrange(__i, __i + __n);
3725 return subrange(counted_iterator(
std::move(__i), __n),
3730 inline constexpr _Counted counted{};
3734 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3735 class common_view :
public view_interface<common_view<_Vp>>
3738 _Vp _M_base = _Vp();
3741 common_view()
requires default_initializable<_Vp> = default;
3744 common_view(_Vp __r)
3749 base() const& requires copy_constructible<_Vp>
3759 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3760 return ranges::begin(_M_base);
3762 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3763 (ranges::begin(_M_base));
3767 begin() const requires range<const _Vp>
3769 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3770 return ranges::begin(_M_base);
3772 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3773 (ranges::begin(_M_base));
3779 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3780 return ranges::begin(_M_base) + ranges::size(_M_base);
3782 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3783 (ranges::end(_M_base));
3787 end() const requires range<const _Vp>
3789 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3790 return ranges::begin(_M_base) + ranges::size(_M_base);
3792 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3793 (ranges::end(_M_base));
3797 size()
requires sized_range<_Vp>
3798 {
return ranges::size(_M_base); }
3801 size() const requires sized_range<const _Vp>
3802 {
return ranges::size(_M_base); }
3805 template<
typename _Range>
3806 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3808 template<
typename _Tp>
3809 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3810 = enable_borrowed_range<_Tp>;
3816 template<
typename _Range>
3817 concept __already_common = common_range<_Range>
3818 &&
requires { views::all(std::declval<_Range>()); };
3820 template<
typename _Range>
3821 concept __can_common_view
3822 =
requires { common_view{std::declval<_Range>()}; };
3825 struct _Common : __adaptor::_RangeAdaptorClosure
3827 template<viewable_range _Range>
3828 requires __detail::__already_common<_Range>
3829 || __detail::__can_common_view<_Range>
3831 operator() [[nodiscard]] (_Range&& __r)
const
3833 if constexpr (__detail::__already_common<_Range>)
3834 return views::all(std::forward<_Range>(__r));
3836 return common_view{std::forward<_Range>(__r)};
3839 static constexpr bool _S_has_simple_call_op =
true;
3842 inline constexpr _Common common;
3846 requires bidirectional_range<_Vp>
3847 class reverse_view :
public view_interface<reverse_view<_Vp>>
3850 static constexpr bool _S_needs_cached_begin
3851 = !common_range<_Vp> && !(random_access_range<_Vp>
3852 && sized_sentinel_for<sentinel_t<_Vp>,
3855 _Vp _M_base = _Vp();
3856 [[no_unique_address]]
3857 __detail::__maybe_present_t<_S_needs_cached_begin,
3858 __detail::_CachedPosition<_Vp>>
3862 reverse_view()
requires default_initializable<_Vp> = default;
3865 reverse_view(_Vp __r)
3870 base() const& requires copy_constructible<_Vp>
3877 constexpr reverse_iterator<iterator_t<_Vp>>
3880 if constexpr (_S_needs_cached_begin)
3881 if (_M_cached_begin._M_has_value())
3884 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3885 if constexpr (_S_needs_cached_begin)
3886 _M_cached_begin._M_set(_M_base, __it);
3891 begin()
requires common_range<_Vp>
3895 begin() const requires common_range<const _Vp>
3898 constexpr reverse_iterator<iterator_t<_Vp>>
3903 end() const requires common_range<const _Vp>
3907 size()
requires sized_range<_Vp>
3908 {
return ranges::size(_M_base); }
3911 size() const requires sized_range<const _Vp>
3912 {
return ranges::size(_M_base); }
3915 template<
typename _Range>
3916 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3918 template<
typename _Tp>
3919 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3920 = enable_borrowed_range<_Tp>;
3927 inline constexpr bool __is_reversible_subrange =
false;
3929 template<
typename _Iter, subrange_kind _Kind>
3930 inline constexpr bool
3931 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3932 reverse_iterator<_Iter>,
3936 inline constexpr bool __is_reverse_view =
false;
3938 template<
typename _Vp>
3939 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
3941 template<
typename _Range>
3942 concept __can_reverse_view
3943 =
requires { reverse_view{std::declval<_Range>()}; };
3946 struct _Reverse : __adaptor::_RangeAdaptorClosure
3948 template<viewable_range _Range>
3949 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3950 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3951 || __detail::__can_reverse_view<_Range>
3953 operator() [[nodiscard]] (_Range&& __r)
const
3955 using _Tp = remove_cvref_t<_Range>;
3956 if constexpr (__detail::__is_reverse_view<_Tp>)
3957 return std::forward<_Range>(__r).base();
3958 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3960 using _Iter =
decltype(ranges::begin(__r).base());
3961 if constexpr (sized_range<_Tp>)
3962 return subrange<_Iter, _Iter, subrange_kind::sized>
3963 {__r.end().base(), __r.begin().base(), __r.size()};
3965 return subrange<_Iter, _Iter, subrange_kind::unsized>
3966 {__r.end().base(), __r.begin().base()};
3969 return reverse_view{std::forward<_Range>(__r)};
3972 static constexpr bool _S_has_simple_call_op =
true;
3975 inline constexpr _Reverse reverse;
3980 template<
typename _Tp,
size_t _Nm>
3981 concept __has_tuple_element =
requires(_Tp __t)
3983 typename tuple_size<_Tp>::type;
3984 requires _Nm < tuple_size_v<_Tp>;
3985 typename tuple_element_t<_Nm, _Tp>;
3986 { std::get<_Nm>(__t) }
3987 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3990 template<
typename _Tp,
size_t _Nm>
3991 concept __returnable_element
3992 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
3995 template<input_range _Vp,
size_t _Nm>
3997 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3998 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4000 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4001 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4004 elements_view()
requires default_initializable<_Vp> = default;
4007 elements_view(_Vp
__base)
4012 base() const& requires copy_constructible<_Vp>
4020 begin()
requires (!__detail::__simple_view<_Vp>)
4021 {
return _Iterator<false>(ranges::begin(_M_base)); }
4024 begin() const requires range<const _Vp>
4025 {
return _Iterator<true>(ranges::begin(_M_base)); }
4028 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4029 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4032 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4033 {
return _Iterator<false>{ranges::end(_M_base)}; }
4036 end() const requires range<const _Vp>
4037 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4040 end() const requires common_range<const _Vp>
4041 {
return _Iterator<true>{ranges::end(_M_base)}; }
4044 size()
requires sized_range<_Vp>
4045 {
return ranges::size(_M_base); }
4048 size() const requires sized_range<const _Vp>
4049 {
return ranges::size(_M_base); }
4052 template<
bool _Const>
4053 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4055 template<
bool _Const>
4059 template<
bool _Const>
4060 requires forward_range<_Base<_Const>>
4061 struct __iter_cat<_Const>
4064 static auto _S_iter_cat()
4066 using _Base = elements_view::_Base<_Const>;
4067 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4068 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4069 if constexpr (!is_lvalue_reference_v<_Res>)
4070 return input_iterator_tag{};
4071 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4072 return random_access_iterator_tag{};
4077 using iterator_category =
decltype(_S_iter_cat());
4080 template<
bool _Const>
4083 template<
bool _Const>
4084 struct _Iterator : __iter_cat<_Const>
4087 using _Base = elements_view::_Base<_Const>;
4089 iterator_t<_Base> _M_current = iterator_t<_Base>();
4091 static constexpr decltype(
auto)
4092 _S_get_element(
const iterator_t<_Base>& __i)
4094 if constexpr (is_reference_v<range_reference_t<_Base>>)
4095 return std::get<_Nm>(*__i);
4098 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4099 return static_cast<_Et
>(std::get<_Nm>(*__i));
4106 if constexpr (random_access_range<_Base>)
4107 return random_access_iterator_tag{};
4108 else if constexpr (bidirectional_range<_Base>)
4109 return bidirectional_iterator_tag{};
4110 else if constexpr (forward_range<_Base>)
4111 return forward_iterator_tag{};
4113 return input_iterator_tag{};
4116 friend _Iterator<!_Const>;
4119 using iterator_concept =
decltype(_S_iter_concept());
4122 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4123 using difference_type = range_difference_t<_Base>;
4125 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4128 _Iterator(iterator_t<_Base> __current)
4129 : _M_current(
std::
move(__current))
4133 _Iterator(_Iterator<!_Const> __i)
4134 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4138 constexpr const iterator_t<_Base>&
4139 base() const& noexcept
4140 {
return _M_current; }
4142 constexpr iterator_t<_Base>
4146 constexpr decltype(
auto)
4148 {
return _S_get_element(_M_current); }
4150 constexpr _Iterator&
4162 operator++(
int)
requires forward_range<_Base>
4169 constexpr _Iterator&
4170 operator--()
requires bidirectional_range<_Base>
4177 operator--(
int)
requires bidirectional_range<_Base>
4184 constexpr _Iterator&
4185 operator+=(difference_type __n)
4186 requires random_access_range<_Base>
4192 constexpr _Iterator&
4193 operator-=(difference_type __n)
4194 requires random_access_range<_Base>
4200 constexpr decltype(
auto)
4201 operator[](difference_type __n)
const
4202 requires random_access_range<_Base>
4203 {
return _S_get_element(_M_current + __n); }
4205 friend constexpr bool
4206 operator==(
const _Iterator& __x,
const _Iterator& __y)
4207 requires equality_comparable<iterator_t<_Base>>
4208 {
return __x._M_current == __y._M_current; }
4210 friend constexpr bool
4211 operator<(
const _Iterator& __x,
const _Iterator& __y)
4212 requires random_access_range<_Base>
4213 {
return __x._M_current < __y._M_current; }
4215 friend constexpr bool
4216 operator>(
const _Iterator& __x,
const _Iterator& __y)
4217 requires random_access_range<_Base>
4218 {
return __y._M_current < __x._M_current; }
4220 friend constexpr bool
4221 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4222 requires random_access_range<_Base>
4223 {
return !(__y._M_current > __x._M_current); }
4225 friend constexpr bool
4226 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4227 requires random_access_range<_Base>
4228 {
return !(__x._M_current > __y._M_current); }
4230#ifdef __cpp_lib_three_way_comparison
4231 friend constexpr auto
4232 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4233 requires random_access_range<_Base>
4234 && three_way_comparable<iterator_t<_Base>>
4235 {
return __x._M_current <=> __y._M_current; }
4238 friend constexpr _Iterator
4239 operator+(
const _Iterator& __x, difference_type __y)
4240 requires random_access_range<_Base>
4241 {
return _Iterator{__x} += __y; }
4243 friend constexpr _Iterator
4244 operator+(difference_type __x,
const _Iterator& __y)
4245 requires random_access_range<_Base>
4246 {
return __y + __x; }
4248 friend constexpr _Iterator
4249 operator-(
const _Iterator& __x, difference_type __y)
4250 requires random_access_range<_Base>
4251 {
return _Iterator{__x} -= __y; }
4255 friend constexpr difference_type
4256 operator-(
const _Iterator& __x,
const _Iterator& __y)
4257 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4258 {
return __x._M_current - __y._M_current; }
4260 template <
bool>
friend struct _Sentinel;
4263 template<
bool _Const>
4267 template<
bool _Const2>
4269 _M_equal(
const _Iterator<_Const2>& __x)
const
4270 {
return __x._M_current == _M_end; }
4272 template<
bool _Const2>
4274 _M_distance_from(
const _Iterator<_Const2>& __i)
const
4275 {
return _M_end - __i._M_current; }
4277 using _Base = elements_view::_Base<_Const>;
4278 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4281 _Sentinel() =
default;
4284 _Sentinel(sentinel_t<_Base> __end)
4289 _Sentinel(_Sentinel<!_Const> __other)
4291 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4295 constexpr sentinel_t<_Base>
4299 template<
bool _Const2>
4300 requires sentinel_for<sentinel_t<_Base>,
4301 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4302 friend constexpr bool
4303 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4304 {
return __y._M_equal(__x); }
4306 template<
bool _Const2,
4307 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4308 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4309 friend constexpr range_difference_t<_Base2>
4310 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4311 {
return -__y._M_distance_from(__x); }
4313 template<
bool _Const2,
4314 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4315 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4316 friend constexpr range_difference_t<_Base2>
4317 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4318 {
return __x._M_distance_from(__y); }
4320 friend _Sentinel<!_Const>;
4323 _Vp _M_base = _Vp();
4326 template<
typename _Tp,
size_t _Nm>
4327 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4328 = enable_borrowed_range<_Tp>;
4330 template<
typename _Range>
4331 using keys_view = elements_view<views::all_t<_Range>, 0>;
4333 template<
typename _Range>
4334 using values_view = elements_view<views::all_t<_Range>, 1>;
4340 template<
size_t _Nm,
typename _Range>
4341 concept __can_elements_view
4342 =
requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4345 template<
size_t _Nm>
4346 struct _Elements : __adaptor::_RangeAdaptorClosure
4348 template<viewable_range _Range>
4349 requires __detail::__can_elements_view<_Nm, _Range>
4351 operator() [[nodiscard]] (_Range&& __r)
const
4353 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4356 static constexpr bool _S_has_simple_call_op =
true;
4359 template<
size_t _Nm>
4360 inline constexpr _Elements<_Nm> elements;
4361 inline constexpr auto keys = elements<0>;
4362 inline constexpr auto values = elements<1>;
4365#if __cplusplus > 202002L
4367#define __cpp_lib_ranges_zip 202110L
4371 template<
typename... _Rs>
4372 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4373 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4374 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4376 template<
typename... _Ts>
4377 struct __tuple_or_pair
4380 template<
typename _Tp,
typename _Up>
4381 struct __tuple_or_pair<_Tp, _Up>
4382 {
using type = pair<_Tp, _Up>; };
4384 template<
typename... _Ts>
4385 using __tuple_or_pair_t =
typename __tuple_or_pair<_Ts...>::type;
4387 template<
typename _Fp,
typename _Tuple>
4389 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4391 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4392 return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
4394 }, std::forward<_Tuple>(__tuple));
4397 template<
typename _Fp,
typename _Tuple>
4399 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4401 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4403 }, std::forward<_Tuple>(__tuple));
4407 template<input_range... _Vs>
4408 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4409 class zip_view :
public view_interface<zip_view<_Vs...>>
4411 tuple<_Vs...> _M_views;
4413 template<
bool>
class _Iterator;
4414 template<
bool>
class _Sentinel;
4417 zip_view() =
default;
4420 zip_view(_Vs... __views)
4421 : _M_views(
std::
move(__views)...)
4425 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4426 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4429 begin() const requires (range<const _Vs> && ...)
4430 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4433 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4435 if constexpr (!__detail::__zip_is_common<_Vs...>)
4436 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4437 else if constexpr ((random_access_range<_Vs> && ...))
4438 return begin() + iter_difference_t<_Iterator<false>>(
size());
4440 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4444 end() const requires (range<const _Vs> && ...)
4446 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4447 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4448 else if constexpr ((random_access_range<const _Vs> && ...))
4449 return begin() + iter_difference_t<_Iterator<true>>(
size());
4451 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4455 size()
requires (sized_range<_Vs> && ...)
4457 return std::apply([](
auto... sizes) {
4458 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4459 return ranges::min({_CT(sizes)...});
4460 }, __detail::__tuple_transform(ranges::size, _M_views));
4464 size() const requires (sized_range<const _Vs> && ...)
4466 return std::apply([](
auto... sizes) {
4467 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4468 return ranges::min({_CT(sizes)...});
4469 }, __detail::__tuple_transform(ranges::size, _M_views));
4473 template<
typename... _Rs>
4474 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4476 template<
typename... _Views>
4477 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4478 = (enable_borrowed_range<_Views> && ...);
4482 template<
bool _Const,
typename... _Vs>
4483 concept __all_random_access
4484 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4486 template<
bool _Const,
typename... _Vs>
4487 concept __all_bidirectional
4488 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4490 template<
bool _Const,
typename... _Vs>
4491 concept __all_forward
4492 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4494 template<
bool _Const,
typename... _Views>
4495 struct __zip_view_iter_cat
4498 template<
bool _Const,
typename... _Views>
4499 requires __all_forward<_Const, _Views...>
4500 struct __zip_view_iter_cat<_Const, _Views...>
4501 {
using iterator_category = input_iterator_tag; };
4504 template<input_range... _Vs>
4505 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4506 template<
bool _Const>
4507 class zip_view<_Vs...>::_Iterator
4508 :
public __detail::__zip_view_iter_cat<_Const, _Vs...>
4510 __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4513 _Iterator(
decltype(_M_current) __current)
4514 : _M_current(
std::
move(__current))
4520 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4521 return random_access_iterator_tag{};
4522 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4523 return bidirectional_iterator_tag{};
4524 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4525 return forward_iterator_tag{};
4527 return input_iterator_tag{};
4530 template<copy_constructible _Fp, input_range... _Ws>
4531 requires (view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4532 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4533 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4534 friend class zip_transform_view;
4538 using iterator_concept =
decltype(_S_iter_concept());
4540 = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4541 using difference_type
4542 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4544 _Iterator() =
default;
4547 _Iterator(_Iterator<!_Const> __i)
4549 && (convertible_to<iterator_t<_Vs>,
4550 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4551 : _M_current(
std::
move(__i._M_current))
4557 auto __f = [](
auto& __i) ->
decltype(
auto) {
4560 return __detail::__tuple_transform(__f, _M_current);
4563 constexpr _Iterator&
4566 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4576 requires __detail::__all_forward<_Const, _Vs...>
4583 constexpr _Iterator&
4585 requires __detail::__all_bidirectional<_Const, _Vs...>
4587 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4593 requires __detail::__all_bidirectional<_Const, _Vs...>
4600 constexpr _Iterator&
4601 operator+=(difference_type __x)
4602 requires __detail::__all_random_access<_Const, _Vs...>
4604 auto __f = [&]<
typename _It>(_It& __i) {
4605 __i += iter_difference_t<_It>(__x);
4607 __detail::__tuple_for_each(__f, _M_current);
4611 constexpr _Iterator&
4612 operator-=(difference_type __x)
4613 requires __detail::__all_random_access<_Const, _Vs...>
4615 auto __f = [&]<
typename _It>(_It& __i) {
4616 __i -= iter_difference_t<_It>(__x);
4618 __detail::__tuple_for_each(__f, _M_current);
4623 operator[](difference_type __n)
const
4624 requires __detail::__all_random_access<_Const, _Vs...>
4626 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
4627 return __i[iter_difference_t<_It>(__n)];
4629 return __detail::__tuple_transform(__f, _M_current);
4632 friend constexpr bool
4633 operator==(
const _Iterator& __x,
const _Iterator& __y)
4634 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4636 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4637 return __x._M_current == __y._M_current;
4639 return [&]<
size_t... _Is>(index_sequence<_Is...>) {
4640 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4644 friend constexpr auto
4645 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4646 requires __detail::__all_random_access<_Const, _Vs...>
4647 {
return __x._M_current <=> __y._M_current; }
4649 friend constexpr _Iterator
4650 operator+(
const _Iterator& __i, difference_type __n)
4651 requires __detail::__all_random_access<_Const, _Vs...>
4658 friend constexpr _Iterator
4659 operator+(difference_type __n,
const _Iterator& __i)
4660 requires __detail::__all_random_access<_Const, _Vs...>
4667 friend constexpr _Iterator
4668 operator-(
const _Iterator& __i, difference_type __n)
4669 requires __detail::__all_random_access<_Const, _Vs...>
4676 friend constexpr difference_type
4677 operator-(
const _Iterator& __x,
const _Iterator& __y)
4678 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4679 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4682 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4683 - std::get<_Is>(__y._M_current))...},
4685 [](difference_type __i) {
4686 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4691 friend constexpr auto
4692 iter_move(
const _Iterator& __i)
4693 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4695 friend constexpr void
4696 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
4697 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4700 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4704 friend class zip_view;
4707 template<input_range... _Vs>
4708 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4709 template<
bool _Const>
4710 class zip_view<_Vs...>::_Sentinel
4712 __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4715 _Sentinel(
decltype(_M_end) __end)
4719 friend class zip_view;
4722 _Sentinel() =
default;
4725 _Sentinel(_Sentinel<!_Const> __i)
4727 && (convertible_to<sentinel_t<_Vs>,
4728 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4729 : _M_end(
std::
move(__i._M_end))
4732 template<
bool _OtherConst>
4733 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4734 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4735 friend constexpr bool
4736 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
4739 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4743 template<
bool _OtherConst>
4744 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4745 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4746 friend constexpr auto
4747 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
4750 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4752 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4755 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4760 template<
bool _OtherConst>
4761 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4762 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4763 friend constexpr auto
4764 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
4765 {
return -(__x - __y); }
4772 template<
typename... _Ts>
4773 concept __can_zip_view
4774 =
requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4779 template<
typename... _Ts>
4780 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4782 operator() [[nodiscard]] (_Ts&&... __ts)
const
4784 if constexpr (
sizeof...(_Ts) == 0)
4785 return views::empty<tuple<>>;
4787 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4791 inline constexpr _Zip zip;
4796 template<
typename _Range,
bool _Const>
4797 using __range_iter_cat
4798 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4801 template<copy_constructible _Fp, input_range... _Vs>
4802 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
4803 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4804 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4805 class zip_transform_view :
public view_interface<zip_transform_view<_Fp, _Vs...>>
4807 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4808 zip_view<_Vs...> _M_zip;
4810 using _InnerView = zip_view<_Vs...>;
4812 template<
bool _Const>
4813 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4815 template<
bool _Const>
4816 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4818 template<
bool _Const>
4819 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
4821 template<
bool _Const>
4825 template<
bool _Const>
4826 requires forward_range<_Base<_Const>>
4827 struct __iter_cat<_Const>
4833 using __detail::__maybe_const_t;
4834 using __detail::__range_iter_cat;
4835 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
4836 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
4837 if constexpr (!is_lvalue_reference_v<_Res>)
4838 return input_iterator_tag{};
4839 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4840 random_access_iterator_tag> && ...))
4841 return random_access_iterator_tag{};
4842 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4843 bidirectional_iterator_tag> && ...))
4844 return bidirectional_iterator_tag{};
4845 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4846 forward_iterator_tag> && ...))
4847 return forward_iterator_tag{};
4849 return input_iterator_tag{};
4852 using iterator_category =
decltype(_S_iter_cat());
4855 template<
bool>
class _Iterator;
4856 template<
bool>
class _Sentinel;
4859 zip_transform_view() =
default;
4862 zip_transform_view(_Fp __fun, _Vs... __views)
4868 {
return _Iterator<false>(*
this, _M_zip.begin()); }
4872 requires range<const _InnerView>
4873 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4874 {
return _Iterator<true>(*
this, _M_zip.begin()); }
4879 if constexpr (common_range<_InnerView>)
4880 return _Iterator<false>(*
this, _M_zip.end());
4882 return _Sentinel<false>(_M_zip.end());
4887 requires range<const _InnerView>
4888 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4890 if constexpr (common_range<const _InnerView>)
4891 return _Iterator<true>(*
this, _M_zip.end());
4893 return _Sentinel<true>(_M_zip.end());
4897 size()
requires sized_range<_InnerView>
4898 {
return _M_zip.size(); }
4901 size() const requires sized_range<const _InnerView>
4902 {
return _M_zip.size(); }
4905 template<
class _Fp,
class... Rs>
4906 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
4908 template<copy_constructible _Fp, input_range... _Vs>
4909 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
4910 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4911 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4912 template<
bool _Const>
4913 class zip_transform_view<_Fp, _Vs...>::_Iterator :
public __iter_cat<_Const>
4915 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
4917 _Parent* _M_parent =
nullptr;
4918 __ziperator<_Const> _M_inner;
4921 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
4925 friend class zip_transform_view;
4929 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
4931 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
4932 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
4933 using difference_type = range_difference_t<_Base<_Const>>;
4935 _Iterator() =
default;
4938 _Iterator(_Iterator<!_Const> __i)
4939 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
4940 : _M_parent(__i._M_parent), _M_inner(
std::move(__i._M_inner))
4943 constexpr decltype(
auto)
4946 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
4948 }, _M_inner._M_current);
4951 constexpr _Iterator&
4963 operator++(
int)
requires forward_range<_Base<_Const>>
4970 constexpr _Iterator&
4971 operator--()
requires bidirectional_range<_Base<_Const>>
4978 operator--(
int)
requires bidirectional_range<_Base<_Const>>
4985 constexpr _Iterator&
4986 operator+=(difference_type __x)
requires random_access_range<_Base<_Const>>
4992 constexpr _Iterator&
4993 operator-=(difference_type __x)
requires random_access_range<_Base<_Const>>
4999 constexpr decltype(
auto)
5000 operator[](difference_type __n)
const requires random_access_range<_Base<_Const>>
5002 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5003 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5004 }, _M_inner._M_current);
5007 friend constexpr bool
5008 operator==(
const _Iterator& __x,
const _Iterator& __y)
5009 requires equality_comparable<__ziperator<_Const>>
5010 {
return __x._M_inner == __y._M_inner; }
5012 friend constexpr auto
5013 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5014 requires random_access_range<_Base<_Const>>
5015 {
return __x._M_inner <=> __y._M_inner; }
5017 friend constexpr _Iterator
5018 operator+(
const _Iterator& __i, difference_type __n)
5019 requires random_access_range<_Base<_Const>>
5020 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5022 friend constexpr _Iterator
5023 operator+(difference_type __n,
const _Iterator& __i)
5024 requires random_access_range<_Base<_Const>>
5025 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5027 friend constexpr _Iterator
5028 operator-(
const _Iterator& __i, difference_type __n)
5029 requires random_access_range<_Base<_Const>>
5030 {
return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5032 friend constexpr difference_type
5033 operator-(
const _Iterator& __x,
const _Iterator& __y)
5034 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5035 {
return __x._M_inner - __y._M_inner; }
5038 template<copy_constructible _Fp, input_range... _Vs>
5039 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5040 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5041 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5042 template<
bool _Const>
5043 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5045 __zentinel<_Const> _M_inner;
5048 _Sentinel(__zentinel<_Const> __inner)
5052 friend class zip_transform_view;
5055 _Sentinel() =
default;
5058 _Sentinel(_Sentinel<!_Const> __i)
5059 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5063 template<
bool _OtherConst>
5064 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5065 friend constexpr bool
5066 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5067 {
return __x._M_inner == __y._M_inner; }
5069 template<
bool _OtherConst>
5070 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5071 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5072 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5073 {
return __x._M_inner - __y._M_inner; }
5075 template<
bool _OtherConst>
5076 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5077 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5078 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5079 {
return __x._M_inner - __y._M_inner; }
5086 template<
typename _Fp,
typename... _Ts>
5087 concept __can_zip_transform_view
5088 =
requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5091 struct _ZipTransform
5093 template<
typename _Fp,
typename... _Ts>
5094 requires (
sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5096 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5098 if constexpr (
sizeof...(_Ts) == 0)
5099 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5101 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5105 inline constexpr _ZipTransform zip_transform;
5108 template<forward_range _Vp,
size_t _Nm>
5109 requires view<_Vp> && (_Nm > 0)
5110 class adjacent_view :
public view_interface<adjacent_view<_Vp, _Nm>>
5112 _Vp _M_base = _Vp();
5114 template<
bool>
class _Iterator;
5115 template<
bool>
class _Sentinel;
5117 struct __as_sentinel
5121 adjacent_view()
requires default_initializable<_Vp> = default;
5124 adjacent_view(_Vp
__base)
5129 begin()
requires (!__detail::__simple_view<_Vp>)
5130 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5133 begin() const requires range<const _Vp>
5134 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5137 end()
requires (!__detail::__simple_view<_Vp>)
5139 if constexpr (common_range<_Vp>)
5140 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5142 return _Sentinel<false>(ranges::end(_M_base));
5146 end() const requires range<const _Vp>
5148 if constexpr (common_range<const _Vp>)
5149 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5151 return _Sentinel<true>(ranges::end(_M_base));
5155 size()
requires sized_range<_Vp>
5157 using _ST =
decltype(ranges::size(_M_base));
5158 using _CT = common_type_t<_ST, size_t>;
5159 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5160 __sz -= std::min<_CT>(__sz, _Nm - 1);
5161 return static_cast<_ST
>(__sz);
5165 size() const requires sized_range<const _Vp>
5167 using _ST =
decltype(ranges::size(_M_base));
5168 using _CT = common_type_t<_ST, size_t>;
5169 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5170 __sz -= std::min<_CT>(__sz, _Nm - 1);
5171 return static_cast<_ST
>(__sz);
5175 template<
typename _Vp,
size_t _Nm>
5176 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5177 = enable_borrowed_range<_Vp>;
5182 template<
typename _Tp,
size_t _Nm>
5187 template<
typename _Fp,
size_t _Nm>
5190 template<
typename... _Ts>
5192 __tuple_apply(
const tuple<_Ts...>&);
5194 template<
typename _Tp>
5195 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5200 template<forward_range _Vp,
size_t _Nm>
5201 requires view<_Vp> && (_Nm > 0)
5202 template<bool _Const>
5203 class adjacent_view<_Vp, _Nm>::_Iterator
5205 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5206 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5209 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5211 for (
auto& __i : _M_current)
5214 ranges::advance(__first, 1, __last);
5219 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5221 if constexpr (!bidirectional_range<_Base>)
5222 for (
auto& __it : _M_current)
5225 for (
size_t __i = 0; __i < _Nm; ++__i)
5227 _M_current[_Nm - 1 - __i] = __last;
5228 ranges::advance(__last, -1, __first);
5235 if constexpr (random_access_range<_Base>)
5236 return random_access_iterator_tag{};
5237 else if constexpr (bidirectional_range<_Base>)
5238 return bidirectional_iterator_tag{};
5240 return forward_iterator_tag{};
5243 friend class adjacent_view;
5245 template<forward_range _Wp, copy_constructible _Fp,
size_t _Mm>
5246 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5247 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5248 && std::__detail::__can_reference<
invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5249 range_reference_t<_Wp>>>
5250 friend class adjacent_transform_view;
5253 using iterator_category = input_iterator_tag;
5254 using iterator_concept =
decltype(_S_iter_concept());
5256 pair<range_value_t<_Base>, range_value_t<_Base>>,
5257 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5258 using difference_type = range_difference_t<_Base>;
5260 _Iterator() =
default;
5263 _Iterator(_Iterator<!_Const> __i)
5264 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5266 for (
size_t __j = 0; __j < _Nm; ++__j)
5267 _M_current[__j] =
std::move(__i._M_current[__j]);
5273 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5274 return __detail::__tuple_transform(__f, _M_current);
5277 constexpr _Iterator&
5280 for (
auto& __i : _M_current)
5293 constexpr _Iterator&
5294 operator--()
requires bidirectional_range<_Base>
5296 for (
auto& __i : _M_current)
5302 operator--(
int)
requires bidirectional_range<_Base>
5309 constexpr _Iterator&
5310 operator+=(difference_type __x)
5311 requires random_access_range<_Base>
5313 for (
auto& __i : _M_current)
5318 constexpr _Iterator&
5319 operator-=(difference_type __x)
5320 requires random_access_range<_Base>
5322 for (
auto& __i : _M_current)
5328 operator[](difference_type __n)
const
5329 requires random_access_range<_Base>
5331 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5332 return __detail::__tuple_transform(__f, _M_current);
5335 friend constexpr bool
5336 operator==(
const _Iterator& __x,
const _Iterator& __y)
5337 {
return __x._M_current.back() == __y._M_current.back(); }
5339 friend constexpr bool
5340 operator<(
const _Iterator& __x,
const _Iterator& __y)
5341 requires random_access_range<_Base>
5342 {
return __x._M_current.back() < __y._M_current.back(); }
5344 friend constexpr bool
5345 operator>(
const _Iterator& __x,
const _Iterator& __y)
5346 requires random_access_range<_Base>
5347 {
return __y < __x; }
5349 friend constexpr bool
5350 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5351 requires random_access_range<_Base>
5352 {
return !(__y < __x); }
5354 friend constexpr bool
5355 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5356 requires random_access_range<_Base>
5357 {
return !(__x < __y); }
5359 friend constexpr auto
5360 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5361 requires random_access_range<_Base>
5362 && three_way_comparable<iterator_t<_Base>>
5363 {
return __x._M_current.back() <=> __y._M_current.back(); }
5365 friend constexpr _Iterator
5366 operator+(
const _Iterator& __i, difference_type __n)
5367 requires random_access_range<_Base>
5374 friend constexpr _Iterator
5375 operator+(difference_type __n,
const _Iterator& __i)
5376 requires random_access_range<_Base>
5383 friend constexpr _Iterator
5384 operator-(
const _Iterator& __i, difference_type __n)
5385 requires random_access_range<_Base>
5392 friend constexpr difference_type
5393 operator-(
const _Iterator& __x,
const _Iterator& __y)
5394 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5395 {
return __x._M_current.back() - __y._M_current.back(); }
5397 friend constexpr auto
5398 iter_move(
const _Iterator& __i)
5399 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5401 friend constexpr void
5402 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5403 requires indirectly_swappable<iterator_t<_Base>>
5405 for (
size_t __i = 0; __i < _Nm; __i++)
5406 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5410 template<forward_range _Vp,
size_t _Nm>
5411 requires view<_Vp> && (_Nm > 0)
5412 template<bool _Const>
5413 class adjacent_view<_Vp, _Nm>::_Sentinel
5415 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5417 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5420 _Sentinel(sentinel_t<_Base> __end)
5424 friend class adjacent_view;
5427 _Sentinel() =
default;
5430 _Sentinel(_Sentinel<!_Const> __i)
5431 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5435 template<
bool _OtherConst>
5436 requires sentinel_for<sentinel_t<_Base>,
5437 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5438 friend constexpr bool
5439 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5440 {
return __x._M_current.back() == __y._M_end; }
5442 template<
bool _OtherConst>
5443 requires sized_sentinel_for<sentinel_t<_Base>,
5444 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5445 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5446 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5447 {
return __x._M_current.back() - __y._M_end; }
5449 template<
bool _OtherConst>
5450 requires sized_sentinel_for<sentinel_t<_Base>,
5451 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5452 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5453 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5454 {
return __y._M_end - __x._M_current.back(); }
5461 template<
size_t _Nm,
typename _Range>
5462 concept __can_adjacent_view
5463 =
requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5466 template<
size_t _Nm>
5467 struct _Adjacent : __adaptor::_RangeAdaptorClosure
5469 template<viewable_range _Range>
5470 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5472 operator() [[nodiscard]] (_Range&& __r)
const
5474 if constexpr (_Nm == 0)
5475 return views::empty<tuple<>>;
5477 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5481 template<
size_t _Nm>
5482 inline constexpr _Adjacent<_Nm> adjacent;
5484 inline constexpr auto pairwise = adjacent<2>;
5487 template<forward_range _Vp, copy_constructible _Fp,
size_t _Nm>
5488 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5489 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5490 && std::__detail::__can_reference<
invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5491 range_reference_t<_Vp>>>
5492 class adjacent_transform_view :
public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5494 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5495 adjacent_view<_Vp, _Nm> _M_inner;
5497 using _InnerView = adjacent_view<_Vp, _Nm>;
5499 template<
bool _Const>
5500 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5502 template<
bool _Const>
5503 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5505 template<
bool>
class _Iterator;
5506 template<
bool>
class _Sentinel;
5509 adjacent_transform_view() =
default;
5512 adjacent_transform_view(_Vp
__base, _Fp __fun)
5518 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5522 requires range<const _InnerView>
5523 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5524 range_reference_t<const _Vp>>
5525 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5530 if constexpr (common_range<_InnerView>)
5531 return _Iterator<false>(*
this, _M_inner.end());
5533 return _Sentinel<false>(_M_inner.end());
5538 requires range<const _InnerView>
5539 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5540 range_reference_t<const _Vp>>
5542 if constexpr (common_range<const _InnerView>)
5543 return _Iterator<true>(*
this, _M_inner.end());
5545 return _Sentinel<true>(_M_inner.end());
5549 size()
requires sized_range<_InnerView>
5550 {
return _M_inner.size(); }
5553 size() const requires sized_range<const _InnerView>
5554 {
return _M_inner.size(); }
5557 template<forward_range _Vp, copy_constructible _Fp,
size_t _Nm>
5558 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5559 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5560 && std::__detail::__can_reference<
invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5561 range_reference_t<_Vp>>>
5562 template<bool _Const>
5563 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5565 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5566 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5568 _Parent* _M_parent =
nullptr;
5569 _InnerIter<_Const> _M_inner;
5572 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5579 using __detail::__maybe_const_t;
5580 using __detail::__unarize;
5581 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5582 range_reference_t<_Base>>;
5583 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
5584 if constexpr (!is_lvalue_reference_v<_Res>)
5585 return input_iterator_tag{};
5586 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5587 return random_access_iterator_tag{};
5588 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5589 return bidirectional_iterator_tag{};
5590 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5591 return forward_iterator_tag{};
5593 return input_iterator_tag{};
5596 friend class adjacent_transform_view;
5599 using iterator_category =
decltype(_S_iter_cat());
5600 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
5603 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5604 range_reference_t<_Base>>>;
5605 using difference_type = range_difference_t<_Base>;
5607 _Iterator() =
default;
5610 _Iterator(_Iterator<!_Const> __i)
5611 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5612 : _M_parent(__i._M_parent), _M_inner(
std::move(__i._M_inner))
5615 constexpr decltype(
auto)
5618 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5620 }, _M_inner._M_current);
5623 constexpr _Iterator&
5638 constexpr _Iterator&
5639 operator--()
requires bidirectional_range<_Base>
5646 operator--(
int)
requires bidirectional_range<_Base>
5653 constexpr _Iterator&
5654 operator+=(difference_type __x)
requires random_access_range<_Base>
5660 constexpr _Iterator&
5661 operator-=(difference_type __x)
requires random_access_range<_Base>
5667 constexpr decltype(
auto)
5668 operator[](difference_type __n)
const requires random_access_range<_Base>
5670 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5672 }, _M_inner._M_current);
5675 friend constexpr bool
5676 operator==(
const _Iterator& __x,
const _Iterator& __y)
5677 {
return __x._M_inner == __y._M_inner; }
5679 friend constexpr bool
5680 operator<(
const _Iterator& __x,
const _Iterator& __y)
5681 requires random_access_range<_Base>
5682 {
return __x._M_inner < __y._M_inner; }
5684 friend constexpr bool
5685 operator>(
const _Iterator& __x,
const _Iterator& __y)
5686 requires random_access_range<_Base>
5687 {
return __x._M_inner > __y._M_inner; }
5689 friend constexpr bool
5690 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5691 requires random_access_range<_Base>
5692 {
return __x._M_inner <= __y._M_inner; }
5694 friend constexpr bool
5695 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5696 requires random_access_range<_Base>
5697 {
return __x._M_inner >= __y._M_inner; }
5699 friend constexpr auto
5700 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5701 requires random_access_range<_Base> &&
5702 three_way_comparable<_InnerIter<_Const>>
5703 {
return __x._M_inner <=> __y._M_inner; }
5705 friend constexpr _Iterator
5706 operator+(
const _Iterator& __i, difference_type __n)
5707 requires random_access_range<_Base>
5708 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5710 friend constexpr _Iterator
5711 operator+(difference_type __n,
const _Iterator& __i)
5712 requires random_access_range<_Base>
5713 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5715 friend constexpr _Iterator
5716 operator-(
const _Iterator& __i, difference_type __n)
5717 requires random_access_range<_Base>
5718 {
return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5720 friend constexpr difference_type
5721 operator-(
const _Iterator& __x,
const _Iterator& __y)
5722 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5723 {
return __x._M_inner - __y._M_inner; }
5726 template<forward_range _Vp, copy_constructible _Fp,
size_t _Nm>
5727 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5728 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5729 && std::__detail::__can_reference<
invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5730 range_reference_t<_Vp>>>
5731 template<bool _Const>
5732 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5734 _InnerSent<_Const> _M_inner;
5737 _Sentinel(_InnerSent<_Const> __inner)
5741 friend class adjacent_transform_view;
5744 _Sentinel() =
default;
5747 _Sentinel(_Sentinel<!_Const> __i)
5748 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5752 template<
bool _OtherConst>
5753 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5754 friend constexpr bool
5755 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5756 {
return __x._M_inner == __y._M_inner; }
5758 template<
bool _OtherConst>
5759 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5760 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5761 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5762 {
return __x._M_inner - __y._M_inner; }
5764 template<
bool _OtherConst>
5765 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5766 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5767 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5768 {
return __x._M_inner - __y._M_inner; }
5775 template<
size_t _Nm,
typename _Range,
typename _Fp>
5776 concept __can_adjacent_transform_view
5777 =
requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5778 (std::declval<_Range>(), std::declval<_Fp>()); };
5781 template<
size_t _Nm>
5782 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5784 template<viewable_range _Range,
typename _Fp>
5785 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5787 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
5789 if constexpr (_Nm == 0)
5790 return zip_transform(std::forward<_Fp>(__f));
5792 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5793 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5796 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5797 static constexpr int _S_arity = 2;
5798 static constexpr bool _S_has_simple_extra_args =
true;
5801 template<
size_t _Nm>
5802 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
5804 inline constexpr auto pairwise_transform = adjacent_transform<2>;
5807#define __cpp_lib_ranges_chunk 202202L
5811 template<
typename _Tp>
5812 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
5814 _Tp __r = __num / __denom;
5815 if (__num % __denom)
5822 requires input_range<_Vp>
5823 class chunk_view :
public view_interface<chunk_view<_Vp>>
5826 range_difference_t<_Vp> _M_n;
5827 range_difference_t<_Vp> _M_remainder = 0;
5828 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
5835 chunk_view(_Vp
__base, range_difference_t<_Vp> __n)
5837 { __glibcxx_assert(__n >= 0); }
5840 base() const & requires copy_constructible<_Vp>
5847 constexpr _OuterIter
5850 _M_current = ranges::begin(_M_base);
5851 _M_remainder = _M_n;
5852 return _OuterIter(*
this);
5855 constexpr default_sentinel_t
5856 end() const noexcept
5860 size()
requires sized_range<_Vp>
5862 return __detail::__to_unsigned_like(__detail::__div_ceil
5863 (ranges::distance(_M_base), _M_n));
5867 size() const requires sized_range<const _Vp>
5869 return __detail::__to_unsigned_like(__detail::__div_ceil
5870 (ranges::distance(_M_base), _M_n));
5874 template<
typename _Range>
5875 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
5878 requires input_range<_Vp>
5879 class chunk_view<_Vp>::_OuterIter
5881 chunk_view* _M_parent;
5884 _OuterIter(chunk_view& __parent) noexcept
5891 using iterator_concept = input_iterator_tag;
5892 using difference_type = range_difference_t<_Vp>;
5896 _OuterIter(_OuterIter&&) =
default;
5897 _OuterIter& operator=(_OuterIter&&) =
default;
5899 constexpr value_type
5903 return value_type(*_M_parent);
5906 constexpr _OuterIter&
5910 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
5911 ranges::end(_M_parent->_M_base));
5912 _M_parent->_M_remainder = _M_parent->_M_n;
5920 friend constexpr bool
5921 operator==(
const _OuterIter& __x, default_sentinel_t)
5923 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
5924 && __x._M_parent->_M_remainder != 0;
5927 friend constexpr difference_type
5928 operator-(default_sentinel_t,
const _OuterIter& __x)
5929 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5931 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
5933 if (__dist < __x._M_parent->_M_remainder)
5934 return __dist == 0 ? 0 : 1;
5936 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
5937 __x._M_parent->_M_n);
5940 friend constexpr difference_type
5941 operator-(
const _OuterIter& __x, default_sentinel_t __y)
5942 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5943 {
return -(__y - __x); }
5947 requires input_range<_Vp>
5948 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
5951 chunk_view* _M_parent;
5954 value_type(chunk_view& __parent) noexcept
5961 constexpr _InnerIter
5962 begin() const noexcept
5963 {
return _InnerIter(*_M_parent); }
5965 constexpr default_sentinel_t
5966 end() const noexcept
5971 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5973 return __detail::__to_unsigned_like
5974 (ranges::min(_M_parent->_M_remainder,
5975 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
5980 requires input_range<_Vp>
5981 class chunk_view<_Vp>::_InnerIter
5983 chunk_view* _M_parent;
5986 _InnerIter(chunk_view& __parent) noexcept
5990 friend _OuterIter::value_type;
5993 using iterator_concept = input_iterator_tag;
5994 using difference_type = range_difference_t<_Vp>;
5995 using value_type = range_value_t<_Vp>;
5997 _InnerIter(_InnerIter&&) =
default;
5998 _InnerIter& operator=(_InnerIter&&) =
default;
6000 constexpr const iterator_t<_Vp>&
6002 {
return *_M_parent->_M_current; }
6004 constexpr range_reference_t<_Vp>
6008 return **_M_parent->_M_current;
6011 constexpr _InnerIter&
6015 ++*_M_parent->_M_current;
6016 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6017 _M_parent->_M_remainder = 0;
6019 --_M_parent->_M_remainder;
6027 friend constexpr bool
6028 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6029 {
return __x._M_parent->_M_remainder == 0; }
6031 friend constexpr difference_type
6032 operator-(default_sentinel_t,
const _InnerIter& __x)
6033 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6035 return ranges::min(__x._M_parent->_M_remainder,
6036 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6039 friend constexpr difference_type
6040 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6041 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6042 {
return -(__y - __x); }
6046 requires forward_range<_Vp>
6047 class chunk_view<_Vp> :
public view_interface<chunk_view<_Vp>>
6050 range_difference_t<_Vp> _M_n;
6051 template<
bool>
class _Iterator;
6055 chunk_view(_Vp
__base, range_difference_t<_Vp> __n)
6057 { __glibcxx_assert(__n > 0); }
6060 base() const & requires copy_constructible<_Vp>
6068 begin()
requires (!__detail::__simple_view<_Vp>)
6069 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6072 begin() const requires forward_range<const _Vp>
6073 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6076 end()
requires (!__detail::__simple_view<_Vp>)
6078 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6080 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6081 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6083 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6084 return _Iterator<false>(
this, ranges::end(_M_base));
6090 end() const requires forward_range<const _Vp>
6092 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6094 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6095 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6097 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6098 return _Iterator<true>(
this, ranges::end(_M_base));
6104 size()
requires sized_range<_Vp>
6106 return __detail::__to_unsigned_like(__detail::__div_ceil
6107 (ranges::distance(_M_base), _M_n));
6111 size() const requires sized_range<const _Vp>
6113 return __detail::__to_unsigned_like(__detail::__div_ceil
6114 (ranges::distance(_M_base), _M_n));
6118 template<
typename _Vp>
6119 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6120 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6123 requires forward_range<_Vp>
6124 template<
bool _Const>
6125 class chunk_view<_Vp>::_Iterator
6127 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6128 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6130 iterator_t<_Base> _M_current = iterator_t<_Base>();
6131 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6132 range_difference_t<_Base> _M_n = 0;
6133 range_difference_t<_Base> _M_missing = 0;
6136 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6137 range_difference_t<_Base> __missing = 0)
6138 : _M_current(__current), _M_end(ranges::
end(__parent->_M_base)),
6139 _M_n(__parent->_M_n), _M_missing(__missing)
6145 if constexpr (random_access_range<_Base>)
6146 return random_access_iterator_tag{};
6147 else if constexpr (bidirectional_range<_Base>)
6148 return bidirectional_iterator_tag{};
6150 return forward_iterator_tag{};
6156 using iterator_category = input_iterator_tag;
6157 using iterator_concept =
decltype(_S_iter_cat());
6158 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6159 using difference_type = range_difference_t<_Base>;
6161 _Iterator() =
default;
6163 constexpr _Iterator(_Iterator<!_Const> __i)
6165 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6166 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6168 _M_n(__i._M_n), _M_missing(__i._M_missing)
6171 constexpr iterator_t<_Base>
6173 {
return _M_current; }
6175 constexpr value_type
6178 __glibcxx_assert(_M_current != _M_end);
6179 return views::take(subrange(_M_current, _M_end), _M_n);
6182 constexpr _Iterator&
6185 __glibcxx_assert(_M_current != _M_end);
6186 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6198 constexpr _Iterator&
6199 operator--()
requires bidirectional_range<_Base>
6201 ranges::advance(_M_current, _M_missing - _M_n);
6207 operator--(
int)
requires bidirectional_range<_Base>
6214 constexpr _Iterator&
6215 operator+=(difference_type __x)
6216 requires random_access_range<_Base>
6220 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6221 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6225 ranges::advance(_M_current, _M_n * __x + _M_missing);
6231 constexpr _Iterator&
6232 operator-=(difference_type __x)
6233 requires random_access_range<_Base>
6234 {
return *
this += -__x; }
6236 constexpr value_type
6237 operator[](difference_type __n)
const
6238 requires random_access_range<_Base>
6239 {
return *(*
this + __n); }
6241 friend constexpr bool
6242 operator==(
const _Iterator& __x,
const _Iterator& __y)
6243 {
return __x._M_current == __y._M_current; }
6245 friend constexpr bool
6246 operator==(
const _Iterator& __x, default_sentinel_t)
6247 {
return __x._M_current == __x._M_end; }
6249 friend constexpr bool
6250 operator<(
const _Iterator& __x,
const _Iterator& __y)
6251 requires random_access_range<_Base>
6252 {
return __x._M_current > __y._M_current; }
6254 friend constexpr bool
6255 operator>(
const _Iterator& __x,
const _Iterator& __y)
6256 requires random_access_range<_Base>
6257 {
return __y < __x; }
6259 friend constexpr bool
6260 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6261 requires random_access_range<_Base>
6262 {
return !(__y < __x); }
6264 friend constexpr bool
6265 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6266 requires random_access_range<_Base>
6267 {
return !(__x < __y); }
6269 friend constexpr auto
6270 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6271 requires random_access_range<_Base>
6272 && three_way_comparable<iterator_t<_Base>>
6273 {
return __x._M_current <=> __y._M_current; }
6275 friend constexpr _Iterator
6276 operator+(
const _Iterator& __i, difference_type __n)
6277 requires random_access_range<_Base>
6284 friend constexpr _Iterator
6285 operator+(difference_type __n,
const _Iterator& __i)
6286 requires random_access_range<_Base>
6293 friend constexpr _Iterator
6294 operator-(
const _Iterator& __i, difference_type __n)
6295 requires random_access_range<_Base>
6302 friend constexpr difference_type
6303 operator-(
const _Iterator& __x,
const _Iterator& __y)
6304 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6306 return (__x._M_current - __y._M_current
6307 + __x._M_missing - __y._M_missing) / __x._M_n;
6310 friend constexpr difference_type
6311 operator-(default_sentinel_t __y,
const _Iterator& __x)
6312 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6313 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6315 friend constexpr difference_type
6316 operator-(
const _Iterator& __x, default_sentinel_t __y)
6317 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6318 {
return -(__y - __x); }
6325 template<
typename _Range,
typename _Dp>
6326 concept __can_chunk_view
6327 =
requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6330 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6332 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6333 requires __detail::__can_chunk_view<_Range, _Dp>
6335 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6336 {
return chunk_view(std::forward<_Range>(__r), __n); }
6338 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6339 static constexpr int _S_arity = 2;
6340 static constexpr bool _S_has_simple_extra_args =
true;
6343 inline constexpr _Chunk chunk;
6346#define __cpp_lib_ranges_slide 202202L
6350 template<
typename _Vp>
6351 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6353 template<
typename _Vp>
6354 concept __slide_caches_last
6355 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6357 template<
typename _Vp>
6358 concept __slide_caches_first
6359 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6362 template<forward_range _Vp>
6364 class slide_view :
public view_interface<slide_view<_Vp>>
6367 range_difference_t<_Vp> _M_n;
6368 [[no_unique_address]]
6369 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6370 __detail::_CachedPosition<_Vp>> _M_cached_begin;
6371 [[no_unique_address]]
6372 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6373 __detail::_CachedPosition<_Vp>> _M_cached_end;
6375 template<
bool>
class _Iterator;
6380 slide_view(_Vp
__base, range_difference_t<_Vp> __n)
6382 { __glibcxx_assert(__n > 0); }
6385 begin()
requires (!(__detail::__simple_view<_Vp>
6386 && __detail::__slide_caches_nothing<const _Vp>))
6388 if constexpr (__detail::__slide_caches_first<_Vp>)
6390 iterator_t<_Vp> __it;
6391 if (_M_cached_begin._M_has_value())
6392 __it = _M_cached_begin._M_get(_M_base);
6395 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6396 _M_cached_begin._M_set(_M_base, __it);
6398 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6401 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6405 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6406 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6409 end()
requires (!(__detail::__simple_view<_Vp>
6410 && __detail::__slide_caches_nothing<const _Vp>))
6412 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6413 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(
size()),
6415 else if constexpr (__detail::__slide_caches_last<_Vp>)
6417 iterator_t<_Vp> __it;
6418 if (_M_cached_end._M_has_value())
6419 __it = _M_cached_end._M_get(_M_base);
6422 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6423 _M_cached_end._M_set(_M_base, __it);
6425 return _Iterator<false>(
std::move(__it), _M_n);
6427 else if constexpr (common_range<_Vp>)
6428 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6430 return _Sentinel(ranges::end(_M_base));
6434 end() const requires __detail::__slide_caches_nothing<const _Vp>
6435 {
return begin() + range_difference_t<const _Vp>(
size()); }
6438 size()
requires sized_range<_Vp>
6440 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6443 return __detail::__to_unsigned_like(__sz);
6447 size() const requires sized_range<const _Vp>
6449 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6452 return __detail::__to_unsigned_like(__sz);
6456 template<
typename _Range>
6457 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6459 template<
typename _Vp>
6460 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6461 = enable_borrowed_range<_Vp>;
6463 template<forward_range _Vp>
6465 template<
bool _Const>
6466 class slide_view<_Vp>::_Iterator
6468 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6469 static constexpr bool _S_last_elt_present
6470 = __detail::__slide_caches_first<_Base>;
6472 iterator_t<_Base> _M_current = iterator_t<_Base>();
6473 [[no_unique_address]]
6474 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6475 _M_last_elt =
decltype(_M_last_elt)();
6476 range_difference_t<_Base> _M_n = 0;
6479 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6480 requires (!_S_last_elt_present)
6481 : _M_current(__current), _M_n(__n)
6485 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6486 range_difference_t<_Base> __n)
6487 requires _S_last_elt_present
6488 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6494 if constexpr (random_access_range<_Base>)
6495 return random_access_iterator_tag{};
6496 else if constexpr (bidirectional_range<_Base>)
6497 return bidirectional_iterator_tag{};
6499 return forward_iterator_tag{};
6503 friend slide_view::_Sentinel;
6506 using iterator_category = input_iterator_tag;
6507 using iterator_concept =
decltype(_S_iter_concept());
6508 using value_type =
decltype(views::counted(_M_current, _M_n));
6509 using difference_type = range_difference_t<_Base>;
6511 _Iterator() =
default;
6514 _Iterator(_Iterator<!_Const> __i)
6515 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6516 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
6521 {
return views::counted(_M_current, _M_n); }
6523 constexpr _Iterator&
6527 if constexpr (_S_last_elt_present)
6540 constexpr _Iterator&
6541 operator--()
requires bidirectional_range<_Base>
6544 if constexpr (_S_last_elt_present)
6550 operator--(
int)
requires bidirectional_range<_Base>
6557 constexpr _Iterator&
6558 operator+=(difference_type __x)
6559 requires random_access_range<_Base>
6562 if constexpr (_S_last_elt_present)
6567 constexpr _Iterator&
6568 operator-=(difference_type __x)
6569 requires random_access_range<_Base>
6572 if constexpr (_S_last_elt_present)
6578 operator[](difference_type __n)
const
6579 requires random_access_range<_Base>
6580 {
return views::counted(_M_current + __n, _M_n); }
6582 friend constexpr bool
6583 operator==(
const _Iterator& __x,
const _Iterator& __y)
6585 if constexpr (_S_last_elt_present)
6586 return __x._M_last_elt == __y._M_last_elt;
6588 return __x._M_current == __y._M_current;
6591 friend constexpr bool
6592 operator<(
const _Iterator& __x,
const _Iterator& __y)
6593 requires random_access_range<_Base>
6594 {
return __x._M_current < __y._M_current; }
6596 friend constexpr bool
6597 operator>(
const _Iterator& __x,
const _Iterator& __y)
6598 requires random_access_range<_Base>
6599 {
return __y < __x; }
6601 friend constexpr bool
6602 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6603 requires random_access_range<_Base>
6604 {
return !(__y < __x); }
6606 friend constexpr bool
6607 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6608 requires random_access_range<_Base>
6609 {
return !(__x < __y); }
6611 friend constexpr auto
6612 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6613 requires random_access_range<_Base>
6614 && three_way_comparable<iterator_t<_Base>>
6615 {
return __x._M_current <=> __y._M_current; }
6617 friend constexpr _Iterator
6618 operator+(
const _Iterator& __i, difference_type __n)
6619 requires random_access_range<_Base>
6626 friend constexpr _Iterator
6627 operator+(difference_type __n,
const _Iterator& __i)
6628 requires random_access_range<_Base>
6635 friend constexpr _Iterator
6636 operator-(
const _Iterator& __i, difference_type __n)
6637 requires random_access_range<_Base>
6644 friend constexpr difference_type
6645 operator-(
const _Iterator& __x,
const _Iterator& __y)
6646 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6648 if constexpr (_S_last_elt_present)
6649 return __x._M_last_elt - __y._M_last_elt;
6651 return __x._M_current - __y._M_current;
6655 template<forward_range _Vp>
6657 class slide_view<_Vp>::_Sentinel
6659 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6662 _Sentinel(sentinel_t<_Vp> __end)
6669 _Sentinel() =
default;
6671 friend constexpr bool
6672 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
6673 {
return __x._M_last_elt == __y._M_end; }
6675 friend constexpr range_difference_t<_Vp>
6676 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
6677 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6678 {
return __x._M_last_elt - __y._M_end; }
6680 friend constexpr range_difference_t<_Vp>
6681 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
6682 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6683 {
return __y._M_end -__x._M_last_elt; }
6690 template<
typename _Range,
typename _Dp>
6691 concept __can_slide_view
6692 =
requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6695 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6697 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6698 requires __detail::__can_slide_view<_Range, _Dp>
6700 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6701 {
return slide_view(std::forward<_Range>(__r), __n); }
6703 using __adaptor::_RangeAdaptor<_Slide>::operator();
6704 static constexpr int _S_arity = 2;
6705 static constexpr bool _S_has_simple_extra_args =
true;
6708 inline constexpr _Slide slide;
6711#define __cpp_lib_ranges_chunk_by 202202L
6713 template<forward_range _Vp,
6714 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6715 requires view<_Vp> && is_object_v<_Pred>
6716 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
6718 _Vp _M_base = _Vp();
6719 __detail::__box<_Pred> _M_pred = _Pred();
6720 __detail::_CachedPosition<_Vp> _M_cached_begin;
6722 constexpr iterator_t<_Vp>
6723 _M_find_next(iterator_t<_Vp> __current)
6725 __glibcxx_assert(_M_pred.has_value());
6726 auto __pred = [
this]<
typename _Tp>(_Tp&& __x, _Tp&& __y) {
6727 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Tp>(__y)));
6729 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6730 return ranges::next(__it, 1, ranges::end(_M_base));
6733 constexpr iterator_t<_Vp>
6734 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
6736 __glibcxx_assert(_M_pred.has_value());
6737 auto __pred = [
this]<
typename _Tp>(_Tp&& __x, _Tp&& __y) {
6738 return !bool((*_M_pred)(std::forward<_Tp>(__y), std::forward<_Tp>(__x)));
6742 __glibcxx_assert(__rbegin != __rend);
6743 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6744 return ranges::prev(__it, 1, ranges::begin(_M_base));
6750 chunk_by_view()
requires (default_initializable<_Vp>
6751 && default_initializable<_Pred>)
6755 chunk_by_view(_Vp
__base, _Pred __pred)
6760 base() const & requires copy_constructible<_Vp>
6767 constexpr const _Pred&
6769 {
return *_M_pred; }
6774 __glibcxx_assert(_M_pred.has_value());
6775 iterator_t<_Vp> __it;
6776 if (_M_cached_begin._M_has_value())
6777 __it = _M_cached_begin._M_get(_M_base);
6780 __it = _M_find_next(ranges::begin(_M_base));
6781 _M_cached_begin._M_set(_M_base, __it);
6783 return _Iterator(*
this, ranges::begin(_M_base), __it);
6789 if constexpr (common_range<_Vp>)
6790 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
6796 template<
typename _Range,
typename _Pred>
6797 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6799 template<forward_range _Vp,
6800 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6801 requires view<_Vp> && is_object_v<_Pred>
6802 class chunk_by_view<_Vp, _Pred>::_Iterator
6804 chunk_by_view* _M_parent =
nullptr;
6805 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
6806 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
6809 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
6810 : _M_parent(
std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
6816 if constexpr (bidirectional_range<_Vp>)
6817 return bidirectional_iterator_tag{};
6819 return forward_iterator_tag{};
6822 friend chunk_by_view;
6825 using value_type = subrange<iterator_t<_Vp>>;
6826 using difference_type = range_difference_t<_Vp>;
6827 using iterator_category = input_iterator_tag;
6828 using iterator_concept =
decltype(_S_iter_concept());
6830 _Iterator() =
default;
6832 constexpr value_type
6835 __glibcxx_assert(_M_current != _M_next);
6836 return ranges::subrange(_M_current, _M_next);
6839 constexpr _Iterator&
6842 __glibcxx_assert(_M_current != _M_next);
6843 _M_current = _M_next;
6844 _M_next = _M_parent->_M_find_next(_M_current);
6856 constexpr _Iterator&
6857 operator--()
requires bidirectional_range<_Vp>
6859 _M_next = _M_current;
6860 _M_current = _M_parent->_M_find_prev(_M_next);
6865 operator--(
int)
requires bidirectional_range<_Vp>
6872 friend constexpr bool
6873 operator==(
const _Iterator& __x,
const _Iterator& __y)
6874 {
return __x._M_current == __y._M_current; }
6876 friend constexpr bool
6877 operator==(
const _Iterator& __x, default_sentinel_t)
6878 {
return __x._M_current == __x._M_next; }
6885 template<
typename _Range,
typename _Pred>
6886 concept __can_chunk_by_view
6887 =
requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
6890 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
6892 template<viewable_range _Range,
typename _Pred>
6893 requires __detail::__can_chunk_by_view<_Range, _Pred>
6895 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
6896 {
return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
6898 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
6899 static constexpr int _S_arity = 2;
6900 static constexpr bool _S_has_simple_extra_args =
true;
6903 inline constexpr _ChunkBy chunk_by;
6906#define __cpp_lib_ranges_join_with 202202L
6910 template<
typename _Range,
typename _Pattern>
6911 concept __compatible_joinable_ranges
6912 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
6913 && common_reference_with<range_reference_t<_Range>,
6914 range_reference_t<_Pattern>>
6915 && common_reference_with<range_rvalue_reference_t<_Range>,
6916 range_rvalue_reference_t<_Pattern>>;
6918 template<
typename _Range>
6919 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
6922 template<input_range _Vp, forward_range _Pattern>
6923 requires view<_Vp> && view<_Pattern>
6924 && input_range<range_reference_t<_Vp>>
6925 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
6926 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
6928 using _InnerRange = range_reference_t<_Vp>;
6930 _Vp _M_base = _Vp();
6931 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
6932 _Pattern _M_pattern = _Pattern();
6934 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6935 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
6936 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
6938 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
6939 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
6940 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
6942 template<
bool _Const>
6943 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
6945 template<
bool _Const>
6949 template<
bool _Const>
6950 requires _S_ref_is_glvalue<_Const>
6951 && forward_range<_Base<_Const>>
6952 && forward_range<_InnerBase<_Const>>
6953 struct __iter_cat<_Const>
6959 using _OuterIter = join_with_view::_OuterIter<_Const>;
6960 using _InnerIter = join_with_view::_InnerIter<_Const>;
6961 using _PatternIter = join_with_view::_PatternIter<_Const>;
6962 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
6963 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
6964 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
6965 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
6966 iter_reference_t<_PatternIter>>>)
6967 return input_iterator_tag{};
6968 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
6969 && derived_from<_InnerCat, bidirectional_iterator_tag>
6970 && derived_from<_PatternCat, bidirectional_iterator_tag>
6971 && common_range<_InnerBase<_Const>>
6972 && common_range<_PatternBase<_Const>>)
6973 return bidirectional_iterator_tag{};
6974 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
6975 && derived_from<_InnerCat, forward_iterator_tag>
6976 && derived_from<_PatternCat, forward_iterator_tag>)
6977 return forward_iterator_tag{};
6979 return input_iterator_tag{};
6982 using iterator_category =
decltype(_S_iter_cat());
6985 template<
bool>
struct _Iterator;
6986 template<
bool>
struct _Sentinel;
6989 join_with_view()
requires (default_initializable<_Vp>
6990 && default_initializable<_Pattern>)
6994 join_with_view(_Vp
__base, _Pattern __pattern)
6998 template<input_range _Range>
6999 requires constructible_from<_Vp, views::all_t<_Range>>
7000 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7002 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7003 : _M_base(views::all(
std::
forward<_Range>(__r))),
7004 _M_pattern(views::single(
std::
move(__e)))
7008 base() const& requires copy_constructible<_Vp>
7018 constexpr bool __use_const = is_reference_v<_InnerRange>
7019 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7020 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7025 requires input_range<const _Vp>
7026 && forward_range<const _Pattern>
7027 && is_reference_v<range_reference_t<const _Vp>>
7028 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7033 constexpr bool __use_const
7034 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7035 if constexpr (is_reference_v<_InnerRange>
7036 && forward_range<_Vp> && common_range<_Vp>
7037 && forward_range<_InnerRange> && common_range<_InnerRange>)
7038 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7040 return _Sentinel<__use_const>{*
this};
7045 requires input_range<const _Vp>
7046 && forward_range<const _Pattern>
7047 && is_reference_v<range_reference_t<const _Vp>>
7049 using _InnerConstRange = range_reference_t<const _Vp>;
7050 if constexpr (forward_range<const _Vp>
7051 && forward_range<_InnerConstRange>
7052 && common_range<const _Vp>
7053 && common_range<_InnerConstRange>)
7054 return _Iterator<true>{*
this, ranges::end(_M_base)};
7056 return _Sentinel<true>{*
this};
7060 template<
typename _Range,
typename _Pattern>
7061 join_with_view(_Range&&, _Pattern&&)
7062 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7064 template<input_range _Range>
7065 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7066 -> join_with_view<views::all_t<_Range>,
7067 single_view<range_value_t<range_reference_t<_Range>>>>;
7069 template<input_range _Vp, forward_range _Pattern>
7070 requires view<_Vp> && view<_Pattern>
7071 && input_range<range_reference_t<_Vp>>
7072 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7073 template<
bool _Const>
7074 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7076 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7077 using _Base = join_with_view::_Base<_Const>;
7078 using _InnerBase = join_with_view::_InnerBase<_Const>;
7079 using _PatternBase = join_with_view::_PatternBase<_Const>;
7081 using _OuterIter = join_with_view::_OuterIter<_Const>;
7082 using _InnerIter = join_with_view::_InnerIter<_Const>;
7083 using _PatternIter = join_with_view::_PatternIter<_Const>;
7085 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7087 _Parent* _M_parent =
nullptr;
7088 _OuterIter _M_outer_it = _OuterIter();
7089 variant<_PatternIter, _InnerIter> _M_inner_it;
7092 _Iterator(_Parent& __parent, iterator_t<_Base> __outer)
7095 if (_M_outer_it != ranges::end(_M_parent->_M_base))
7097 auto&& __inner = _M_update_inner(_M_outer_it);
7098 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7104 _M_update_inner(
const _OuterIter& __x)
7106 if constexpr (_S_ref_is_glvalue)
7109 return _M_parent->_M_inner._M_emplace_deref(__x);
7113 _M_get_inner(
const _OuterIter& __x)
7115 if constexpr (_S_ref_is_glvalue)
7118 return *_M_parent->_M_inner;
7126 if (_M_inner_it.index() == 0)
7128 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7131 auto&& __inner = _M_update_inner(_M_outer_it);
7132 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7136 auto&& __inner = _M_get_inner(_M_outer_it);
7137 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7140 if (++_M_outer_it == ranges::end(_M_parent->_M_base))
7142 if constexpr (_S_ref_is_glvalue)
7143 _M_inner_it.template emplace<0>();
7147 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7155 if constexpr (_S_ref_is_glvalue
7156 && bidirectional_range<_Base>
7157 && __detail::__bidirectional_common<_InnerBase>
7158 && __detail::__bidirectional_common<_PatternBase>)
7159 return bidirectional_iterator_tag{};
7160 else if constexpr (_S_ref_is_glvalue
7161 && forward_range<_Base>
7162 && forward_range<_InnerBase>)
7163 return forward_iterator_tag{};
7165 return input_iterator_tag{};
7168 friend join_with_view;
7171 using iterator_concept =
decltype(_S_iter_concept());
7173 using value_type = common_type_t<iter_value_t<_InnerIter>,
7174 iter_value_t<_PatternIter>>;
7175 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7176 iter_difference_t<_InnerIter>,
7177 iter_difference_t<_PatternIter>>;
7179 _Iterator()
requires default_initializable<_OuterIter> = default;
7182 _Iterator(_Iterator<!_Const> __i)
7184 && convertible_to<iterator_t<_Vp>, _OuterIter>
7185 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7186 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7187 : _M_parent(__i._M_parent),
7188 _M_outer_it(
std::
move(__i._M_outer_it))
7190 if (__i._M_inner_it.index() == 0)
7191 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7193 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7196 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7197 iter_reference_t<_PatternIter>>
7200 if (_M_inner_it.index() == 0)
7201 return *std::get<0>(_M_inner_it);
7203 return *std::get<1>(_M_inner_it);
7206 constexpr _Iterator&
7209 if (_M_inner_it.index() == 0)
7210 ++std::get<0>(_M_inner_it);
7212 ++std::get<1>(_M_inner_it);
7223 requires _S_ref_is_glvalue
7224 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7226 _Iterator __tmp = *
this;
7231 constexpr _Iterator&
7233 requires _S_ref_is_glvalue
7234 && bidirectional_range<_Base>
7235 && __detail::__bidirectional_common<_InnerBase>
7236 && __detail::__bidirectional_common<_PatternBase>
7238 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7240 auto&& __inner = *--_M_outer_it;
7241 _M_inner_it.template emplace<1>(ranges::end(__inner));
7246 if (_M_inner_it.index() == 0)
7248 auto& __it = std::get<0>(_M_inner_it);
7249 if (__it == ranges::begin(_M_parent->_M_pattern))
7251 auto&& __inner = *--_M_outer_it;
7252 _M_inner_it.template emplace<1>(ranges::end(__inner));
7259 auto& __it = std::get<1>(_M_inner_it);
7260 auto&& __inner = *_M_outer_it;
7261 if (__it == ranges::begin(__inner))
7262 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7268 if (_M_inner_it.index() == 0)
7269 --std::get<0>(_M_inner_it);
7271 --std::get<1>(_M_inner_it);
7277 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7278 && __detail::__bidirectional_common<_InnerBase>
7279 && __detail::__bidirectional_common<_PatternBase>
7281 _Iterator __tmp = *
this;
7286 friend constexpr bool
7287 operator==(
const _Iterator& __x,
const _Iterator& __y)
7288 requires _S_ref_is_glvalue
7289 && equality_comparable<_OuterIter> && equality_comparable<_InnerIter>
7290 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7292 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7293 iter_rvalue_reference_t<_PatternIter>>
7294 iter_move(
const _Iterator& __x)
7296 if (__x._M_inner_it.index() == 0)
7297 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7299 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7302 friend constexpr void
7303 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7304 requires indirectly_swappable<_InnerIter, _PatternIter>
7306 if (__x._M_inner_it.index() == 0)
7308 if (__y._M_inner_it.index() == 0)
7309 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7311 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7315 if (__y._M_inner_it.index() == 0)
7316 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7318 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7323 template<input_range _Vp, forward_range _Pattern>
7324 requires view<_Vp> && view<_Pattern>
7325 && input_range<range_reference_t<_Vp>>
7326 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7327 template<
bool _Const>
7328 class join_with_view<_Vp, _Pattern>::_Sentinel
7330 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7331 using _Base = join_with_view::_Base<_Const>;
7333 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7336 _Sentinel(_Parent& __parent)
7337 : _M_end(ranges::
end(__parent._M_base))
7340 friend join_with_view;
7343 _Sentinel() =
default;
7346 _Sentinel(_Sentinel<!_Const> __s)
7347 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7351 template<
bool _OtherConst>
7352 requires sentinel_for<sentinel_t<_Base>,
7353 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7354 friend constexpr bool
7355 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7356 {
return __x._M_outer_it == __y._M_end; }
7363 template<
typename _Range,
typename _Pattern>
7364 concept __can_join_with_view
7365 =
requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7368 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7370 template<viewable_range _Range,
typename _Pattern>
7371 requires __detail::__can_join_with_view<_Range, _Pattern>
7373 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7375 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7378 using _RangeAdaptor<_JoinWith>::operator();
7379 static constexpr int _S_arity = 2;
7380 template<
typename _Pattern>
7381 static constexpr bool _S_has_simple_extra_args
7382 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7385 inline constexpr _JoinWith join_with;
7388#define __cpp_lib_ranges_repeat 202207L
7390 template<copy_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7391 requires (is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7392 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
7393 class repeat_view :
public view_interface<repeat_view<_Tp, _Bound>>
7395 __detail::__box<_Tp> _M_value = _Tp();
7396 [[no_unique_address]] _Bound _M_bound = _Bound();
7400 template<
typename _Range>
7401 friend constexpr auto
7402 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7404 template<
typename _Range>
7405 friend constexpr auto
7406 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7409 repeat_view()
requires default_initializable<_Tp> = default;
7412 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7413 : _M_value(__value), _M_bound(__bound)
7415 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7416 __glibcxx_assert(__bound >= 0);
7420 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7421 : _M_value(
std::
move(__value)), _M_bound(__bound)
7424 template<
typename... _Args,
typename... _BoundArgs>
7425 requires constructible_from<_Tp, _Args...>
7426 && constructible_from<_Bound, _BoundArgs...>
7428 repeat_view(piecewise_construct_t,
7429 tuple<_Args...> __args,
7430 tuple<_BoundArgs...> __bound_args = tuple<>{})
7431 : _M_value(std::make_from_tuple<_Tp>(
std::move(__args))),
7432 _M_bound(std::make_from_tuple<_Bound>(
std::move(__bound_args)))
7440 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7443 constexpr unreachable_sentinel_t
7444 end() const noexcept
7445 {
return unreachable_sentinel; }
7448 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7449 {
return __detail::__to_unsigned_like(_M_bound); }
7452 template<
typename _Tp,
typename _Bound>
7453 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7455 template<copy_constructible _Tp, semiregular _Bound>
7456 requires __detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>
7457 class repeat_view<_Tp, _Bound>::_Iterator
7460 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7462 const _Tp* _M_value =
nullptr;
7463 __index_type _M_current = __index_type();
7466 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
7467 : _M_value(__value), _M_current(__bound)
7469 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7470 __glibcxx_assert(__bound >= 0);
7476 using iterator_concept = random_access_iterator_tag;
7477 using iterator_category = random_access_iterator_tag;
7478 using value_type = _Tp;
7479 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7481 __detail::__iota_diff_t<__index_type>>;
7483 _Iterator() =
default;
7485 constexpr const _Tp&
7487 {
return *_M_value; }
7489 constexpr _Iterator&
7504 constexpr _Iterator&
7507 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7508 __glibcxx_assert(_M_current > 0);
7521 constexpr _Iterator&
7522 operator+=(difference_type __n)
7524 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7525 __glibcxx_assert(_M_current + __n >= 0);
7530 constexpr _Iterator&
7531 operator-=(difference_type __n)
7533 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7534 __glibcxx_assert(_M_current - __n >= 0);
7539 constexpr const _Tp&
7540 operator[](difference_type __n)
const noexcept
7541 {
return *(*
this + __n); }
7543 friend constexpr bool
7544 operator==(
const _Iterator& __x,
const _Iterator& __y)
7545 {
return __x._M_current == __y._M_current; }
7547 friend constexpr auto
7548 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7549 {
return __x._M_current <=> __y._M_current; }
7551 friend constexpr _Iterator
7552 operator+(_Iterator __i, difference_type __n)
7558 friend constexpr _Iterator
7559 operator+(difference_type __n, _Iterator __i)
7560 {
return __i + __n; }
7562 friend constexpr _Iterator
7563 operator-(_Iterator __i, difference_type __n)
7569 friend constexpr difference_type
7570 operator-(
const _Iterator& __x,
const _Iterator& __y)
7572 return (
static_cast<difference_type
>(__x._M_current)
7573 -
static_cast<difference_type
>(__y._M_current));
7581 template<
typename _Tp,
typename _Bound>
7582 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
7584 template<
typename _Tp>
7585 concept __can_repeat_view
7586 =
requires { repeat_view(std::declval<_Tp>()); };
7588 template<
typename _Tp,
typename _Bound>
7589 concept __can_bounded_repeat_view
7590 =
requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7595 template<
typename _Tp>
7596 requires __detail::__can_repeat_view<_Tp>
7598 operator() [[nodiscard]] (_Tp&& __value)
const
7599 {
return repeat_view(std::forward<_Tp>(__value)); }
7601 template<
typename _Tp,
typename _Bound>
7602 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7604 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
7605 {
return repeat_view(std::forward<_Tp>(__value), __bound); }
7608 inline constexpr _Repeat repeat;
7612 template<
typename _Range>
7614 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7616 using _Tp = remove_cvref_t<_Range>;
7617 static_assert(__is_repeat_view<_Tp>);
7618 if constexpr (sized_range<_Tp>)
7619 return views::repeat(*__r._M_value,
std::min(ranges::distance(__r), __n));
7621 return views::repeat(*__r._M_value, __n);
7624 template<
typename _Range>
7626 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7628 using _Tp = remove_cvref_t<_Range>;
7629 static_assert(__is_repeat_view<_Tp>);
7630 if constexpr (sized_range<_Tp>)
7632 auto __sz = ranges::distance(__r);
7633 return views::repeat(*__r._M_value, __sz -
std::min(__sz, __n));
7641#define __cpp_lib_ranges_stride 202207L
7643 template<input_range _Vp>
7645 class stride_view :
public view_interface<stride_view<_Vp>>
7648 range_difference_t<_Vp> _M_stride;
7650 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7652 template<
bool _Const>
7656 template<
bool _Const>
7657 requires forward_range<_Base<_Const>>
7658 struct __iter_cat<_Const>
7664 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7665 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7666 return random_access_iterator_tag{};
7671 using iterator_category =
decltype(_S_iter_cat());
7674 template<
bool>
class _Iterator;
7678 stride_view(_Vp
__base, range_difference_t<_Vp> __stride)
7680 { __glibcxx_assert(__stride > 0); }
7683 base() const& requires copy_constructible<_Vp>
7690 constexpr range_difference_t<_Vp>
7691 stride() const noexcept
7692 {
return _M_stride; }
7695 begin()
requires (!__detail::__simple_view<_Vp>)
7696 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
7699 begin() const requires range<const _Vp>
7700 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
7703 end()
requires (!__detail::__simple_view<_Vp>)
7705 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7707 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7708 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
7710 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7711 return _Iterator<false>(
this, ranges::end(_M_base));
7717 end() const requires range<const _Vp>
7719 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7720 && forward_range<const _Vp>)
7722 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7723 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
7725 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7726 return _Iterator<true>(
this, ranges::end(_M_base));
7732 size()
requires sized_range<_Vp>
7734 return __detail::__to_unsigned_like
7735 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7739 size() const requires sized_range<const _Vp>
7741 return __detail::__to_unsigned_like
7742 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7746 template<
typename _Range>
7747 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7749 template<
typename _Vp>
7750 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7751 = enable_borrowed_range<_Vp>;
7753 template<input_range _Vp>
7755 template<
bool _Const>
7756 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
7758 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
7759 using _Base = stride_view::_Base<_Const>;
7761 iterator_t<_Base> _M_current = iterator_t<_Base>();
7762 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7763 range_difference_t<_Base> _M_stride = 0;
7764 range_difference_t<_Base> _M_missing = 0;
7767 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
7768 range_difference_t<_Base> __missing = 0)
7769 : _M_current(
std::
move(__current)), _M_end(ranges::
end(__parent->_M_base)),
7770 _M_stride(__parent->_M_stride), _M_missing(__missing)
7776 if constexpr (random_access_range<_Base>)
7777 return random_access_iterator_tag{};
7778 else if constexpr (bidirectional_range<_Base>)
7779 return bidirectional_iterator_tag{};
7780 else if constexpr (forward_range<_Base>)
7781 return forward_iterator_tag{};
7783 return input_iterator_tag{};
7789 using difference_type = range_difference_t<_Base>;
7790 using value_type = range_value_t<_Base>;
7791 using iterator_concept =
decltype(_S_iter_concept());
7794 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
7797 _Iterator(_Iterator<!_Const> __other)
7799 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7800 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7801 : _M_current(
std::
move(__other._M_current)), _M_end(
std::
move(__other._M_end)),
7802 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
7805 constexpr iterator_t<_Base>
7809 constexpr const iterator_t<_Base>&
7810 base() const & noexcept
7811 {
return _M_current; }
7813 constexpr decltype(
auto)
7815 {
return *_M_current; }
7817 constexpr _Iterator&
7820 __glibcxx_assert(_M_current != _M_end);
7821 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
7830 operator++(
int)
requires forward_range<_Base>
7837 constexpr _Iterator&
7838 operator--()
requires bidirectional_range<_Base>
7840 ranges::advance(_M_current, _M_missing - _M_stride);
7846 operator--(
int)
requires bidirectional_range<_Base>
7853 constexpr _Iterator&
7854 operator+=(difference_type __n)
requires random_access_range<_Base>
7858 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
7859 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
7863 ranges::advance(_M_current, _M_stride * __n + _M_missing);
7869 constexpr _Iterator&
7870 operator-=(difference_type __n)
requires random_access_range<_Base>
7871 {
return *
this += -__n; }
7873 constexpr decltype(
auto)
operator[](difference_type __n)
const
7874 requires random_access_range<_Base>
7875 {
return *(*
this + __n); }
7877 friend constexpr bool
7878 operator==(
const _Iterator& __x, default_sentinel_t)
7879 {
return __x._M_current == __x._M_end; }
7881 friend constexpr bool
7882 operator==(
const _Iterator& __x,
const _Iterator& __y)
7883 requires equality_comparable<iterator_t<_Base>>
7884 {
return __x._M_current == __y._M_current; }
7886 friend constexpr bool
7887 operator<(
const _Iterator& __x,
const _Iterator& __y)
7888 requires random_access_range<_Base>
7889 {
return __x._M_current < __y._M_current; }
7891 friend constexpr bool
7892 operator>(
const _Iterator& __x,
const _Iterator& __y)
7893 requires random_access_range<_Base>
7894 {
return __y._M_current < __x._M_current; }
7896 friend constexpr bool
7897 operator<=(
const _Iterator& __x,
const _Iterator& __y)
7898 requires random_access_range<_Base>
7899 {
return !(__y._M_current < __x._M_current); }
7901 friend constexpr bool
7902 operator>=(
const _Iterator& __x,
const _Iterator& __y)
7903 requires random_access_range<_Base>
7904 {
return !(__x._M_current < __y._M_current); }
7906 friend constexpr auto
7907 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7908 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
7909 {
return __x._M_current <=> __y._M_current; }
7911 friend constexpr _Iterator
7912 operator+(
const _Iterator& __i, difference_type __n)
7913 requires random_access_range<_Base>
7920 friend constexpr _Iterator
7921 operator+(difference_type __n,
const _Iterator& __i)
7922 requires random_access_range<_Base>
7923 {
return __i + __n; }
7925 friend constexpr _Iterator
7926 operator-(
const _Iterator& __i, difference_type __n)
7927 requires random_access_range<_Base>
7934 friend constexpr difference_type
7935 operator-(
const _Iterator& __x,
const _Iterator& __y)
7936 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7938 auto __n = __x._M_current - __y._M_current;
7939 if constexpr (forward_range<_Base>)
7940 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
7942 return -__detail::__div_ceil(-__n, __x._M_stride);
7944 return __detail::__div_ceil(__n, __x._M_stride);
7947 friend constexpr difference_type
7948 operator-(default_sentinel_t __y,
const _Iterator& __x)
7949 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7950 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
7952 friend constexpr difference_type
7953 operator-(
const _Iterator& __x, default_sentinel_t __y)
7954 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7955 {
return -(__y - __x); }
7957 friend constexpr range_rvalue_reference_t<_Base>
7958 iter_move(
const _Iterator& __i)
7959 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
7960 {
return ranges::iter_move(__i._M_current); }
7962 friend constexpr void
7963 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7964 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
7965 requires indirectly_swappable<iterator_t<_Base>>
7966 { ranges::iter_swap(__x._M_current, __y._M_current); }
7973 template<
typename _Range,
typename _Dp>
7974 concept __can_stride_view
7975 =
requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
7978 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
7980 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
7981 requires __detail::__can_stride_view<_Range, _Dp>
7983 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
7984 {
return stride_view(std::forward<_Range>(__r), __n); }
7986 using __adaptor::_RangeAdaptor<_Stride>::operator();
7987 static constexpr int _S_arity = 2;
7988 static constexpr bool _S_has_simple_extra_args =
true;
7991 inline constexpr _Stride stride;
7994#define __cpp_lib_ranges_cartesian_product 202207L
7998 template<
bool _Const,
typename _First,
typename... _Vs>
7999 concept __cartesian_product_is_random_access
8000 = (random_access_range<__maybe_const_t<_Const, _First>>
8002 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8003 && sized_range<__maybe_const_t<_Const, _Vs>>));
8005 template<
typename _Range>
8006 concept __cartesian_product_common_arg
8007 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8009 template<
bool _Const,
typename _First,
typename... _Vs>
8010 concept __cartesian_product_is_bidirectional
8011 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8013 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8014 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8016 template<
typename _First,
typename... _Vs>
8017 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8019 template<
typename... _Vs>
8020 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8022 template<
bool _Const,
template<
typename>
class FirstSent,
typename _First,
typename... _Vs>
8023 concept __cartesian_is_sized_sentinel
8024 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8025 iterator_t<__maybe_const_t<_Const, _First>>>
8027 && (sized_range<__maybe_const_t<_Const, _Vs>>
8028 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8029 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8031 template<__cartesian_product_common_arg _Range>
8033 __cartesian_common_arg_end(_Range& __r)
8035 if constexpr (common_range<_Range>)
8036 return ranges::end(__r);
8038 return ranges::begin(__r) + ranges::distance(__r);
8042 template<input_range _First, forward_range... _Vs>
8043 requires (view<_First> && ... && view<_Vs>)
8044 class cartesian_product_view :
public view_interface<cartesian_product_view<_First, _Vs...>>
8046 tuple<_First, _Vs...> _M_bases;
8048 template<
bool>
class _Iterator;
8051 _S_difference_type()
8057 range_difference_t<_First>,
8058 range_difference_t<_Vs>...>{};
8062 cartesian_product_view() =
default;
8065 cartesian_product_view(_First __first, _Vs... __rest)
8069 constexpr _Iterator<false>
8070 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8071 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8073 constexpr _Iterator<true>
8074 begin() const requires (range<const _First> && ... && range<const _Vs>)
8075 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8077 constexpr _Iterator<false>
8078 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8079 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8081 bool __empty_tail = [
this]<
size_t... _Is>(
index_sequence<_Is...>) {
8082 return (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8085 auto __it = __detail::__tuple_transform(ranges::begin, _M_bases);
8087 std::get<0>(__it) = __detail::__cartesian_common_arg_end(std::get<0>(_M_bases));
8088 return _Iterator<false>{*
this,
std::move(__it)};
8091 constexpr _Iterator<true>
8092 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8094 bool __empty_tail = [
this]<
size_t... _Is>(
index_sequence<_Is...>) {
8095 return (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8098 auto __it = __detail::__tuple_transform(ranges::begin, _M_bases);
8100 std::get<0>(__it) = __detail::__cartesian_common_arg_end(std::get<0>(_M_bases));
8101 return _Iterator<true>{*
this,
std::move(__it)};
8104 constexpr default_sentinel_t
8105 end() const noexcept
8109 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8111 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8113 auto __size =
static_cast<_ST
>(1);
8114#ifdef _GLIBCXX_ASSERTIONS
8115 if constexpr (integral<_ST>)
8118 = (__builtin_mul_overflow(__size,
8119 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8122 __glibcxx_assert(!__overflow);
8126 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8132 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8134 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8136 auto __size =
static_cast<_ST
>(1);
8137#ifdef _GLIBCXX_ASSERTIONS
8138 if constexpr (integral<_ST>)
8141 = (__builtin_mul_overflow(__size,
8142 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8145 __glibcxx_assert(!__overflow);
8149 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8155 template<
typename... _Vs>
8156 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8158 template<input_range _First, forward_range... _Vs>
8159 requires (view<_First> && ... && view<_Vs>)
8160 template<bool _Const>
8161 class cartesian_product_view<_First, _Vs...>::_Iterator
8163 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8164 _Parent* _M_parent =
nullptr;
8165 __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
8166 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8169 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8171 _M_current(
std::
move(__current))
8177 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8178 return random_access_iterator_tag{};
8179 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8180 return bidirectional_iterator_tag{};
8181 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8182 return forward_iterator_tag{};
8184 return input_iterator_tag{};
8187 friend cartesian_product_view;
8190 using iterator_category = input_iterator_tag;
8191 using iterator_concept =
decltype(_S_iter_concept());
8193 = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
8194 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8196 = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
8197 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8198 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8200 _Iterator()
requires forward_range<__maybe_const_t<_Const, _First>> = default;
8203 _Iterator(_Iterator<!_Const> __i)
8205 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8206 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8208 _M_current(
std::
move(__i._M_current))
8214 auto __f = [](
auto& __i) ->
decltype(
auto) {
8217 return __detail::__tuple_transform(__f, _M_current);
8220 constexpr _Iterator&
8232 operator++(
int)
requires forward_range<__maybe_const_t<_Const, _First>>
8239 constexpr _Iterator&
8241 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8249 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8256 constexpr _Iterator&
8257 operator+=(difference_type __x)
8258 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8264 constexpr _Iterator&
8265 operator-=(difference_type __x)
8266 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8267 {
return *
this += -__x; }
8270 operator[](difference_type __n)
const
8271 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8272 {
return *((*this) + __n); }
8274 friend constexpr bool
8275 operator==(
const _Iterator& __x,
const _Iterator& __y)
8276 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8277 {
return __x._M_current == __y._M_current; }
8279 friend constexpr bool
8280 operator==(
const _Iterator& __x, default_sentinel_t)
8283 return ((std::get<_Is>(__x._M_current)
8284 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8289 friend constexpr auto
8290 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8291 requires __detail::__all_random_access<_Const, _First, _Vs...>
8292 {
return __x._M_current <=> __y._M_current; }
8294 friend constexpr _Iterator
8295 operator+(_Iterator __x, difference_type __y)
8296 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8297 {
return __x += __y; }
8299 friend constexpr _Iterator
8300 operator+(difference_type __x, _Iterator __y)
8301 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8302 {
return __y += __x; }
8304 friend constexpr _Iterator
8305 operator-(_Iterator __x, difference_type __y)
8306 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8307 {
return __x -= __y; }
8309 friend constexpr difference_type
8310 operator-(
const _Iterator& __x,
const _Iterator& __y)
8311 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8312 {
return __x._M_distance_from(__y._M_current); }
8314 friend constexpr difference_type
8315 operator-(
const _Iterator& __i, default_sentinel_t)
8316 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8319 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8320 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8322 return __i._M_distance_from(__end_tuple);
8325 friend constexpr difference_type
8326 operator-(default_sentinel_t,
const _Iterator& __i)
8327 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8330 friend constexpr auto
8331 iter_move(
const _Iterator& __i)
8332 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8334 friend constexpr void
8335 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8336 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8338 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8341 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8346 template<
size_t _Nm =
sizeof...(_Vs)>
8350 auto& __it = std::get<_Nm>(_M_current);
8352 if constexpr (_Nm > 0)
8353 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8355 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8360 template<
size_t _Nm =
sizeof...(_Vs)>
8364 auto& __it = std::get<_Nm>(_M_current);
8365 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8367 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8368 if constexpr (_Nm > 0)
8374 template<
size_t _Nm =
sizeof...(_Vs)>
8376 _M_advance(difference_type __x)
8377 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8386 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8387 auto& __it = std::get<_Nm>(_M_current);
8388 if constexpr (_Nm == 0)
8390#ifdef _GLIBCXX_ASSERTIONS
8391 auto __size = ranges::ssize(__r);
8392 auto __begin = ranges::begin(__r);
8393 auto __offset = __it - __begin;
8394 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8400 auto __size = ranges::ssize(__r);
8401 auto __begin = ranges::begin(__r);
8402 auto __offset = __it - __begin;
8404 __x = __offset / __size;
8408 __offset = __size + __offset;
8411 __it = __begin + __offset;
8412 _M_advance<_Nm - 1>(__x);
8417 template<
typename _Tuple>
8418 constexpr difference_type
8419 _M_distance_from(
const _Tuple& __t)
const
8422 auto __sum =
static_cast<difference_type
>(0);
8423#ifdef _GLIBCXX_ASSERTIONS
8424 if constexpr (integral<difference_type>)
8427 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8429 __glibcxx_assert(!__overflow);
8433 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8438 template<
size_t _Nm,
typename _Tuple>
8439 constexpr difference_type
8440 _M_scaled_distance(
const _Tuple& __t)
const
8442 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8443 - std::get<_Nm>(__t));
8444#ifdef _GLIBCXX_ASSERTIONS
8445 if constexpr (integral<difference_type>)
8447 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8448 __glibcxx_assert(!__overflow);
8452 __dist *= _M_scaled_size<_Nm+1>();
8456 template<
size_t _Nm>
8457 constexpr difference_type
8458 _M_scaled_size()
const
8460 if constexpr (_Nm <=
sizeof...(_Vs))
8462 auto __size =
static_cast<difference_type
>(ranges::size
8463 (std::get<_Nm>(_M_parent->_M_bases)));
8464#ifdef _GLIBCXX_ASSERTIONS
8465 if constexpr (integral<difference_type>)
8467 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8468 __glibcxx_assert(!__overflow);
8472 __size *= _M_scaled_size<_Nm+1>();
8476 return static_cast<difference_type
>(1);
8484 template<
typename... _Ts>
8485 concept __can_cartesian_product_view
8486 =
requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8489 struct _CartesianProduct
8491 template<
typename... _Ts>
8492 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8494 operator() [[nodiscard]] (_Ts&&... __ts)
const
8496 if constexpr (
sizeof...(_Ts) == 0)
8497 return views::empty<tuple<>>;
8499 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8503 inline constexpr _CartesianProduct cartesian_product;
8506#define __cpp_lib_ranges_as_rvalue 202207L
8508 template<input_range _Vp>
8510 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
8512 _Vp _M_base = _Vp();
8515 as_rvalue_view()
requires default_initializable<_Vp> = default;
8518 as_rvalue_view(_Vp
__base)
8523 base() const& requires copy_constructible<_Vp>
8531 begin()
requires (!__detail::__simple_view<_Vp>)
8532 {
return move_iterator(ranges::begin(_M_base)); }
8535 begin() const requires range<const _Vp>
8536 {
return move_iterator(ranges::begin(_M_base)); }
8539 end()
requires (!__detail::__simple_view<_Vp>)
8541 if constexpr (common_range<_Vp>)
8542 return move_iterator(ranges::end(_M_base));
8544 return move_sentinel(ranges::end(_M_base));
8548 end() const requires range<const _Vp>
8550 if constexpr (common_range<const _Vp>)
8551 return move_iterator(ranges::end(_M_base));
8553 return move_sentinel(ranges::end(_M_base));
8557 size()
requires sized_range<_Vp>
8558 {
return ranges::size(_M_base); }
8561 size() const requires sized_range<const _Vp>
8562 {
return ranges::size(_M_base); }
8565 template<
typename _Range>
8566 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8568 template<
typename _Tp>
8569 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8570 = enable_borrowed_range<_Tp>;
8576 template<
typename _Tp>
8577 concept __can_as_rvalue_view =
requires { as_rvalue_view(std::declval<_Tp>()); };
8580 struct _AsRvalue : __adaptor::_RangeAdaptorClosure
8582 template<viewable_range _Range>
8583 requires __detail::__can_as_rvalue_view<_Range>
8585 operator() [[nodiscard]] (_Range&& __r)
const
8587 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8588 range_reference_t<_Range>>)
8589 return views::all(std::forward<_Range>(__r));
8591 return as_rvalue_view(std::forward<_Range>(__r));
8595 inline constexpr _AsRvalue as_rvalue;
8600 namespace views = ranges::views;
8602_GLIBCXX_END_NAMESPACE_VERSION
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
basic_istream< char > istream
Base class for char input streams.
typename make_unsigned< _Tp >::type make_unsigned_t
Alias template for make_unsigned.
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
typename conditional< _Cond, _Iftrue, _Iffalse >::type conditional_t
Alias template for conditional.
typename remove_cvref< _Tp >::type remove_cvref_t
typename invoke_result< _Fn, _Args... >::type invoke_result_t
std::invoke_result_t
constexpr auto tuple_cat(_Tpls &&... __tpls) -> typename __tuple_cat_result< _Tpls... >::__type
Create a tuple containing all elements from multiple tuple-like objects.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
constexpr reverse_iterator< _Iterator > make_reverse_iterator(_Iterator __i)
Generator function for reverse_iterator.
constexpr void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
Create a range of sequentially increasing values.
ISO C++ entities toplevel namespace is std.
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
constexpr default_sentinel_t default_sentinel
A default sentinel value.
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
integer_sequence< size_t, _Idx... > index_sequence
Alias template index_sequence.
constexpr _Iterator __base(_Iterator __it)
Class template for optional values.
A view that contains no elements.
A view that contains exactly one element.
Primary class template, tuple.
The ranges::view_interface class template.
[concept.constructible], concept constructible_from
[concept.defaultinitializable], concept default_initializable
[concept.copyconstructible], concept copy_constructible