30#ifndef _GLIBCXX_RANGES
31#define _GLIBCXX_RANGES 1
33#if __cplusplus > 201703L
36#pragma GCC system_header
50#if __cplusplus > 202002L
56#define __glibcxx_want_algorithm_default_value_type
57#define __glibcxx_want_ranges
58#define __glibcxx_want_ranges_as_const
59#define __glibcxx_want_ranges_as_rvalue
60#define __glibcxx_want_ranges_cartesian_product
61#define __glibcxx_want_ranges_concat
62#define __glibcxx_want_ranges_chunk
63#define __glibcxx_want_ranges_chunk_by
64#define __glibcxx_want_ranges_enumerate
65#define __glibcxx_want_ranges_iota
66#define __glibcxx_want_ranges_join_with
67#define __glibcxx_want_ranges_repeat
68#define __glibcxx_want_ranges_slide
69#define __glibcxx_want_ranges_stride
70#define __glibcxx_want_ranges_to_container
71#define __glibcxx_want_ranges_zip
74#ifdef __glibcxx_generator
75# include <bits/elements_of.h>
84namespace std _GLIBCXX_VISIBILITY(default)
86_GLIBCXX_BEGIN_NAMESPACE_VERSION
101 template<
typename _Tp>
requires is_object_v<_Tp>
103 :
public view_interface<empty_view<_Tp>>
106 static constexpr _Tp*
begin() noexcept {
return nullptr; }
107 static constexpr _Tp*
end() noexcept {
return nullptr; }
108 static constexpr _Tp*
data() noexcept {
return nullptr; }
109 static constexpr size_t size() noexcept {
return 0; }
110 static constexpr bool empty() noexcept {
return true; }
113 template<
typename _Tp>
114 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> =
true;
118#if __cpp_lib_ranges >= 202207L
120 template<
typename _Tp>
121 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
123 template<
typename _Tp>
124 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
127 template<__boxable _Tp>
128 struct __box : std::optional<_Tp>
130 using std::optional<_Tp>::optional;
134 noexcept(is_nothrow_default_constructible_v<_Tp>)
135 requires default_initializable<_Tp>
136 :
std::optional<_Tp>{std::in_place}
139 __box(
const __box&) =
default;
140 __box(__box&&) =
default;
142 using std::optional<_Tp>::operator=;
148 operator=(
const __box& __that)
149 noexcept(is_nothrow_copy_constructible_v<_Tp>)
150 requires (!copyable<_Tp>) && copy_constructible<_Tp>
155 this->emplace(*__that);
163 operator=(__box&& __that)
164 noexcept(is_nothrow_move_constructible_v<_Tp>)
165 requires (!movable<_Tp>)
178 template<
typename _Tp>
179 concept __boxable_copyable
180 = copy_constructible<_Tp>
181 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
182 && is_nothrow_copy_constructible_v<_Tp>));
183 template<
typename _Tp>
184 concept __boxable_movable
185 = (!copy_constructible<_Tp>)
186 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
192 template<__boxable _Tp>
193 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
197 [[no_unique_address]] _Tp _M_value = _Tp();
200 __box()
requires default_initializable<_Tp> = default;
203 __box(const _Tp& __t)
204 noexcept(is_nothrow_copy_constructible_v<_Tp>)
205 requires copy_constructible<_Tp>
211 noexcept(is_nothrow_move_constructible_v<_Tp>)
215 template<
typename... _Args>
216 requires constructible_from<_Tp, _Args...>
218 __box(in_place_t, _Args&&... __args)
219 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
223 __box(
const __box&) =
default;
224 __box(__box&&) =
default;
225 __box& operator=(
const __box&)
requires copyable<_Tp> =
default;
226 __box& operator=(__box&&)
requires movable<_Tp> = default;
231 operator=(const __box& __that) noexcept
232 requires (!copyable<_Tp>) && copy_constructible<_Tp>
234 static_assert(is_nothrow_copy_constructible_v<_Tp>);
245 operator=(__box&& __that)
noexcept
246 requires (!movable<_Tp>)
248 static_assert(is_nothrow_move_constructible_v<_Tp>);
258 has_value() const noexcept
273 constexpr const _Tp&&
278 operator->() noexcept
282 operator->() const noexcept
288#if __cpp_lib_ranges >= 202207L
289 template<move_constructible _Tp>
291 template<copy_constructible _Tp>
293 requires is_object_v<_Tp>
294 class single_view :
public view_interface<single_view<_Tp>>
297 single_view()
requires default_initializable<_Tp> = default;
300 single_view(const _Tp& __t)
301 noexcept(is_nothrow_copy_constructible_v<_Tp>)
302 requires copy_constructible<_Tp>
307 single_view(_Tp&& __t)
308 noexcept(is_nothrow_move_constructible_v<_Tp>)
314 template<
typename... _Args>
315 requires constructible_from<_Tp, _Args...>
317 single_view(in_place_t, _Args&&... __args)
318 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
319 : _M_value{in_place,
std::
forward<_Args>(__args)...}
327 begin() const noexcept
332 {
return data() + 1; }
336 {
return data() + 1; }
340 static constexpr bool
344 static constexpr size_t
350 {
return _M_value.operator->(); }
353 data() const noexcept
354 {
return _M_value.operator->(); }
357 [[no_unique_address]] __detail::__box<_Tp> _M_value;
360 template<
typename _Tp>
361 single_view(_Tp) -> single_view<_Tp>;
365 template<
typename _Wp>
366 constexpr auto __to_signed_like(_Wp __w)
noexcept
368 if constexpr (!integral<_Wp>)
369 return iter_difference_t<_Wp>();
370 else if constexpr (
sizeof(iter_difference_t<_Wp>) >
sizeof(_Wp))
371 return iter_difference_t<_Wp>(__w);
372 else if constexpr (
sizeof(ptrdiff_t) >
sizeof(_Wp))
373 return ptrdiff_t(__w);
374 else if constexpr (
sizeof(
long long) >
sizeof(_Wp))
375 return (
long long)(__w);
376#ifdef __SIZEOF_INT128__
377 else if constexpr (__SIZEOF_INT128__ >
sizeof(_Wp))
378 return __int128(__w);
381 return __max_diff_type(__w);
384 template<
typename _Wp>
385 using __iota_diff_t =
decltype(__to_signed_like(std::declval<_Wp>()));
387 template<
typename _It>
388 concept __decrementable = incrementable<_It>
391 { --__i } -> same_as<_It&>;
392 { __i-- } -> same_as<_It>;
395 template<
typename _It>
396 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
397 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
399 { __i += __n } -> same_as<_It&>;
400 { __i -= __n } -> same_as<_It&>;
404 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
407 template<
typename _Winc>
408 struct __iota_view_iter_cat
411 template<incrementable _Winc>
412 struct __iota_view_iter_cat<_Winc>
413 {
using iterator_category = input_iterator_tag; };
416 template<weakly_incrementable _Winc,
417 semiregular _Bound = unreachable_sentinel_t>
418 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
420 class iota_view :
public view_interface<iota_view<_Winc, _Bound>>
425 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
431 using namespace __detail;
432 if constexpr (__advanceable<_Winc>)
433 return random_access_iterator_tag{};
434 else if constexpr (__decrementable<_Winc>)
435 return bidirectional_iterator_tag{};
436 else if constexpr (incrementable<_Winc>)
437 return forward_iterator_tag{};
439 return input_iterator_tag{};
443 using iterator_concept =
decltype(_S_iter_concept());
445 using value_type = _Winc;
446 using difference_type = __detail::__iota_diff_t<_Winc>;
448 _Iterator()
requires default_initializable<_Winc> = default;
451 _Iterator(_Winc __value)
452 : _M_value(__value) { }
455 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
470 operator++(
int)
requires incrementable<_Winc>
478 operator--()
requires __detail::__decrementable<_Winc>
485 operator--(
int)
requires __detail::__decrementable<_Winc>
493 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
495 using __detail::__is_integer_like;
496 using __detail::__is_signed_integer_like;
497 if constexpr (__is_integer_like<_Winc>
498 && !__is_signed_integer_like<_Winc>)
500 if (__n >= difference_type(0))
501 _M_value +=
static_cast<_Winc
>(__n);
503 _M_value -=
static_cast<_Winc
>(-__n);
511 operator-=(difference_type __n)
requires __detail::__advanceable<_Winc>
513 using __detail::__is_integer_like;
514 using __detail::__is_signed_integer_like;
515 if constexpr (__is_integer_like<_Winc>
516 && !__is_signed_integer_like<_Winc>)
518 if (__n >= difference_type(0))
519 _M_value -=
static_cast<_Winc
>(__n);
521 _M_value +=
static_cast<_Winc
>(-__n);
529 operator[](difference_type __n)
const
530 requires __detail::__advanceable<_Winc>
531 {
return _Winc(_M_value + __n); }
533 friend constexpr bool
534 operator==(
const _Iterator& __x,
const _Iterator& __y)
535 requires equality_comparable<_Winc>
536 {
return __x._M_value == __y._M_value; }
538 friend constexpr bool
539 operator<(
const _Iterator& __x,
const _Iterator& __y)
540 requires totally_ordered<_Winc>
541 {
return __x._M_value < __y._M_value; }
543 friend constexpr bool
544 operator>(
const _Iterator& __x,
const _Iterator& __y)
545 requires totally_ordered<_Winc>
546 {
return __y < __x; }
548 friend constexpr bool
549 operator<=(
const _Iterator& __x,
const _Iterator& __y)
550 requires totally_ordered<_Winc>
551 {
return !(__y < __x); }
553 friend constexpr bool
554 operator>=(
const _Iterator& __x,
const _Iterator& __y)
555 requires totally_ordered<_Winc>
556 {
return !(__x < __y); }
558#ifdef __cpp_lib_three_way_comparison
559 friend constexpr auto
560 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
561 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
562 {
return __x._M_value <=> __y._M_value; }
565 friend constexpr _Iterator
566 operator+(_Iterator __i, difference_type __n)
567 requires __detail::__advanceable<_Winc>
573 friend constexpr _Iterator
574 operator+(difference_type __n, _Iterator __i)
575 requires __detail::__advanceable<_Winc>
576 {
return __i += __n; }
578 friend constexpr _Iterator
579 operator-(_Iterator __i, difference_type __n)
580 requires __detail::__advanceable<_Winc>
586 friend constexpr difference_type
587 operator-(
const _Iterator& __x,
const _Iterator& __y)
588 requires __detail::__advanceable<_Winc>
590 using __detail::__is_integer_like;
591 using __detail::__is_signed_integer_like;
592 using _Dt = difference_type;
593 if constexpr (__is_integer_like<_Winc>)
595 if constexpr (__is_signed_integer_like<_Winc>)
596 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
598 return (__y._M_value > __x._M_value)
599 ? _Dt(-_Dt(__y._M_value - __x._M_value))
600 : _Dt(__x._M_value - __y._M_value);
603 return __x._M_value - __y._M_value;
607 _Winc _M_value = _Winc();
617 _M_equal(
const _Iterator& __x)
const
618 {
return __x._M_value == _M_bound; }
621 _M_distance_from(
const _Iterator& __x)
const
622 {
return _M_bound - __x._M_value; }
624 _Bound _M_bound = _Bound();
627 _Sentinel() =
default;
630 _Sentinel(_Bound __bound)
631 : _M_bound(__bound) { }
633 friend constexpr bool
634 operator==(
const _Iterator& __x,
const _Sentinel& __y)
635 {
return __y._M_equal(__x); }
637 friend constexpr iter_difference_t<_Winc>
638 operator-(
const _Iterator& __x,
const _Sentinel& __y)
639 requires sized_sentinel_for<_Bound, _Winc>
640 {
return -__y._M_distance_from(__x); }
642 friend constexpr iter_difference_t<_Winc>
643 operator-(
const _Sentinel& __x,
const _Iterator& __y)
644 requires sized_sentinel_for<_Bound, _Winc>
645 {
return __x._M_distance_from(__y); }
650 _Winc _M_value = _Winc();
651 [[no_unique_address]] _Bound _M_bound = _Bound();
654 iota_view()
requires default_initializable<_Winc> = default;
657 iota_view(_Winc __value)
662 iota_view(type_identity_t<_Winc> __value,
663 type_identity_t<_Bound> __bound)
664 : _M_value(__value), _M_bound(__bound)
666 if constexpr (totally_ordered_with<_Winc, _Bound>)
667 __glibcxx_assert(
bool(__value <= __bound) );
671 iota_view(_Iterator __first, _Iterator __last)
672 requires same_as<_Winc, _Bound>
673 : iota_view(__first._M_value, __last._M_value)
677 iota_view(_Iterator __first, unreachable_sentinel_t __last)
678 requires same_as<_Bound, unreachable_sentinel_t>
679 : iota_view(__first._M_value, __last)
683 iota_view(_Iterator __first, _Sentinel __last)
684 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
685 : iota_view(__first._M_value, __last._M_bound)
689 begin()
const {
return _Iterator{_M_value}; }
694 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
695 return unreachable_sentinel;
697 return _Sentinel{_M_bound};
701 end() const requires same_as<_Winc, _Bound>
702 {
return _Iterator{_M_bound}; }
708 {
return _M_value == _M_bound; }
712 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
713 || (integral<_Winc> && integral<_Bound>)
714 || sized_sentinel_for<_Bound, _Winc>
716 using __detail::__is_integer_like;
717 using __detail::__to_unsigned_like;
718 if constexpr (integral<_Winc> && integral<_Bound>)
721 return _Up(_M_bound) - _Up(_M_value);
723 else if constexpr (__is_integer_like<_Winc>)
724 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
726 return __to_unsigned_like(_M_bound - _M_value);
730 template<
typename _Winc,
typename _Bound>
731 requires (!__detail::__is_integer_like<_Winc>
732 || !__detail::__is_integer_like<_Bound>
733 || (__detail::__is_signed_integer_like<_Winc>
734 == __detail::__is_signed_integer_like<_Bound>))
735 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
737 template<
typename _Winc,
typename _Bound>
738 inline constexpr bool
739 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
743 template<
typename _Tp>
744 inline constexpr empty_view<_Tp>
empty{};
748 template<
typename _Tp>
749 concept __can_single_view
750 =
requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
755 template<__detail::__can_single_view _Tp>
757 operator() [[nodiscard]] (_Tp&& __e)
const
758 noexcept(
noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
759 {
return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
762 inline constexpr _Single single{};
766 template<
typename... _Args>
767 concept __can_iota_view =
requires { iota_view(std::declval<_Args>()...); };
772 template<__detail::__can_iota_view _Tp>
774 operator() [[nodiscard]] (_Tp&& __e)
const
775 {
return iota_view(std::forward<_Tp>(__e)); }
777 template<
typename _Tp,
typename _Up>
778 requires __detail::__can_iota_view<_Tp, _Up>
780 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
781 {
return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
784 inline constexpr _Iota
iota{};
790 template<
typename _Val,
typename _CharT,
typename _Traits>
791 concept __stream_extractable
792 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
795 template<movable _Val,
typename _CharT,
796 typename _Traits = char_traits<_CharT>>
797 requires default_initializable<_Val>
798 && __detail::__stream_extractable<_Val, _CharT, _Traits>
799 class basic_istream_view
800 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
804 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
811 *_M_stream >> _M_object;
812 return _Iterator{
this};
815 constexpr default_sentinel_t
820 basic_istream<_CharT, _Traits>* _M_stream;
821 _Val _M_object = _Val();
826 using iterator_concept = input_iterator_tag;
827 using difference_type = ptrdiff_t;
828 using value_type = _Val;
831 _Iterator(basic_istream_view* __parent) noexcept
832 : _M_parent(__parent)
835 _Iterator(
const _Iterator&) =
delete;
836 _Iterator(_Iterator&&) =
default;
837 _Iterator& operator=(
const _Iterator&) =
delete;
838 _Iterator& operator=(_Iterator&&) =
default;
843 *_M_parent->_M_stream >> _M_parent->_M_object;
853 {
return _M_parent->_M_object; }
856 operator==(
const _Iterator& __x, default_sentinel_t)
857 {
return __x._M_at_end(); }
860 basic_istream_view* _M_parent;
864 {
return !*_M_parent->_M_stream; }
870 template<
typename _Val>
871 using istream_view = basic_istream_view<_Val, char>;
873 template<
typename _Val>
874 using wistream_view = basic_istream_view<_Val, wchar_t>;
880 template<
typename _Tp,
typename _Up>
881 concept __can_istream_view =
requires (_Up __e) {
882 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
886 template<
typename _Tp>
889 template<
typename _CharT,
typename _Traits>
891 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
892 requires __detail::__can_istream_view<_Tp, remove_reference_t<
decltype(__e)>>
893 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
896 template<
typename _Tp>
897 inline constexpr _Istream<_Tp>
istream;
905 template<
typename _Tp,
int _Disc>
914 template<
bool _Present,
typename _Tp,
int _Disc = 0>
915 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
918 template<
bool _Const,
typename _Tp>
919 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
924using __detail::__maybe_const_t;
926namespace views::__adaptor
929 template<
typename _Adaptor,
typename... _Args>
930 concept __adaptor_invocable
931 =
requires { std::declval<_Adaptor>()(declval<_Args>()...); };
935 template<
typename _Adaptor,
typename... _Args>
936 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
937 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
938 && (constructible_from<decay_t<_Args>, _Args> && ...);
940 template<
typename _Adaptor,
typename... _Args>
943 template<
typename _Lhs,
typename _Rhs>
951 template<
typename _Derived>
952 struct _RangeAdaptorClosure;
954 template<
typename _Tp,
typename _Up>
955 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
956 void __is_range_adaptor_closure_fn
957 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
959 template<
typename _Tp>
960 concept __is_range_adaptor_closure
961 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
963#pragma GCC diagnostic push
964#pragma GCC diagnostic ignored "-Wdangling-reference"
966 template<
typename _Self,
typename _Range>
967 requires __is_range_adaptor_closure<_Self>
968 && __adaptor_invocable<_Self, _Range>
971 {
return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
975 template<
typename _Lhs,
typename _Rhs>
976 requires __is_range_adaptor_closure<_Lhs>
977 && __is_range_adaptor_closure<_Rhs>
981 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
982 std::forward<_Rhs>(__rhs)};
984#pragma GCC diagnostic pop
986 template<
typename _Derived>
987 struct _RangeAdaptorClosure
993 template<
typename _Self,
typename _Range>
994 requires __is_range_adaptor_closure<_Self>
995 && __adaptor_invocable<_Self, _Range>
996 friend constexpr auto
999 template<
typename _Lhs,
typename _Rhs>
1000 requires __is_range_adaptor_closure<_Lhs>
1001 && __is_range_adaptor_closure<_Rhs>
1002 friend constexpr auto
1017 template<
typename _Derived>
1018 struct _RangeAdaptor
1022 template<
typename... _Args>
1023 requires __adaptor_partial_app_viable<_Derived, _Args...>
1025 operator()(_Args&&... __args)
const
1027 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1034 template<
typename _Adaptor>
1035 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1039 template<
typename _Adaptor,
typename... _Args>
1040 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1041 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1045 template<
typename _Adaptor,
typename... _Args>
1046 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1048 tuple<_Args...> _M_args;
1052 template<
typename... _Ts>
1054 _Partial(
int, _Ts&&... __args)
1060#if __cpp_explicit_this_parameter
1061 template<
typename _Self,
typename _Range>
1062 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1064 operator()(
this _Self&& __self, _Range&& __r)
1066 auto __forwarder = [&__r] (
auto&&... __args) {
1067 return _Adaptor{}(std::forward<_Range>(__r),
1068 std::forward<decltype(__args)>(__args)...);
1070 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args);
1073 template<
typename _Range>
1074 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1076 operator()(_Range&& __r)
const &
1078 auto __forwarder = [&__r] (
const auto&... __args) {
1079 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1081 return std::apply(__forwarder, _M_args);
1084 template<
typename _Range>
1085 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1087 operator()(_Range&& __r) &&
1089 auto __forwarder = [&__r] (
auto&... __args) {
1090 return _Adaptor{}(std::forward<_Range>(__r),
std::move(__args)...);
1092 return std::apply(__forwarder, _M_args);
1095 template<
typename _Range>
1097 operator()(_Range&& __r)
const && =
delete;
1103 template<
typename _Adaptor,
typename _Arg>
1104 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1108 template<
typename _Tp>
1110 _Partial(
int, _Tp&& __arg)
1114#if __cpp_explicit_this_parameter
1115 template<
typename _Self,
typename _Range>
1116 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1118 operator()(
this _Self&& __self, _Range&& __r)
1120 return _Adaptor{}(std::forward<_Range>(__r),
1121 __like_t<_Self, _Partial>(__self)._M_arg);
1124 template<
typename _Range>
1125 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1127 operator()(_Range&& __r)
const &
1128 {
return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1130 template<
typename _Range>
1131 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1133 operator()(_Range&& __r) &&
1134 {
return _Adaptor{}(std::forward<_Range>(__r),
std::move(_M_arg)); }
1136 template<
typename _Range>
1138 operator()(_Range&& __r)
const && =
delete;
1146 template<
typename _Adaptor,
typename... _Args>
1147 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1148 && (is_trivially_copy_constructible_v<_Args> && ...)
1149 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1151 tuple<_Args...> _M_args;
1153 template<
typename... _Ts>
1155 _Partial(
int, _Ts&&... __args)
1161 template<
typename _Range>
1162 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1164 operator()(_Range&& __r)
const
1166 auto __forwarder = [&__r] (
const auto&... __args) {
1167 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1169 return std::apply(__forwarder, _M_args);
1172 static constexpr bool _S_has_simple_call_op =
true;
1177 template<
typename _Adaptor,
typename _Arg>
1178 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1179 && is_trivially_copy_constructible_v<_Arg>
1180 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1184 template<
typename _Tp>
1186 _Partial(
int, _Tp&& __arg)
1190 template<
typename _Range>
1191 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1193 operator()(_Range&& __r)
const
1194 {
return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1196 static constexpr bool _S_has_simple_call_op =
true;
1199 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1200 concept __pipe_invocable
1201 =
requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1205 template<
typename _Lhs,
typename _Rhs>
1206 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1208 [[no_unique_address]] _Lhs _M_lhs;
1209 [[no_unique_address]] _Rhs _M_rhs;
1211 template<
typename _Tp,
typename _Up>
1213 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1219#if __cpp_explicit_this_parameter
1220 template<
typename _Self,
typename _Range>
1221 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1223 operator()(
this _Self&& __self, _Range&& __r)
1225 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1226 (__like_t<_Self, _Pipe>(__self)._M_lhs
1227 (std::forward<_Range>(__r))));
1230 template<
typename _Range>
1231 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1233 operator()(_Range&& __r)
const &
1234 {
return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1236 template<
typename _Range>
1237 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1239 operator()(_Range&& __r) &&
1242 template<
typename _Range>
1244 operator()(_Range&& __r)
const && =
delete;
1252 template<
typename _Lhs,
typename _Rhs>
1253 requires __closure_has_simple_call_op<_Lhs>
1254 && __closure_has_simple_call_op<_Rhs>
1255 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1257 [[no_unique_address]] _Lhs _M_lhs;
1258 [[no_unique_address]] _Rhs _M_rhs;
1260 template<
typename _Tp,
typename _Up>
1262 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1266 template<
typename _Range>
1267 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1269 operator()(_Range&& __r)
const
1270 {
return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1272 static constexpr bool _S_has_simple_call_op =
true;
1276#if __cpp_lib_ranges >= 202202L
1278 template<
typename _Derived>
1279 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1280 class range_adaptor_closure
1281 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1285 template<range _Range>
requires is_object_v<_Range>
1286 class ref_view :
public view_interface<ref_view<_Range>>
1291 static void _S_fun(_Range&);
1292 static void _S_fun(_Range&&) =
delete;
1295 template<__detail::__different_from<ref_view> _Tp>
1296 requires convertible_to<_Tp, _Range&>
1297 &&
requires { _S_fun(declval<_Tp>()); }
1300 noexcept(
noexcept(
static_cast<_Range&
>(std::declval<_Tp>())))
1308 constexpr iterator_t<_Range>
1310 {
return ranges::begin(*_M_r); }
1312 constexpr sentinel_t<_Range>
1314 {
return ranges::end(*_M_r); }
1317 empty() const requires requires { ranges::empty(*_M_r); }
1318 {
return ranges::empty(*_M_r); }
1321 size() const requires sized_range<_Range>
1322 {
return ranges::size(*_M_r); }
1325 data() const requires contiguous_range<_Range>
1326 {
return ranges::data(*_M_r); }
1329 template<
typename _Range>
1330 ref_view(_Range&) -> ref_view<_Range>;
1332 template<
typename _Tp>
1333 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1335 template<range _Range>
1336 requires movable<_Range>
1337 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1338 class owning_view : public view_interface<owning_view<_Range>>
1341 _Range _M_r = _Range();
1344 owning_view()
requires default_initializable<_Range> = default;
1347 owning_view(_Range&& __t)
1348 noexcept(is_nothrow_move_constructible_v<_Range>)
1352 owning_view(owning_view&&) =
default;
1353 owning_view& operator=(owning_view&&) =
default;
1359 constexpr const _Range&
1360 base() const& noexcept
1367 constexpr const _Range&&
1368 base() const&& noexcept
1371 constexpr iterator_t<_Range>
1373 {
return ranges::begin(_M_r); }
1375 constexpr sentinel_t<_Range>
1377 {
return ranges::end(_M_r); }
1380 begin() const requires range<const _Range>
1381 {
return ranges::begin(_M_r); }
1384 end() const requires range<const _Range>
1385 {
return ranges::end(_M_r); }
1388 empty()
requires requires { ranges::empty(_M_r); }
1389 {
return ranges::empty(_M_r); }
1392 empty() const requires requires { ranges::empty(_M_r); }
1393 {
return ranges::empty(_M_r); }
1396 size()
requires sized_range<_Range>
1397 {
return ranges::size(_M_r); }
1400 size() const requires sized_range<const _Range>
1401 {
return ranges::size(_M_r); }
1404 data()
requires contiguous_range<_Range>
1405 {
return ranges::data(_M_r); }
1408 data() const requires contiguous_range<const _Range>
1409 {
return ranges::data(_M_r); }
1412 template<
typename _Tp>
1413 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1414 = enable_borrowed_range<_Tp>;
1420 template<
typename _Range>
1421 concept __can_ref_view =
requires { ref_view{std::declval<_Range>()}; };
1423 template<
typename _Range>
1424 concept __can_owning_view =
requires { owning_view{std::declval<_Range>()}; };
1427 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1429 template<
typename _Range>
1430 static constexpr bool
1433 if constexpr (view<decay_t<_Range>>)
1434 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1435 else if constexpr (__detail::__can_ref_view<_Range>)
1438 return noexcept(owning_view{std::declval<_Range>()});
1441 template<viewable_range _Range>
1442 requires view<decay_t<_Range>>
1443 || __detail::__can_ref_view<_Range>
1444 || __detail::__can_owning_view<_Range>
1446 operator() [[nodiscard]] (_Range&& __r)
const
1447 noexcept(_S_noexcept<_Range>())
1449 if constexpr (view<decay_t<_Range>>)
1450 return std::forward<_Range>(__r);
1451 else if constexpr (__detail::__can_ref_view<_Range>)
1452 return ref_view{std::forward<_Range>(__r)};
1454 return owning_view{std::forward<_Range>(__r)};
1457 static constexpr bool _S_has_simple_call_op =
true;
1460 inline constexpr _All all;
1462 template<viewable_range _Range>
1463 using all_t =
decltype(all(std::declval<_Range>()));
1468 template<
typename _Tp>
1469 struct __non_propagating_cache
1477 template<
typename _Tp>
1478 requires is_object_v<_Tp>
1479 struct __non_propagating_cache<_Tp>
1480 :
protected _Optional_base<_Tp>
1482 __non_propagating_cache() =
default;
1485 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1489 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1490 { __other._M_reset(); }
1492 constexpr __non_propagating_cache&
1493 operator=(
const __non_propagating_cache& __other)
noexcept
1500 constexpr __non_propagating_cache&
1501 operator=(__non_propagating_cache&& __other)
noexcept
1508 constexpr __non_propagating_cache&
1509 operator=(_Tp __val)
1512 this->_M_payload._M_construct(
std::move(__val));
1517 operator bool() const noexcept
1518 {
return this->_M_is_engaged(); }
1522 {
return this->_M_get(); }
1524 constexpr const _Tp&
1526 {
return this->_M_get(); }
1528 template<
typename _Iter>
1530 _M_emplace_deref(
const _Iter& __i)
1533 auto __f = [] (
auto& __x) {
return *__x; };
1534 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1535 return this->_M_get();
1539 template<range _Range>
1540 struct _CachedPosition
1543 _M_has_value()
const
1546 constexpr iterator_t<_Range>
1547 _M_get(
const _Range&)
const
1549 __glibcxx_assert(
false);
1550 __builtin_unreachable();
1554 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1558 template<forward_range _Range>
1559 struct _CachedPosition<_Range>
1560 :
protected __non_propagating_cache<iterator_t<_Range>>
1563 _M_has_value()
const
1564 {
return this->_M_is_engaged(); }
1566 constexpr iterator_t<_Range>
1567 _M_get(
const _Range&)
const
1569 __glibcxx_assert(_M_has_value());
1574 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1576 __glibcxx_assert(!_M_has_value());
1579 this->_M_payload._M_engaged =
true;
1583 template<random_access_range _Range>
1584 requires (
sizeof(range_difference_t<_Range>)
1585 <=
sizeof(iterator_t<_Range>))
1586 struct _CachedPosition<_Range>
1589 range_difference_t<_Range> _M_offset = -1;
1592 _CachedPosition() =
default;
1595 _CachedPosition(
const _CachedPosition&) =
default;
1598 _CachedPosition(_CachedPosition&& __other)
noexcept
1601 constexpr _CachedPosition&
1602 operator=(
const _CachedPosition&) =
default;
1604 constexpr _CachedPosition&
1605 operator=(_CachedPosition&& __other)
noexcept
1608 _M_offset = __other._M_offset;
1609 __other._M_offset = -1;
1614 _M_has_value()
const
1615 {
return _M_offset >= 0; }
1617 constexpr iterator_t<_Range>
1618 _M_get(_Range& __r)
const
1620 __glibcxx_assert(_M_has_value());
1621 return ranges::begin(__r) + _M_offset;
1625 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1627 __glibcxx_assert(!_M_has_value());
1628 _M_offset = __it - ranges::begin(__r);
1635 template<
typename _Base>
1636 struct __filter_view_iter_cat
1639 template<forward_range _Base>
1640 struct __filter_view_iter_cat<_Base>
1646 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1647 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1648 return bidirectional_iterator_tag{};
1649 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1650 return forward_iterator_tag{};
1655 using iterator_category =
decltype(_S_iter_cat());
1659 template<input_range _Vp,
1660 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1661 requires view<_Vp> && is_object_v<_Pred>
1662 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1667 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1670 static constexpr auto
1673 if constexpr (bidirectional_range<_Vp>)
1674 return bidirectional_iterator_tag{};
1675 else if constexpr (forward_range<_Vp>)
1676 return forward_iterator_tag{};
1678 return input_iterator_tag{};
1683 using _Vp_iter = iterator_t<_Vp>;
1685 _Vp_iter _M_current = _Vp_iter();
1686 filter_view* _M_parent =
nullptr;
1689 using iterator_concept =
decltype(_S_iter_concept());
1691 using value_type = range_value_t<_Vp>;
1692 using difference_type = range_difference_t<_Vp>;
1694 _Iterator()
requires default_initializable<_Vp_iter> = default;
1697 _Iterator(filter_view* __parent, _Vp_iter __current)
1698 : _M_current(
std::move(__current)),
1702 constexpr const _Vp_iter&
1703 base() const & noexcept
1704 {
return _M_current; }
1710 constexpr range_reference_t<_Vp>
1712 {
return *_M_current; }
1716 requires __detail::__has_arrow<_Vp_iter>
1717 && copyable<_Vp_iter>
1718 {
return _M_current; }
1720 constexpr _Iterator&
1723 _M_current = ranges::find_if(
std::move(++_M_current),
1724 ranges::end(_M_parent->_M_base),
1725 std::ref(*_M_parent->_M_pred));
1734 operator++(
int)
requires forward_range<_Vp>
1741 constexpr _Iterator&
1742 operator--()
requires bidirectional_range<_Vp>
1751 operator--(
int)
requires bidirectional_range<_Vp>
1758 friend constexpr bool
1759 operator==(
const _Iterator& __x,
const _Iterator& __y)
1760 requires equality_comparable<_Vp_iter>
1761 {
return __x._M_current == __y._M_current; }
1763 friend constexpr range_rvalue_reference_t<_Vp>
1764 iter_move(
const _Iterator& __i)
1765 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1766 {
return ranges::iter_move(__i._M_current); }
1768 friend constexpr void
1769 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1770 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1771 requires indirectly_swappable<_Vp_iter>
1772 { ranges::iter_swap(__x._M_current, __y._M_current); }
1778 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1781 __equal(
const _Iterator& __i)
const
1782 {
return __i._M_current == _M_end; }
1785 _Sentinel() =
default;
1788 _Sentinel(filter_view* __parent)
1789 : _M_end(ranges::
end(__parent->_M_base))
1792 constexpr sentinel_t<_Vp>
1796 friend constexpr bool
1797 operator==(
const _Iterator& __x,
const _Sentinel& __y)
1798 {
return __y.__equal(__x); }
1801 _Vp _M_base = _Vp();
1802 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1803 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1806 filter_view()
requires (default_initializable<_Vp>
1807 && default_initializable<_Pred>)
1811 filter_view(_Vp __base, _Pred __pred)
1816 base() const& requires copy_constructible<_Vp>
1823 constexpr const _Pred&
1825 {
return *_M_pred; }
1830 if (_M_cached_begin._M_has_value())
1831 return {
this, _M_cached_begin._M_get(_M_base)};
1833 __glibcxx_assert(_M_pred.has_value());
1834 auto __it = ranges::find_if(ranges::begin(_M_base),
1835 ranges::end(_M_base),
1836 std::ref(*_M_pred));
1837 _M_cached_begin._M_set(_M_base, __it);
1844 if constexpr (common_range<_Vp>)
1845 return _Iterator{
this, ranges::end(_M_base)};
1847 return _Sentinel{
this};
1851 template<
typename _Range,
typename _Pred>
1852 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1858 template<
typename _Range,
typename _Pred>
1859 concept __can_filter_view
1860 =
requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1863 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1865 template<viewable_range _Range,
typename _Pred>
1866 requires __detail::__can_filter_view<_Range, _Pred>
1868 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1870 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1873 using _RangeAdaptor<_Filter>::operator();
1874 static constexpr int _S_arity = 2;
1875 static constexpr bool _S_has_simple_extra_args =
true;
1878 inline constexpr _Filter filter;
1881#if __cpp_lib_ranges >= 202207L
1882 template<input_range _Vp, move_constructible _Fp>
1884 template<input_range _Vp, copy_constructible _Fp>
1886 requires view<_Vp> && is_object_v<_Fp>
1887 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1888 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1889 range_reference_t<_Vp>>>
1890 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
1893 template<
bool _Const>
1894 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1896 template<
bool _Const>
1900 template<
bool _Const>
1901 requires forward_range<_Base<_Const>>
1902 struct __iter_cat<_Const>
1911 using _Base = transform_view::_Base<_Const>;
1912 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1913 range_reference_t<_Base>>;
1916 if constexpr (is_reference_v<_Res>)
1919 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1920 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1921 return random_access_iterator_tag{};
1926 return input_iterator_tag{};
1929 using iterator_category =
decltype(_S_iter_cat());
1932 template<
bool _Const>
1935 template<
bool _Const>
1936 struct _Iterator : __iter_cat<_Const>
1939 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1940 using _Base = transform_view::_Base<_Const>;
1945 if constexpr (random_access_range<_Base>)
1946 return random_access_iterator_tag{};
1947 else if constexpr (bidirectional_range<_Base>)
1948 return bidirectional_iterator_tag{};
1949 else if constexpr (forward_range<_Base>)
1950 return forward_iterator_tag{};
1952 return input_iterator_tag{};
1955 using _Base_iter = iterator_t<_Base>;
1957 _Base_iter _M_current = _Base_iter();
1958 _Parent* _M_parent =
nullptr;
1961 using iterator_concept =
decltype(_S_iter_concept());
1964 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1965 range_reference_t<_Base>>>;
1966 using difference_type = range_difference_t<_Base>;
1968 _Iterator()
requires default_initializable<_Base_iter> = default;
1971 _Iterator(_Parent* __parent, _Base_iter __current)
1972 : _M_current(
std::move(__current)),
1977 _Iterator(_Iterator<!_Const> __i)
1979 && convertible_to<iterator_t<_Vp>, _Base_iter>
1980 : _M_current(
std::move(__i._M_current)), _M_parent(__i._M_parent)
1983 constexpr const _Base_iter&
1984 base() const & noexcept
1985 {
return _M_current; }
1987 constexpr _Base_iter
1991 constexpr decltype(
auto)
1993 noexcept(
noexcept(
std::__invoke(*_M_parent->_M_fun, *_M_current)))
1996 constexpr _Iterator&
2008 operator++(
int)
requires forward_range<_Base>
2015 constexpr _Iterator&
2016 operator--()
requires bidirectional_range<_Base>
2023 operator--(
int)
requires bidirectional_range<_Base>
2030 constexpr _Iterator&
2031 operator+=(difference_type __n)
requires random_access_range<_Base>
2037 constexpr _Iterator&
2038 operator-=(difference_type __n)
requires random_access_range<_Base>
2044 constexpr decltype(
auto)
2045 operator[](difference_type __n)
const
2046 requires random_access_range<_Base>
2047 {
return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2049 friend constexpr bool
2050 operator==(
const _Iterator& __x,
const _Iterator& __y)
2051 requires equality_comparable<_Base_iter>
2052 {
return __x._M_current == __y._M_current; }
2054 friend constexpr bool
2055 operator<(
const _Iterator& __x,
const _Iterator& __y)
2056 requires random_access_range<_Base>
2057 {
return __x._M_current < __y._M_current; }
2059 friend constexpr bool
2060 operator>(
const _Iterator& __x,
const _Iterator& __y)
2061 requires random_access_range<_Base>
2062 {
return __y < __x; }
2064 friend constexpr bool
2065 operator<=(
const _Iterator& __x,
const _Iterator& __y)
2066 requires random_access_range<_Base>
2067 {
return !(__y < __x); }
2069 friend constexpr bool
2070 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2071 requires random_access_range<_Base>
2072 {
return !(__x < __y); }
2074#ifdef __cpp_lib_three_way_comparison
2075 friend constexpr auto
2076 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2077 requires random_access_range<_Base>
2078 && three_way_comparable<_Base_iter>
2079 {
return __x._M_current <=> __y._M_current; }
2082 friend constexpr _Iterator
2083 operator+(_Iterator __i, difference_type __n)
2084 requires random_access_range<_Base>
2085 {
return {__i._M_parent, __i._M_current + __n}; }
2087 friend constexpr _Iterator
2088 operator+(difference_type __n, _Iterator __i)
2089 requires random_access_range<_Base>
2090 {
return {__i._M_parent, __i._M_current + __n}; }
2092 friend constexpr _Iterator
2093 operator-(_Iterator __i, difference_type __n)
2094 requires random_access_range<_Base>
2095 {
return {__i._M_parent, __i._M_current - __n}; }
2099 friend constexpr difference_type
2100 operator-(
const _Iterator& __x,
const _Iterator& __y)
2101 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2102 {
return __x._M_current - __y._M_current; }
2104 friend constexpr decltype(
auto)
2105 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2107 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2113 friend _Iterator<!_Const>;
2114 template<
bool>
friend struct _Sentinel;
2117 template<
bool _Const>
2121 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2122 using _Base = transform_view::_Base<_Const>;
2124 template<
bool _Const2>
2126 __distance_from(
const _Iterator<_Const2>& __i)
const
2127 {
return _M_end - __i._M_current; }
2129 template<
bool _Const2>
2131 __equal(
const _Iterator<_Const2>& __i)
const
2132 {
return __i._M_current == _M_end; }
2134 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2137 _Sentinel() =
default;
2140 _Sentinel(sentinel_t<_Base> __end)
2145 _Sentinel(_Sentinel<!_Const> __i)
2147 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2151 constexpr sentinel_t<_Base>
2155 template<
bool _Const2>
2156 requires sentinel_for<sentinel_t<_Base>,
2157 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2158 friend constexpr bool
2159 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2160 {
return __y.__equal(__x); }
2162 template<
bool _Const2,
2163 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2164 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2165 friend constexpr range_difference_t<_Base2>
2166 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2167 {
return -__y.__distance_from(__x); }
2169 template<
bool _Const2,
2170 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2171 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2172 friend constexpr range_difference_t<_Base2>
2173 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2174 {
return __y.__distance_from(__x); }
2176 friend _Sentinel<!_Const>;
2179 _Vp _M_base = _Vp();
2180 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2183 transform_view()
requires (default_initializable<_Vp>
2184 && default_initializable<_Fp>)
2188 transform_view(_Vp __base, _Fp __fun)
2193 base() const& requires copy_constructible<_Vp>
2194 {
return _M_base ; }
2200 constexpr _Iterator<false>
2202 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2204 constexpr _Iterator<true>
2206 requires range<const _Vp>
2207 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2208 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2210 constexpr _Sentinel<false>
2212 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2214 constexpr _Iterator<false>
2215 end()
requires common_range<_Vp>
2216 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2218 constexpr _Sentinel<true>
2220 requires range<const _Vp>
2221 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2222 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2224 constexpr _Iterator<true>
2226 requires common_range<const _Vp>
2227 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2228 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2231 size()
requires sized_range<_Vp>
2232 {
return ranges::size(_M_base); }
2235 size() const requires sized_range<const _Vp>
2236 {
return ranges::size(_M_base); }
2239 template<
typename _Range,
typename _Fp>
2240 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2246 template<
typename _Range,
typename _Fp>
2247 concept __can_transform_view
2248 =
requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2251 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2253 template<viewable_range _Range,
typename _Fp>
2254 requires __detail::__can_transform_view<_Range, _Fp>
2256 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2258 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2261 using _RangeAdaptor<_Transform>::operator();
2262 static constexpr int _S_arity = 2;
2263 static constexpr bool _S_has_simple_extra_args =
true;
2266 inline constexpr _Transform transform;
2270 class take_view :
public view_interface<take_view<_Vp>>
2273 template<
bool _Const>
2274 using _CI = counted_iterator<
2275 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2277 template<
bool _Const>
2281 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2282 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2285 _Sentinel() =
default;
2288 _Sentinel(sentinel_t<_Base> __end)
2293 _Sentinel(_Sentinel<!_Const> __s)
2294 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2298 constexpr sentinel_t<_Base>
2302 friend constexpr bool
2303 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2304 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2306 template<
bool _OtherConst = !_Const,
2307 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2308 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2309 friend constexpr bool
2310 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2311 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2313 friend _Sentinel<!_Const>;
2316 _Vp _M_base = _Vp();
2317 range_difference_t<_Vp> _M_count = 0;
2320 take_view()
requires default_initializable<_Vp> = default;
2323 take_view(_Vp __base, range_difference_t<_Vp> __count)
2324 : _M_base(
std::move(__base)), _M_count(
std::move(__count))
2328 base() const& requires copy_constructible<_Vp>
2336 begin()
requires (!__detail::__simple_view<_Vp>)
2338 if constexpr (sized_range<_Vp>)
2340 if constexpr (random_access_range<_Vp>)
2341 return ranges::begin(_M_base);
2345 return counted_iterator(ranges::begin(_M_base), __sz);
2349 return counted_iterator(ranges::begin(_M_base), _M_count);
2353 begin() const requires range<const _Vp>
2355 if constexpr (sized_range<const _Vp>)
2357 if constexpr (random_access_range<const _Vp>)
2358 return ranges::begin(_M_base);
2362 return counted_iterator(ranges::begin(_M_base), __sz);
2366 return counted_iterator(ranges::begin(_M_base), _M_count);
2370 end()
requires (!__detail::__simple_view<_Vp>)
2372 if constexpr (sized_range<_Vp>)
2374 if constexpr (random_access_range<_Vp>)
2375 return ranges::begin(_M_base) +
size();
2380 return _Sentinel<false>{ranges::end(_M_base)};
2384 end() const requires range<const _Vp>
2386 if constexpr (sized_range<const _Vp>)
2388 if constexpr (random_access_range<const _Vp>)
2389 return ranges::begin(_M_base) +
size();
2394 return _Sentinel<true>{ranges::end(_M_base)};
2398 size()
requires sized_range<_Vp>
2400 auto __n = ranges::size(_M_base);
2401 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2405 size() const requires sized_range<const _Vp>
2407 auto __n = ranges::size(_M_base);
2408 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2415 template<
typename _Range>
2416 take_view(_Range&&, range_difference_t<_Range>)
2417 -> take_view<views::all_t<_Range>>;
2419 template<
typename _Tp>
2420 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2421 = enable_borrowed_range<_Tp>;
2427 template<
typename _Range>
2428 inline constexpr bool __is_empty_view =
false;
2430 template<
typename _Tp>
2431 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2433 template<
typename _Range>
2434 inline constexpr bool __is_basic_string_view =
false;
2436 template<
typename _CharT,
typename _Traits>
2437 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2440 using ranges::__detail::__is_subrange;
2442 template<
typename _Range>
2443 inline constexpr bool __is_iota_view =
false;
2445 template<
typename _Winc,
typename _Bound>
2446 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2448 template<
typename _Range>
2449 inline constexpr bool __is_repeat_view =
false;
2451 template<
typename _Range>
2453 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2455 template<
typename _Range,
typename _Dp>
2456 concept __can_take_view
2457 =
requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2460 struct _Take : __adaptor::_RangeAdaptor<_Take>
2462 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2463 requires __detail::__can_take_view<_Range, _Dp>
2465 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2467 using _Tp = remove_cvref_t<_Range>;
2468 if constexpr (__detail::__is_empty_view<_Tp>)
2470 else if constexpr (random_access_range<_Tp>
2472 && (std::__detail::__is_span<_Tp>
2473 || __detail::__is_basic_string_view<_Tp>
2474 || __detail::__is_subrange<_Tp>
2475 || __detail::__is_iota_view<_Tp>))
2477 __n = std::min<_Dp>(ranges::distance(__r), __n);
2478 auto __begin = ranges::begin(__r);
2479 auto __end = __begin + __n;
2480 if constexpr (std::__detail::__is_span<_Tp>)
2481 return span<typename _Tp::element_type>(__begin, __end);
2482 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2483 return _Tp(__begin, __end);
2484 else if constexpr (__detail::__is_subrange<_Tp>)
2485 return subrange<iterator_t<_Tp>>(__begin, __end);
2487 return iota_view(*__begin, *__end);
2489 else if constexpr (__detail::__is_repeat_view<_Tp>)
2490 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2492 return take_view(std::forward<_Range>(__r), __n);
2495 using _RangeAdaptor<_Take>::operator();
2496 static constexpr int _S_arity = 2;
2500 template<
typename _Tp>
2501 static constexpr bool _S_has_simple_extra_args
2502 = ranges::__detail::__is_integer_like<_Tp>;
2505 inline constexpr _Take take;
2508 template<view _Vp,
typename _Pred>
2509 requires input_range<_Vp> && is_object_v<_Pred>
2510 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2511 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2513 template<
bool _Const>
2517 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2519 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2520 const _Pred* _M_pred =
nullptr;
2523 _Sentinel() =
default;
2526 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2527 : _M_end(__end), _M_pred(__pred)
2531 _Sentinel(_Sentinel<!_Const> __s)
2532 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2533 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2536 constexpr sentinel_t<_Base>
2537 base()
const {
return _M_end; }
2539 friend constexpr bool
2540 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2541 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2543 template<
bool _OtherConst = !_Const,
2544 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2545 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2546 friend constexpr bool
2547 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2548 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2550 friend _Sentinel<!_Const>;
2553 _Vp _M_base = _Vp();
2554 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2557 take_while_view()
requires (default_initializable<_Vp>
2558 && default_initializable<_Pred>)
2562 take_while_view(_Vp __base, _Pred __pred)
2567 base() const& requires copy_constructible<_Vp>
2574 constexpr const _Pred&
2576 {
return *_M_pred; }
2579 begin()
requires (!__detail::__simple_view<_Vp>)
2580 {
return ranges::begin(_M_base); }
2583 begin() const requires range<const _Vp>
2584 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2585 {
return ranges::begin(_M_base); }
2588 end()
requires (!__detail::__simple_view<_Vp>)
2589 {
return _Sentinel<false>(ranges::end(_M_base),
2593 end() const requires range<const _Vp>
2594 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2595 {
return _Sentinel<true>(ranges::end(_M_base),
2599 template<
typename _Range,
typename _Pred>
2600 take_while_view(_Range&&, _Pred)
2601 -> take_while_view<views::all_t<_Range>, _Pred>;
2607 template<
typename _Range,
typename _Pred>
2608 concept __can_take_while_view
2609 =
requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2612 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2614 template<viewable_range _Range,
typename _Pred>
2615 requires __detail::__can_take_while_view<_Range, _Pred>
2617 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2619 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2622 using _RangeAdaptor<_TakeWhile>::operator();
2623 static constexpr int _S_arity = 2;
2624 static constexpr bool _S_has_simple_extra_args =
true;
2627 inline constexpr _TakeWhile take_while;
2631 class drop_view :
public view_interface<drop_view<_Vp>>
2634 _Vp _M_base = _Vp();
2635 range_difference_t<_Vp> _M_count = 0;
2639 static constexpr bool _S_needs_cached_begin
2640 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2641 [[no_unique_address]]
2642 __detail::__maybe_present_t<_S_needs_cached_begin,
2643 __detail::_CachedPosition<_Vp>>
2647 drop_view()
requires default_initializable<_Vp> = default;
2650 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2651 : _M_base(
std::move(__base)), _M_count(__count)
2652 { __glibcxx_assert(__count >= 0); }
2655 base() const& requires copy_constructible<_Vp>
2665 requires (!(__detail::__simple_view<_Vp>
2666 && random_access_range<const _Vp>
2667 && sized_range<const _Vp>))
2669 if constexpr (_S_needs_cached_begin)
2670 if (_M_cached_begin._M_has_value())
2671 return _M_cached_begin._M_get(_M_base);
2673 auto __it = ranges::next(ranges::begin(_M_base),
2674 _M_count, ranges::end(_M_base));
2675 if constexpr (_S_needs_cached_begin)
2676 _M_cached_begin._M_set(_M_base, __it);
2684 requires random_access_range<const _Vp> && sized_range<const _Vp>
2686 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2691 end()
requires (!__detail::__simple_view<_Vp>)
2692 {
return ranges::end(_M_base); }
2695 end() const requires range<const _Vp>
2696 {
return ranges::end(_M_base); }
2699 size()
requires sized_range<_Vp>
2701 const auto __s = ranges::size(_M_base);
2702 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2703 return __s < __c ? 0 : __s - __c;
2707 size() const requires sized_range<const _Vp>
2709 const auto __s = ranges::size(_M_base);
2710 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2711 return __s < __c ? 0 : __s - __c;
2715 template<
typename _Range>
2716 drop_view(_Range&&, range_difference_t<_Range>)
2717 -> drop_view<views::all_t<_Range>>;
2719 template<
typename _Tp>
2720 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2721 = enable_borrowed_range<_Tp>;
2727 template<
typename _Range>
2729 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2731 template<
typename _Range,
typename _Dp>
2732 concept __can_drop_view
2733 =
requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2736 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2738 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2739 requires __detail::__can_drop_view<_Range, _Dp>
2741 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2743 using _Tp = remove_cvref_t<_Range>;
2744 if constexpr (__detail::__is_empty_view<_Tp>)
2746 else if constexpr (random_access_range<_Tp>
2748 && (std::__detail::__is_span<_Tp>
2749 || __detail::__is_basic_string_view<_Tp>
2750 || __detail::__is_iota_view<_Tp>
2751 || __detail::__is_subrange<_Tp>))
2753 __n = std::min<_Dp>(ranges::distance(__r), __n);
2754 auto __begin = ranges::begin(__r) + __n;
2755 auto __end = ranges::end(__r);
2756 if constexpr (std::__detail::__is_span<_Tp>)
2757 return span<typename _Tp::element_type>(__begin, __end);
2758 else if constexpr (__detail::__is_subrange<_Tp>)
2760 if constexpr (_Tp::_S_store_size)
2762 using ranges::__detail::__to_unsigned_like;
2763 auto __m = ranges::distance(__r) - __n;
2764 return _Tp(__begin, __end, __to_unsigned_like(__m));
2767 return _Tp(__begin, __end);
2770 return _Tp(__begin, __end);
2772 else if constexpr (__detail::__is_repeat_view<_Tp>)
2773 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2775 return drop_view(std::forward<_Range>(__r), __n);
2778 using _RangeAdaptor<_Drop>::operator();
2779 static constexpr int _S_arity = 2;
2780 template<
typename _Tp>
2781 static constexpr bool _S_has_simple_extra_args
2782 = _Take::_S_has_simple_extra_args<_Tp>;
2785 inline constexpr _Drop drop;
2788 template<view _Vp,
typename _Pred>
2789 requires input_range<_Vp> && is_object_v<_Pred>
2790 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2791 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2794 _Vp _M_base = _Vp();
2795 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2796 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2799 drop_while_view()
requires (default_initializable<_Vp>
2800 && default_initializable<_Pred>)
2804 drop_while_view(_Vp __base, _Pred __pred)
2809 base() const& requires copy_constructible<_Vp>
2816 constexpr const _Pred&
2818 {
return *_M_pred; }
2823 if (_M_cached_begin._M_has_value())
2824 return _M_cached_begin._M_get(_M_base);
2826 __glibcxx_assert(_M_pred.has_value());
2827 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2828 ranges::end(_M_base),
2829 std::cref(*_M_pred));
2830 _M_cached_begin._M_set(_M_base, __it);
2836 {
return ranges::end(_M_base); }
2839 template<
typename _Range,
typename _Pred>
2840 drop_while_view(_Range&&, _Pred)
2841 -> drop_while_view<views::all_t<_Range>, _Pred>;
2843 template<
typename _Tp,
typename _Pred>
2844 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2845 = enable_borrowed_range<_Tp>;
2851 template<
typename _Range,
typename _Pred>
2852 concept __can_drop_while_view
2853 =
requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2856 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2858 template<viewable_range _Range,
typename _Pred>
2859 requires __detail::__can_drop_while_view<_Range, _Pred>
2861 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2863 return drop_while_view(std::forward<_Range>(__r),
2864 std::forward<_Pred>(__p));
2867 using _RangeAdaptor<_DropWhile>::operator();
2868 static constexpr int _S_arity = 2;
2869 static constexpr bool _S_has_simple_extra_args =
true;
2872 inline constexpr _DropWhile drop_while;
2877 template<
typename _Tp>
2879 __as_lvalue(_Tp&& __t)
2880 {
return static_cast<_Tp&
>(__t); }
2883 template<input_range _Vp>
2884 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2885 class join_view :
public view_interface<join_view<_Vp>>
2888 using _InnerRange = range_reference_t<_Vp>;
2890 template<
bool _Const>
2891 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2893 template<
bool _Const>
2894 using _Outer_iter = iterator_t<_Base<_Const>>;
2896 template<
bool _Const>
2897 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2899 template<
bool _Const>
2900 static constexpr bool _S_ref_is_glvalue
2901 = is_reference_v<range_reference_t<_Base<_Const>>>;
2903 template<
bool _Const>
2907 template<
bool _Const>
2908 requires _S_ref_is_glvalue<_Const>
2909 && forward_range<_Base<_Const>>
2910 && forward_range<range_reference_t<_Base<_Const>>>
2911 struct __iter_cat<_Const>
2914 static constexpr auto
2917 using _Outer_iter = join_view::_Outer_iter<_Const>;
2918 using _Inner_iter = join_view::_Inner_iter<_Const>;
2919 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
2920 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
2921 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2922 && derived_from<_InnerCat, bidirectional_iterator_tag>
2923 && common_range<range_reference_t<_Base<_Const>>>)
2924 return bidirectional_iterator_tag{};
2925 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2926 && derived_from<_InnerCat, forward_iterator_tag>)
2927 return forward_iterator_tag{};
2929 return input_iterator_tag{};
2932 using iterator_category =
decltype(_S_iter_cat());
2935 template<
bool _Const>
2938 template<
bool _Const>
2939 struct _Iterator : __iter_cat<_Const>
2942 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2943 using _Base = join_view::_Base<_Const>;
2947 static constexpr bool _S_ref_is_glvalue
2948 = join_view::_S_ref_is_glvalue<_Const>;
2953 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
2954 if constexpr (_S_ref_is_glvalue)
2957 return _M_parent->_M_inner._M_emplace_deref(__x);
2960 _Outer_iter& __outer = _M_get_outer();
2961 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2963 auto&& __inner = __update_inner(__outer);
2964 _M_inner = ranges::begin(__inner);
2965 if (_M_inner != ranges::end(__inner))
2969 if constexpr (_S_ref_is_glvalue)
2973 static constexpr auto
2976 if constexpr (_S_ref_is_glvalue
2977 && bidirectional_range<_Base>
2978 && bidirectional_range<range_reference_t<_Base>>
2979 && common_range<range_reference_t<_Base>>)
2980 return bidirectional_iterator_tag{};
2981 else if constexpr (_S_ref_is_glvalue
2982 && forward_range<_Base>
2983 && forward_range<range_reference_t<_Base>>)
2984 return forward_iterator_tag{};
2986 return input_iterator_tag{};
2989 using _Outer_iter = join_view::_Outer_iter<_Const>;
2990 using _Inner_iter = join_view::_Inner_iter<_Const>;
2992 constexpr _Outer_iter&
2995 if constexpr (forward_range<_Base>)
2998 return *_M_parent->_M_outer;
3001 constexpr const _Outer_iter&
3002 _M_get_outer()
const
3004 if constexpr (forward_range<_Base>)
3007 return *_M_parent->_M_outer;
3011 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
3012 : _M_outer(
std::move(__outer)), _M_parent(__parent)
3016 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
3017 : _M_parent(__parent)
3020 [[no_unique_address]]
3021 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
3022 optional<_Inner_iter> _M_inner;
3023 _Parent* _M_parent =
nullptr;
3026 using iterator_concept =
decltype(_S_iter_concept());
3028 using value_type = range_value_t<range_reference_t<_Base>>;
3029 using difference_type
3030 = common_type_t<range_difference_t<_Base>,
3031 range_difference_t<range_reference_t<_Base>>>;
3033 _Iterator() =
default;
3036 _Iterator(_Iterator<!_Const> __i)
3038 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3039 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3041 _M_parent(__i._M_parent)
3044 constexpr decltype(
auto)
3046 {
return **_M_inner; }
3050 constexpr _Inner_iter
3052 requires __detail::__has_arrow<_Inner_iter>
3053 && copyable<_Inner_iter>
3054 {
return *_M_inner; }
3056 constexpr _Iterator&
3059 auto&& __inner_range = [
this] () ->
auto&& {
3060 if constexpr (_S_ref_is_glvalue)
3061 return *_M_get_outer();
3063 return *_M_parent->_M_inner;
3065 if (++*_M_inner == ranges::end(__inner_range))
3079 requires _S_ref_is_glvalue && forward_range<_Base>
3080 && forward_range<range_reference_t<_Base>>
3087 constexpr _Iterator&
3089 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3090 && bidirectional_range<range_reference_t<_Base>>
3091 && common_range<range_reference_t<_Base>>
3093 if (_M_outer == ranges::end(_M_parent->_M_base))
3094 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3095 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3096 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3103 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3104 && bidirectional_range<range_reference_t<_Base>>
3105 && common_range<range_reference_t<_Base>>
3112 friend constexpr bool
3113 operator==(
const _Iterator& __x,
const _Iterator& __y)
3114 requires _S_ref_is_glvalue
3115 && forward_range<_Base>
3116 && equality_comparable<_Inner_iter>
3118 return (__x._M_outer == __y._M_outer
3119 && __x._M_inner == __y._M_inner);
3122 friend constexpr decltype(
auto)
3123 iter_move(
const _Iterator& __i)
3124 noexcept(
noexcept(ranges::iter_move(*__i._M_inner)))
3125 {
return ranges::iter_move(*__i._M_inner); }
3127 friend constexpr void
3128 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3129 noexcept(
noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3130 requires indirectly_swappable<_Inner_iter>
3131 {
return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3133 friend _Iterator<!_Const>;
3134 template<
bool>
friend struct _Sentinel;
3137 template<
bool _Const>
3141 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3142 using _Base = join_view::_Base<_Const>;
3144 template<
bool _Const2>
3146 __equal(
const _Iterator<_Const2>& __i)
const
3147 {
return __i._M_get_outer() == _M_end; }
3149 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3152 _Sentinel() =
default;
3155 _Sentinel(_Parent* __parent)
3156 : _M_end(ranges::
end(__parent->_M_base))
3160 _Sentinel(_Sentinel<!_Const> __s)
3161 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3165 template<
bool _Const2>
3166 requires sentinel_for<sentinel_t<_Base>,
3167 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3168 friend constexpr bool
3169 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3170 {
return __y.__equal(__x); }
3172 friend _Sentinel<!_Const>;
3175 _Vp _M_base = _Vp();
3176 [[no_unique_address]]
3177 __detail::__maybe_present_t<!forward_range<_Vp>,
3178 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3179 [[no_unique_address]]
3180 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3183 join_view()
requires default_initializable<_Vp> = default;
3186 join_view(_Vp __base)
3187 : _M_base(
std::move(__base))
3191 base() const& requires copy_constructible<_Vp>
3201 if constexpr (forward_range<_Vp>)
3203 constexpr bool __use_const
3204 = (__detail::__simple_view<_Vp>
3205 && is_reference_v<range_reference_t<_Vp>>);
3206 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3210 _M_outer = ranges::begin(_M_base);
3211 return _Iterator<false>{
this};
3217 requires forward_range<const _Vp>
3218 && is_reference_v<range_reference_t<const _Vp>>
3219 && input_range<range_reference_t<const _Vp>>
3221 return _Iterator<true>{
this, ranges::begin(_M_base)};
3227 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3228 && forward_range<_InnerRange>
3229 && common_range<_Vp> && common_range<_InnerRange>)
3230 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3231 ranges::end(_M_base)};
3233 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3238 requires forward_range<const _Vp>
3239 && is_reference_v<range_reference_t<const _Vp>>
3240 && input_range<range_reference_t<const _Vp>>
3242 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3243 && forward_range<range_reference_t<const _Vp>>
3244 && common_range<const _Vp>
3245 && common_range<range_reference_t<const _Vp>>)
3246 return _Iterator<true>{
this, ranges::end(_M_base)};
3248 return _Sentinel<true>{
this};
3252 template<
typename _Range>
3253 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3259 template<
typename _Range>
3260 concept __can_join_view
3261 =
requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3264 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3266 template<viewable_range _Range>
3267 requires __detail::__can_join_view<_Range>
3269 operator() [[nodiscard]] (_Range&& __r)
const
3273 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3276 static constexpr bool _S_has_simple_call_op =
true;
3279 inline constexpr _Join join;
3285 struct __require_constant;
3287 template<
typename _Range>
3288 concept __tiny_range = sized_range<_Range>
3290 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3291 && (remove_reference_t<_Range>::size() <= 1);
3293 template<
typename _Base>
3294 struct __lazy_split_view_outer_iter_cat
3297 template<forward_range _Base>
3298 struct __lazy_split_view_outer_iter_cat<_Base>
3299 {
using iterator_category = input_iterator_tag; };
3301 template<
typename _Base>
3302 struct __lazy_split_view_inner_iter_cat
3305 template<forward_range _Base>
3306 struct __lazy_split_view_inner_iter_cat<_Base>
3309 static constexpr auto
3312 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3313 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3314 return forward_iterator_tag{};
3319 using iterator_category =
decltype(_S_iter_cat());
3323 template<input_range _Vp, forward_range _Pattern>
3324 requires view<_Vp> && view<_Pattern>
3325 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3327 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3328 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3331 template<
bool _Const>
3332 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3334 template<
bool _Const>
3337 template<
bool _Const>
3339 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3342 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3343 using _Base = lazy_split_view::_Base<_Const>;
3347 {
return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3354 __current() noexcept
3356 if constexpr (forward_range<_Vp>)
3359 return *_M_parent->_M_current;
3363 __current() const noexcept
3365 if constexpr (forward_range<_Vp>)
3368 return *_M_parent->_M_current;
3371 _Parent* _M_parent =
nullptr;
3373 [[no_unique_address]]
3374 __detail::__maybe_present_t<forward_range<_Vp>,
3375 iterator_t<_Base>> _M_current;
3376 bool _M_trailing_empty =
false;
3379 using iterator_concept = __conditional_t<forward_range<_Base>,
3380 forward_iterator_tag,
3381 input_iterator_tag>;
3383 using difference_type = range_difference_t<_Base>;
3385 struct value_type : view_interface<value_type>
3388 _OuterIter _M_i = _OuterIter();
3394 value_type(_OuterIter __i)
3401 constexpr _InnerIter<_Const>
3403 {
return _InnerIter<_Const>{_M_i}; }
3405 constexpr default_sentinel_t
3406 end() const noexcept
3410 _OuterIter() =
default;
3413 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3414 : _M_parent(__parent)
3418 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3419 requires forward_range<_Base>
3420 : _M_parent(__parent),
3425 _OuterIter(_OuterIter<!_Const> __i)
3427 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3428 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3429 _M_trailing_empty(__i._M_trailing_empty)
3432 constexpr value_type
3434 {
return value_type{*
this}; }
3436 constexpr _OuterIter&
3441 const auto __end = ranges::end(_M_parent->_M_base);
3442 if (__current() == __end)
3444 _M_trailing_empty =
false;
3447 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3448 if (__pbegin == __pend)
3450 else if constexpr (__detail::__tiny_range<_Pattern>)
3452 __current() = ranges::find(
std::move(__current()), __end,
3454 if (__current() != __end)
3457 if (__current() == __end)
3458 _M_trailing_empty =
true;
3465 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3469 if (__current() == __end)
3470 _M_trailing_empty =
true;
3473 }
while (++__current() != __end);
3477 constexpr decltype(
auto)
3480 if constexpr (forward_range<_Base>)
3490 friend constexpr bool
3491 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3492 requires forward_range<_Base>
3494 return __x._M_current == __y._M_current
3495 && __x._M_trailing_empty == __y._M_trailing_empty;
3498 friend constexpr bool
3499 operator==(
const _OuterIter& __x, default_sentinel_t)
3500 {
return __x.__at_end(); };
3502 friend _OuterIter<!_Const>;
3503 friend _InnerIter<_Const>;
3506 template<
bool _Const>
3508 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3511 using _Base = lazy_split_view::_Base<_Const>;
3516 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3517 auto __end = ranges::end(_M_i._M_parent->_M_base);
3518 if constexpr (__detail::__tiny_range<_Pattern>)
3520 const auto& __cur = _M_i_current();
3523 if (__pcur == __pend)
3524 return _M_incremented;
3525 return *__cur == *__pcur;
3529 auto __cur = _M_i_current();
3532 if (__pcur == __pend)
3533 return _M_incremented;
3536 if (*__cur != *__pcur)
3538 if (++__pcur == __pend)
3540 }
while (++__cur != __end);
3546 _M_i_current() noexcept
3547 {
return _M_i.__current(); }
3550 _M_i_current() const noexcept
3551 {
return _M_i.__current(); }
3553 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3554 bool _M_incremented =
false;
3557 using iterator_concept
3558 =
typename _OuterIter<_Const>::iterator_concept;
3560 using value_type = range_value_t<_Base>;
3561 using difference_type = range_difference_t<_Base>;
3563 _InnerIter() =
default;
3566 _InnerIter(_OuterIter<_Const> __i)
3570 constexpr const iterator_t<_Base>&
3571 base() const& noexcept
3572 {
return _M_i_current(); }
3574 constexpr iterator_t<_Base>
3575 base() &&
requires forward_range<_Vp>
3578 constexpr decltype(
auto)
3580 {
return *_M_i_current(); }
3582 constexpr _InnerIter&
3585 _M_incremented =
true;
3586 if constexpr (!forward_range<_Base>)
3587 if constexpr (_Pattern::size() == 0)
3593 constexpr decltype(
auto)
3596 if constexpr (forward_range<_Base>)
3606 friend constexpr bool
3607 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3608 requires forward_range<_Base>
3609 {
return __x._M_i == __y._M_i; }
3611 friend constexpr bool
3612 operator==(
const _InnerIter& __x, default_sentinel_t)
3613 {
return __x.__at_end(); }
3615 friend constexpr decltype(
auto)
3616 iter_move(
const _InnerIter& __i)
3617 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3618 {
return ranges::iter_move(__i._M_i_current()); }
3620 friend constexpr void
3621 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3622 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3623 __y._M_i_current())))
3624 requires indirectly_swappable<iterator_t<_Base>>
3625 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3628 _Vp _M_base = _Vp();
3629 _Pattern _M_pattern = _Pattern();
3630 [[no_unique_address]]
3631 __detail::__maybe_present_t<!forward_range<_Vp>,
3632 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3636 lazy_split_view()
requires (default_initializable<_Vp>
3637 && default_initializable<_Pattern>)
3641 lazy_split_view(_Vp __base, _Pattern __pattern)
3645 template<input_range _Range>
3646 requires constructible_from<_Vp, views::all_t<_Range>>
3647 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3649 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3650 : _M_base(views::all(
std::
forward<_Range>(__r))),
3651 _M_pattern(views::single(
std::
move(__e)))
3655 base() const& requires copy_constructible<_Vp>
3665 if constexpr (forward_range<_Vp>)
3667 constexpr bool __simple
3668 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3669 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3673 _M_current = ranges::begin(_M_base);
3674 return _OuterIter<false>{
this};
3679 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3681 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3685 end()
requires forward_range<_Vp> && common_range<_Vp>
3687 constexpr bool __simple
3688 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3689 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3695 if constexpr (forward_range<_Vp>
3696 && forward_range<const _Vp>
3697 && common_range<const _Vp>)
3698 return _OuterIter<true>{
this, ranges::end(_M_base)};
3704 template<
typename _Range,
typename _Pattern>
3705 lazy_split_view(_Range&&, _Pattern&&)
3706 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3708 template<input_range _Range>
3709 lazy_split_view(_Range&&, range_value_t<_Range>)
3710 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3716 template<
typename _Range,
typename _Pattern>
3717 concept __can_lazy_split_view
3718 =
requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3721 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3723 template<viewable_range _Range,
typename _Pattern>
3724 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3726 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3728 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3731 using _RangeAdaptor<_LazySplit>::operator();
3732 static constexpr int _S_arity = 2;
3737 template<
typename _Pattern>
3738 static constexpr bool _S_has_simple_extra_args
3739 = is_scalar_v<_Pattern> || (view<_Pattern>
3740 && copy_constructible<_Pattern>);
3743 inline constexpr _LazySplit lazy_split;
3746 template<forward_range _Vp, forward_range _Pattern>
3747 requires view<_Vp> && view<_Pattern>
3748 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3750 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3753 _Vp _M_base = _Vp();
3754 _Pattern _M_pattern = _Pattern();
3755 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3761 split_view()
requires (default_initializable<_Vp>
3762 && default_initializable<_Pattern>)
3766 split_view(_Vp __base, _Pattern __pattern)
3770 template<forward_range _Range>
3771 requires constructible_from<_Vp, views::all_t<_Range>>
3772 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3774 split_view(_Range&& __r, range_value_t<_Range> __e)
3775 : _M_base(views::all(
std::
forward<_Range>(__r))),
3776 _M_pattern(views::single(
std::
move(__e)))
3780 base() const& requires copy_constructible<_Vp>
3790 if (!_M_cached_begin)
3791 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3792 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3798 if constexpr (common_range<_Vp>)
3799 return _Iterator{
this, ranges::end(_M_base), {}};
3801 return _Sentinel{
this};
3804 constexpr subrange<iterator_t<_Vp>>
3805 _M_find_next(iterator_t<_Vp> __it)
3807 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3808 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3820 split_view* _M_parent =
nullptr;
3821 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3822 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3823 bool _M_trailing_empty =
false;
3825 friend struct _Sentinel;
3828 using iterator_concept = forward_iterator_tag;
3829 using iterator_category = input_iterator_tag;
3830 using value_type = subrange<iterator_t<_Vp>>;
3831 using difference_type = range_difference_t<_Vp>;
3833 _Iterator() =
default;
3836 _Iterator(split_view* __parent,
3837 iterator_t<_Vp> __current,
3838 subrange<iterator_t<_Vp>> __next)
3839 : _M_parent(__parent),
3844 constexpr iterator_t<_Vp>
3848 constexpr value_type
3850 {
return {_M_cur, _M_next.begin()}; }
3852 constexpr _Iterator&
3855 _M_cur = _M_next.begin();
3856 if (_M_cur != ranges::end(_M_parent->_M_base))
3858 _M_cur = _M_next.end();
3859 if (_M_cur == ranges::end(_M_parent->_M_base))
3861 _M_trailing_empty =
true;
3862 _M_next = {_M_cur, _M_cur};
3865 _M_next = _M_parent->_M_find_next(_M_cur);
3868 _M_trailing_empty =
false;
3880 friend constexpr bool
3881 operator==(
const _Iterator& __x,
const _Iterator& __y)
3883 return __x._M_cur == __y._M_cur
3884 && __x._M_trailing_empty == __y._M_trailing_empty;
3891 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3894 _M_equal(
const _Iterator& __x)
const
3895 {
return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3898 _Sentinel() =
default;
3901 _Sentinel(split_view* __parent)
3902 : _M_end(ranges::
end(__parent->_M_base))
3905 friend constexpr bool
3906 operator==(
const _Iterator& __x,
const _Sentinel& __y)
3907 {
return __y._M_equal(__x); }
3911 template<
typename _Range,
typename _Pattern>
3912 split_view(_Range&&, _Pattern&&)
3913 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3915 template<forward_range _Range>
3916 split_view(_Range&&, range_value_t<_Range>)
3917 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3923 template<
typename _Range,
typename _Pattern>
3924 concept __can_split_view
3925 =
requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3928 struct _Split : __adaptor::_RangeAdaptor<_Split>
3930 template<viewable_range _Range,
typename _Pattern>
3931 requires __detail::__can_split_view<_Range, _Pattern>
3933 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3935 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3938 using _RangeAdaptor<_Split>::operator();
3939 static constexpr int _S_arity = 2;
3940 template<
typename _Pattern>
3941 static constexpr bool _S_has_simple_extra_args
3942 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3945 inline constexpr _Split split;
3952 template<input_or_output_iterator _Iter>
3954 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
3956 if constexpr (contiguous_iterator<_Iter>)
3958 else if constexpr (random_access_iterator<_Iter>)
3959 return subrange(__i, __i + __n);
3961 return subrange(counted_iterator(
std::move(__i), __n),
3966 inline constexpr _Counted counted{};
3970 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3971 class common_view : public view_interface<common_view<_Vp>>
3974 _Vp _M_base = _Vp();
3977 common_view()
requires default_initializable<_Vp> = default;
3980 common_view(_Vp __r)
3981 : _M_base(
std::move(__r))
3985 base() const& requires copy_constructible<_Vp>
3995 begin()
requires (!__detail::__simple_view<_Vp>)
3997 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3998 return ranges::begin(_M_base);
4000 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4001 (ranges::begin(_M_base));
4005 begin() const requires range<const _Vp>
4007 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4008 return ranges::begin(_M_base);
4010 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4011 (ranges::begin(_M_base));
4015 end()
requires (!__detail::__simple_view<_Vp>)
4017 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4018 return ranges::begin(_M_base) + ranges::size(_M_base);
4020 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4021 (ranges::end(_M_base));
4025 end() const requires range<const _Vp>
4027 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4028 return ranges::begin(_M_base) + ranges::size(_M_base);
4030 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4031 (ranges::end(_M_base));
4035 size()
requires sized_range<_Vp>
4036 {
return ranges::size(_M_base); }
4039 size() const requires sized_range<const _Vp>
4040 {
return ranges::size(_M_base); }
4043 template<
typename _Range>
4044 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4046 template<
typename _Tp>
4047 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4048 = enable_borrowed_range<_Tp>;
4054 template<
typename _Range>
4055 concept __already_common = common_range<_Range>
4056 &&
requires { views::all(std::declval<_Range>()); };
4058 template<
typename _Range>
4059 concept __can_common_view
4060 =
requires { common_view{std::declval<_Range>()}; };
4063 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4065 template<viewable_range _Range>
4066 requires __detail::__already_common<_Range>
4067 || __detail::__can_common_view<_Range>
4069 operator() [[nodiscard]] (_Range&& __r)
const
4071 if constexpr (__detail::__already_common<_Range>)
4072 return views::all(std::forward<_Range>(__r));
4074 return common_view{std::forward<_Range>(__r)};
4077 static constexpr bool _S_has_simple_call_op =
true;
4080 inline constexpr _Common common;
4084 requires bidirectional_range<_Vp>
4085 class reverse_view :
public view_interface<reverse_view<_Vp>>
4088 static constexpr bool _S_needs_cached_begin
4089 = !common_range<_Vp> && !(random_access_range<_Vp>
4090 && sized_sentinel_for<sentinel_t<_Vp>,
4093 _Vp _M_base = _Vp();
4094 [[no_unique_address]]
4095 __detail::__maybe_present_t<_S_needs_cached_begin,
4096 __detail::_CachedPosition<_Vp>>
4100 reverse_view()
requires default_initializable<_Vp> = default;
4103 reverse_view(_Vp __r)
4104 : _M_base(
std::move(__r))
4108 base() const& requires copy_constructible<_Vp>
4115 constexpr reverse_iterator<iterator_t<_Vp>>
4118 if constexpr (_S_needs_cached_begin)
4119 if (_M_cached_begin._M_has_value())
4122 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4123 if constexpr (_S_needs_cached_begin)
4124 _M_cached_begin._M_set(_M_base, __it);
4129 begin()
requires common_range<_Vp>
4133 begin() const requires common_range<const _Vp>
4136 constexpr reverse_iterator<iterator_t<_Vp>>
4141 end() const requires common_range<const _Vp>
4145 size()
requires sized_range<_Vp>
4146 {
return ranges::size(_M_base); }
4149 size() const requires sized_range<const _Vp>
4150 {
return ranges::size(_M_base); }
4153 template<
typename _Range>
4154 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4156 template<
typename _Tp>
4157 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4158 = enable_borrowed_range<_Tp>;
4165 inline constexpr bool __is_reversible_subrange =
false;
4167 template<
typename _Iter, subrange_kind _Kind>
4168 inline constexpr bool
4169 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4170 reverse_iterator<_Iter>,
4174 inline constexpr bool __is_reverse_view =
false;
4176 template<
typename _Vp>
4177 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4179 template<
typename _Range>
4180 concept __can_reverse_view
4181 =
requires { reverse_view{std::declval<_Range>()}; };
4184 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4186 template<viewable_range _Range>
4187 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4188 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4189 || __detail::__can_reverse_view<_Range>
4191 operator() [[nodiscard]] (_Range&& __r)
const
4193 using _Tp = remove_cvref_t<_Range>;
4194 if constexpr (__detail::__is_reverse_view<_Tp>)
4195 return std::forward<_Range>(__r).base();
4196 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4198 using _Iter =
decltype(ranges::begin(__r).base());
4199 if constexpr (sized_range<_Tp>)
4200 return subrange<_Iter, _Iter, subrange_kind::sized>
4201 {__r.end().base(), __r.begin().base(), __r.size()};
4203 return subrange<_Iter, _Iter, subrange_kind::unsized>
4204 {__r.end().base(), __r.begin().base()};
4207 return reverse_view{std::forward<_Range>(__r)};
4210 static constexpr bool _S_has_simple_call_op =
true;
4213 inline constexpr _Reverse reverse;
4218#if __cpp_lib_tuple_like
4219 template<
typename _Tp,
size_t _Nm>
4220 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4222 template<
typename _Tp,
size_t _Nm>
4223 concept __has_tuple_element =
requires(_Tp __t)
4225 typename tuple_size<_Tp>::type;
4226 requires _Nm < tuple_size_v<_Tp>;
4227 typename tuple_element_t<_Nm, _Tp>;
4228 { std::get<_Nm>(__t) }
4229 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4233 template<
typename _Tp,
size_t _Nm>
4234 concept __returnable_element
4235 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4238 template<input_range _Vp,
size_t _Nm>
4240 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4241 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4243 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4244 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4247 elements_view()
requires default_initializable<_Vp> = default;
4250 elements_view(_Vp __base)
4251 : _M_base(
std::move(__base))
4255 base() const& requires copy_constructible<_Vp>
4263 begin()
requires (!__detail::__simple_view<_Vp>)
4264 {
return _Iterator<false>(ranges::begin(_M_base)); }
4267 begin() const requires range<const _Vp>
4268 {
return _Iterator<true>(ranges::begin(_M_base)); }
4271 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4272 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4275 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4276 {
return _Iterator<false>{ranges::end(_M_base)}; }
4279 end() const requires range<const _Vp>
4280 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4283 end() const requires common_range<const _Vp>
4284 {
return _Iterator<true>{ranges::end(_M_base)}; }
4287 size()
requires sized_range<_Vp>
4288 {
return ranges::size(_M_base); }
4291 size() const requires sized_range<const _Vp>
4292 {
return ranges::size(_M_base); }
4295 template<
bool _Const>
4296 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4298 template<
bool _Const>
4302 template<
bool _Const>
4303 requires forward_range<_Base<_Const>>
4304 struct __iter_cat<_Const>
4307 static auto _S_iter_cat()
4309 using _Base = elements_view::_Base<_Const>;
4310 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4311 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4312 if constexpr (!is_lvalue_reference_v<_Res>)
4313 return input_iterator_tag{};
4314 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4315 return random_access_iterator_tag{};
4320 using iterator_category =
decltype(_S_iter_cat());
4323 template<
bool _Const>
4326 template<
bool _Const>
4327 struct _Iterator : __iter_cat<_Const>
4330 using _Base = elements_view::_Base<_Const>;
4332 iterator_t<_Base> _M_current = iterator_t<_Base>();
4334 static constexpr decltype(
auto)
4335 _S_get_element(
const iterator_t<_Base>& __i)
4337 if constexpr (is_reference_v<range_reference_t<_Base>>)
4338 return std::get<_Nm>(*__i);
4341 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4342 return static_cast<_Et
>(std::get<_Nm>(*__i));
4349 if constexpr (random_access_range<_Base>)
4350 return random_access_iterator_tag{};
4351 else if constexpr (bidirectional_range<_Base>)
4352 return bidirectional_iterator_tag{};
4353 else if constexpr (forward_range<_Base>)
4354 return forward_iterator_tag{};
4356 return input_iterator_tag{};
4359 friend _Iterator<!_Const>;
4362 using iterator_concept =
decltype(_S_iter_concept());
4365 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4366 using difference_type = range_difference_t<_Base>;
4368 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4371 _Iterator(iterator_t<_Base> __current)
4372 : _M_current(
std::move(__current))
4376 _Iterator(_Iterator<!_Const> __i)
4377 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4381 constexpr const iterator_t<_Base>&
4382 base() const& noexcept
4383 {
return _M_current; }
4385 constexpr iterator_t<_Base>
4389 constexpr decltype(
auto)
4391 {
return _S_get_element(_M_current); }
4393 constexpr _Iterator&
4405 operator++(
int)
requires forward_range<_Base>
4412 constexpr _Iterator&
4413 operator--()
requires bidirectional_range<_Base>
4420 operator--(
int)
requires bidirectional_range<_Base>
4427 constexpr _Iterator&
4428 operator+=(difference_type __n)
4429 requires random_access_range<_Base>
4435 constexpr _Iterator&
4436 operator-=(difference_type __n)
4437 requires random_access_range<_Base>
4443 constexpr decltype(
auto)
4444 operator[](difference_type __n)
const
4445 requires random_access_range<_Base>
4446 {
return _S_get_element(_M_current + __n); }
4448 friend constexpr bool
4449 operator==(
const _Iterator& __x,
const _Iterator& __y)
4450 requires equality_comparable<iterator_t<_Base>>
4451 {
return __x._M_current == __y._M_current; }
4453 friend constexpr bool
4454 operator<(
const _Iterator& __x,
const _Iterator& __y)
4455 requires random_access_range<_Base>
4456 {
return __x._M_current < __y._M_current; }
4458 friend constexpr bool
4459 operator>(
const _Iterator& __x,
const _Iterator& __y)
4460 requires random_access_range<_Base>
4461 {
return __y._M_current < __x._M_current; }
4463 friend constexpr bool
4464 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4465 requires random_access_range<_Base>
4466 {
return !(__y._M_current > __x._M_current); }
4468 friend constexpr bool
4469 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4470 requires random_access_range<_Base>
4471 {
return !(__x._M_current > __y._M_current); }
4473#ifdef __cpp_lib_three_way_comparison
4474 friend constexpr auto
4475 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4476 requires random_access_range<_Base>
4477 && three_way_comparable<iterator_t<_Base>>
4478 {
return __x._M_current <=> __y._M_current; }
4481 friend constexpr _Iterator
4482 operator+(
const _Iterator& __x, difference_type __y)
4483 requires random_access_range<_Base>
4484 {
return _Iterator{__x} += __y; }
4486 friend constexpr _Iterator
4487 operator+(difference_type __x,
const _Iterator& __y)
4488 requires random_access_range<_Base>
4489 {
return __y + __x; }
4491 friend constexpr _Iterator
4492 operator-(
const _Iterator& __x, difference_type __y)
4493 requires random_access_range<_Base>
4494 {
return _Iterator{__x} -= __y; }
4498 friend constexpr difference_type
4499 operator-(
const _Iterator& __x,
const _Iterator& __y)
4500 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4501 {
return __x._M_current - __y._M_current; }
4503 template <
bool>
friend struct _Sentinel;
4506 template<
bool _Const>
4510 template<
bool _Const2>
4512 _M_equal(
const _Iterator<_Const2>& __x)
const
4513 {
return __x._M_current == _M_end; }
4515 template<
bool _Const2>
4517 _M_distance_from(
const _Iterator<_Const2>& __i)
const
4518 {
return _M_end - __i._M_current; }
4520 using _Base = elements_view::_Base<_Const>;
4521 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4524 _Sentinel() =
default;
4527 _Sentinel(sentinel_t<_Base> __end)
4532 _Sentinel(_Sentinel<!_Const> __other)
4534 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4538 constexpr sentinel_t<_Base>
4542 template<
bool _Const2>
4543 requires sentinel_for<sentinel_t<_Base>,
4544 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4545 friend constexpr bool
4546 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4547 {
return __y._M_equal(__x); }
4549 template<
bool _Const2,
4550 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4551 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4552 friend constexpr range_difference_t<_Base2>
4553 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4554 {
return -__y._M_distance_from(__x); }
4556 template<
bool _Const2,
4557 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4558 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4559 friend constexpr range_difference_t<_Base2>
4560 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4561 {
return __x._M_distance_from(__y); }
4563 friend _Sentinel<!_Const>;
4566 _Vp _M_base = _Vp();
4569 template<
typename _Tp,
size_t _Nm>
4570 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4571 = enable_borrowed_range<_Tp>;
4575 template<
typename _Range>
4576 using keys_view = elements_view<_Range, 0>;
4578 template<
typename _Range>
4579 using values_view = elements_view<_Range, 1>;
4585 template<
size_t _Nm,
typename _Range>
4586 concept __can_elements_view
4587 =
requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4590 template<
size_t _Nm>
4591 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4593 template<viewable_range _Range>
4594 requires __detail::__can_elements_view<_Nm, _Range>
4596 operator() [[nodiscard]] (_Range&& __r)
const
4598 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4601 static constexpr bool _S_has_simple_call_op =
true;
4604 template<
size_t _Nm>
4605 inline constexpr _Elements<_Nm> elements;
4606 inline constexpr auto keys = elements<0>;
4607 inline constexpr auto values = elements<1>;
4610#ifdef __cpp_lib_ranges_zip
4613 template<
typename... _Rs>
4614 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4615 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4616 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4618 template<
typename _Fp,
typename _Tuple>
4620 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4622 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4623 return tuple<invoke_result_t<_Fp&, _Ts>...>
4625 }, std::forward<_Tuple>(__tuple));
4628 template<
typename _Fp,
typename _Tuple>
4630 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4632 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4634 }, std::forward<_Tuple>(__tuple));
4638 template<input_range... _Vs>
4639 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4640 class zip_view :
public view_interface<zip_view<_Vs...>>
4642 tuple<_Vs...> _M_views;
4644 template<
bool>
class _Iterator;
4645 template<
bool>
class _Sentinel;
4648 zip_view() =
default;
4651 zip_view(_Vs... __views)
4652 : _M_views(
std::
move(__views)...)
4656 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4657 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4660 begin() const requires (range<const _Vs> && ...)
4661 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4664 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4666 if constexpr (!__detail::__zip_is_common<_Vs...>)
4667 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4668 else if constexpr ((random_access_range<_Vs> && ...))
4669 return begin() + iter_difference_t<_Iterator<false>>(
size());
4671 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4675 end() const requires (range<const _Vs> && ...)
4677 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4678 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4679 else if constexpr ((random_access_range<const _Vs> && ...))
4680 return begin() + iter_difference_t<_Iterator<true>>(
size());
4682 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4686 size()
requires (sized_range<_Vs> && ...)
4688 return std::apply([](
auto... sizes) {
4689 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4690 return ranges::min({_CT(sizes)...});
4691 }, __detail::__tuple_transform(ranges::size, _M_views));
4695 size() const requires (sized_range<const _Vs> && ...)
4697 return std::apply([](
auto... sizes) {
4698 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4699 return ranges::min({_CT(sizes)...});
4700 }, __detail::__tuple_transform(ranges::size, _M_views));
4704 template<
typename... _Rs>
4705 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4707 template<
typename... _Views>
4708 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4709 = (enable_borrowed_range<_Views> && ...);
4713 template<
bool _Const,
typename... _Vs>
4714 concept __all_random_access
4715 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4717 template<
bool _Const,
typename... _Vs>
4718 concept __all_bidirectional
4719 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4721 template<
bool _Const,
typename... _Vs>
4722 concept __all_forward
4723 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4725 template<
bool _Const,
typename... _Views>
4726 struct __zip_view_iter_cat
4729 template<
bool _Const,
typename... _Views>
4730 requires __all_forward<_Const, _Views...>
4731 struct __zip_view_iter_cat<_Const, _Views...>
4732 {
using iterator_category = input_iterator_tag; };
4735 template<input_range... _Vs>
4736 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4737 template<
bool _Const>
4738 class zip_view<_Vs...>::_Iterator
4739 :
public __detail::__zip_view_iter_cat<_Const, _Vs...>
4741#ifdef _GLIBCXX_CLANG
4744 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4747 _Iterator(
decltype(_M_current) __current)
4748 : _M_current(
std::
move(__current))
4754 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4755 return random_access_iterator_tag{};
4756 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4757 return bidirectional_iterator_tag{};
4758 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4759 return forward_iterator_tag{};
4761 return input_iterator_tag{};
4764#ifndef _GLIBCXX_CLANG
4765 template<move_constructible _Fp, input_range... _Ws>
4766 requires (view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4767 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4768 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4769 friend class zip_transform_view;
4774 using iterator_concept =
decltype(_S_iter_concept());
4776 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4777 using difference_type
4778 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4780 _Iterator() =
default;
4783 _Iterator(_Iterator<!_Const> __i)
4785 && (convertible_to<iterator_t<_Vs>,
4786 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4787 : _M_current(
std::
move(__i._M_current))
4793 auto __f = [](
auto& __i) ->
decltype(
auto) {
4796 return __detail::__tuple_transform(__f, _M_current);
4799 constexpr _Iterator&
4802 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4812 requires __detail::__all_forward<_Const, _Vs...>
4819 constexpr _Iterator&
4821 requires __detail::__all_bidirectional<_Const, _Vs...>
4823 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4829 requires __detail::__all_bidirectional<_Const, _Vs...>
4836 constexpr _Iterator&
4837 operator+=(difference_type __x)
4838 requires __detail::__all_random_access<_Const, _Vs...>
4840 auto __f = [&]<
typename _It>(_It& __i) {
4841 __i += iter_difference_t<_It>(__x);
4843 __detail::__tuple_for_each(__f, _M_current);
4847 constexpr _Iterator&
4848 operator-=(difference_type __x)
4849 requires __detail::__all_random_access<_Const, _Vs...>
4851 auto __f = [&]<
typename _It>(_It& __i) {
4852 __i -= iter_difference_t<_It>(__x);
4854 __detail::__tuple_for_each(__f, _M_current);
4859 operator[](difference_type __n)
const
4860 requires __detail::__all_random_access<_Const, _Vs...>
4862 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
4863 return __i[iter_difference_t<_It>(__n)];
4865 return __detail::__tuple_transform(__f, _M_current);
4868 friend constexpr bool
4869 operator==(
const _Iterator& __x,
const _Iterator& __y)
4870 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4872 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4873 return __x._M_current == __y._M_current;
4876 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4880 friend constexpr auto
4881 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4882 requires __detail::__all_random_access<_Const, _Vs...>
4883 {
return __x._M_current <=> __y._M_current; }
4885 friend constexpr _Iterator
4886 operator+(
const _Iterator& __i, difference_type __n)
4887 requires __detail::__all_random_access<_Const, _Vs...>
4894 friend constexpr _Iterator
4895 operator+(difference_type __n,
const _Iterator& __i)
4896 requires __detail::__all_random_access<_Const, _Vs...>
4903 friend constexpr _Iterator
4904 operator-(
const _Iterator& __i, difference_type __n)
4905 requires __detail::__all_random_access<_Const, _Vs...>
4912 friend constexpr difference_type
4913 operator-(
const _Iterator& __x,
const _Iterator& __y)
4914 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4915 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4918 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4919 - std::get<_Is>(__y._M_current))...},
4921 [](difference_type __i) {
4922 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4927 friend constexpr auto
4928 iter_move(
const _Iterator& __i)
4929 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4931 friend constexpr void
4932 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
4933 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4936 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4940 friend class zip_view;
4943 template<input_range... _Vs>
4944 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4945 template<
bool _Const>
4946 class zip_view<_Vs...>::_Sentinel
4948 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4951 _Sentinel(
decltype(_M_end) __end)
4955 friend class zip_view;
4958 _Sentinel() =
default;
4961 _Sentinel(_Sentinel<!_Const> __i)
4963 && (convertible_to<sentinel_t<_Vs>,
4964 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4965 : _M_end(
std::
move(__i._M_end))
4968 template<
bool _OtherConst>
4969 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4970 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4971 friend constexpr bool
4972 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
4975 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4979 template<
bool _OtherConst>
4980 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4981 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4982 friend constexpr auto
4983 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
4986 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4988 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4991 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4996 template<
bool _OtherConst>
4997 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4998 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4999 friend constexpr auto
5000 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5001 {
return -(__x - __y); }
5008 template<
typename... _Ts>
5009 concept __can_zip_view
5010 =
requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
5015 template<
typename... _Ts>
5016 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5018 operator() [[nodiscard]] (_Ts&&... __ts)
const
5020 if constexpr (
sizeof...(_Ts) == 0)
5021 return views::empty<tuple<>>;
5023 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
5027 inline constexpr _Zip zip;
5032 template<
typename _Range,
bool _Const>
5033 using __range_iter_cat
5034 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5037 template<move_constructible _Fp, input_range... _Vs>
5038 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5039 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5040 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5041 class zip_transform_view :
public view_interface<zip_transform_view<_Fp, _Vs...>>
5043 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5044 zip_view<_Vs...> _M_zip;
5046 using _InnerView = zip_view<_Vs...>;
5048 template<
bool _Const>
5049 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5051 template<
bool _Const>
5052 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5054 template<
bool _Const>
5055 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5057 template<
bool _Const>
5061 template<
bool _Const>
5062 requires forward_range<_Base<_Const>>
5063 struct __iter_cat<_Const>
5069 using __detail::__maybe_const_t;
5070 using __detail::__range_iter_cat;
5071 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5072 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5075 if constexpr (!is_reference_v<_Res>)
5076 return input_iterator_tag{};
5077 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5078 random_access_iterator_tag> && ...))
5079 return random_access_iterator_tag{};
5080 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5081 bidirectional_iterator_tag> && ...))
5082 return bidirectional_iterator_tag{};
5083 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5084 forward_iterator_tag> && ...))
5085 return forward_iterator_tag{};
5087 return input_iterator_tag{};
5090 using iterator_category =
decltype(_S_iter_cat());
5093 template<
bool>
class _Iterator;
5094 template<
bool>
class _Sentinel;
5097 zip_transform_view() =
default;
5100 zip_transform_view(_Fp __fun, _Vs... __views)
5106 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5110 requires range<const _InnerView>
5111 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5112 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5117 if constexpr (common_range<_InnerView>)
5118 return _Iterator<false>(*
this, _M_zip.end());
5120 return _Sentinel<false>(_M_zip.end());
5125 requires range<const _InnerView>
5126 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5128 if constexpr (common_range<const _InnerView>)
5129 return _Iterator<true>(*
this, _M_zip.end());
5131 return _Sentinel<true>(_M_zip.end());
5135 size()
requires sized_range<_InnerView>
5136 {
return _M_zip.size(); }
5139 size() const requires sized_range<const _InnerView>
5140 {
return _M_zip.size(); }
5143 template<
class _Fp,
class... Rs>
5144 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5146 template<move_constructible _Fp, input_range... _Vs>
5147 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5148 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5149 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5150 template<
bool _Const>
5151 class zip_transform_view<_Fp, _Vs...>::_Iterator :
public __iter_cat<_Const>
5153 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5155 _Parent* _M_parent =
nullptr;
5156 __ziperator<_Const> _M_inner;
5159 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5163 friend class zip_transform_view;
5167 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5169 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5170 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5171 using difference_type = range_difference_t<_Base<_Const>>;
5173 _Iterator() =
default;
5176 _Iterator(_Iterator<!_Const> __i)
5177 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5178 : _M_parent(__i._M_parent), _M_inner(
std::move(__i._M_inner))
5181 constexpr decltype(
auto)
5184 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5186 }, _M_inner._M_current);
5189 constexpr _Iterator&
5201 operator++(
int)
requires forward_range<_Base<_Const>>
5208 constexpr _Iterator&
5209 operator--()
requires bidirectional_range<_Base<_Const>>
5216 operator--(
int)
requires bidirectional_range<_Base<_Const>>
5223 constexpr _Iterator&
5224 operator+=(difference_type __x)
requires random_access_range<_Base<_Const>>
5230 constexpr _Iterator&
5231 operator-=(difference_type __x)
requires random_access_range<_Base<_Const>>
5237 constexpr decltype(
auto)
5238 operator[](difference_type __n)
const requires random_access_range<_Base<_Const>>
5240 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5241 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5242 }, _M_inner._M_current);
5245 friend constexpr bool
5246 operator==(
const _Iterator& __x,
const _Iterator& __y)
5247 requires equality_comparable<__ziperator<_Const>>
5248 {
return __x._M_inner == __y._M_inner; }
5250 friend constexpr auto
5251 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5252 requires random_access_range<_Base<_Const>>
5253 {
return __x._M_inner <=> __y._M_inner; }
5255 friend constexpr _Iterator
5256 operator+(
const _Iterator& __i, difference_type __n)
5257 requires random_access_range<_Base<_Const>>
5258 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5260 friend constexpr _Iterator
5261 operator+(difference_type __n,
const _Iterator& __i)
5262 requires random_access_range<_Base<_Const>>
5263 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5265 friend constexpr _Iterator
5266 operator-(
const _Iterator& __i, difference_type __n)
5267 requires random_access_range<_Base<_Const>>
5268 {
return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5270 friend constexpr difference_type
5271 operator-(
const _Iterator& __x,
const _Iterator& __y)
5272 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5273 {
return __x._M_inner - __y._M_inner; }
5276 template<move_constructible _Fp, input_range... _Vs>
5277 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5278 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5279 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5280 template<
bool _Const>
5281 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5283 __zentinel<_Const> _M_inner;
5286 _Sentinel(__zentinel<_Const> __inner)
5290 friend class zip_transform_view;
5293 _Sentinel() =
default;
5296 _Sentinel(_Sentinel<!_Const> __i)
5297 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5301 template<
bool _OtherConst>
5302 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5303 friend constexpr bool
5304 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5305 {
return __x._M_inner == __y._M_inner; }
5307 template<
bool _OtherConst>
5308 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5309 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5310 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5311 {
return __x._M_inner - __y._M_inner; }
5313 template<
bool _OtherConst>
5314 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5315 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5316 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5317 {
return __x._M_inner - __y._M_inner; }
5324 template<
typename _Fp,
typename... _Ts>
5325 concept __can_zip_transform_view
5326 =
requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5329 struct _ZipTransform
5331 template<
typename _Fp,
typename... _Ts>
5332 requires (
sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5334 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5336 if constexpr (
sizeof...(_Ts) == 0)
5337 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5339 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5343 inline constexpr _ZipTransform zip_transform;
5346 template<forward_range _Vp,
size_t _Nm>
5347 requires view<_Vp> && (_Nm > 0)
5348 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5350 _Vp _M_base = _Vp();
5352 template<
bool>
class _Iterator;
5353 template<
bool>
class _Sentinel;
5355 struct __as_sentinel
5359 adjacent_view()
requires default_initializable<_Vp> = default;
5362 adjacent_view(_Vp __base)
5363 : _M_base(
std::move(__base))
5369 base() const & requires copy_constructible<_Vp>
5377 begin()
requires (!__detail::__simple_view<_Vp>)
5378 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5381 begin() const requires range<const _Vp>
5382 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5385 end()
requires (!__detail::__simple_view<_Vp>)
5387 if constexpr (common_range<_Vp>)
5388 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5390 return _Sentinel<false>(ranges::end(_M_base));
5394 end() const requires range<const _Vp>
5396 if constexpr (common_range<const _Vp>)
5397 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5399 return _Sentinel<true>(ranges::end(_M_base));
5403 size()
requires sized_range<_Vp>
5405 using _ST =
decltype(ranges::size(_M_base));
5406 using _CT = common_type_t<_ST, size_t>;
5407 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5408 __sz -= std::min<_CT>(__sz, _Nm - 1);
5409 return static_cast<_ST
>(__sz);
5413 size() const requires sized_range<const _Vp>
5415 using _ST =
decltype(ranges::size(_M_base));
5416 using _CT = common_type_t<_ST, size_t>;
5417 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5418 __sz -= std::min<_CT>(__sz, _Nm - 1);
5419 return static_cast<_ST
>(__sz);
5423 template<
typename _Vp,
size_t _Nm>
5424 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5425 = enable_borrowed_range<_Vp>;
5430 template<
typename _Tp,
size_t _Nm>
5435 template<
typename _Fp,
size_t _Nm>
5438 template<
typename... _Ts>
5439 static invoke_result_t<_Fp, _Ts...>
5440 __tuple_apply(
const tuple<_Ts...>&);
5442 template<
typename _Tp>
5443 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5448 template<forward_range _Vp,
size_t _Nm>
5449 requires view<_Vp> && (_Nm > 0)
5450 template<bool _Const>
5451 class adjacent_view<_Vp, _Nm>::_Iterator
5453#ifdef _GLIBCXX_CLANG
5456 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5457 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5460 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5462 for (
auto& __i : _M_current)
5465 ranges::advance(__first, 1, __last);
5470 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5472 if constexpr (!bidirectional_range<_Base>)
5473 for (
auto& __it : _M_current)
5476 for (
size_t __i = 0; __i < _Nm; ++__i)
5478 _M_current[_Nm - 1 - __i] = __last;
5479 ranges::advance(__last, -1, __first);
5486 if constexpr (random_access_range<_Base>)
5487 return random_access_iterator_tag{};
5488 else if constexpr (bidirectional_range<_Base>)
5489 return bidirectional_iterator_tag{};
5491 return forward_iterator_tag{};
5494 friend class adjacent_view;
5496#ifndef _GLIBCXX_CLANG
5497 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5498 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5499 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5500 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5501 range_reference_t<_Wp>>>
5502 friend class adjacent_transform_view;
5506 using iterator_category = input_iterator_tag;
5507 using iterator_concept =
decltype(_S_iter_concept());
5509 pair<range_value_t<_Base>, range_value_t<_Base>>,
5510 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5511 using difference_type = range_difference_t<_Base>;
5513 _Iterator() =
default;
5516 _Iterator(_Iterator<!_Const> __i)
5517 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5519 for (
size_t __j = 0; __j < _Nm; ++__j)
5520 _M_current[__j] =
std::move(__i._M_current[__j]);
5526 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5527 return __detail::__tuple_transform(__f, _M_current);
5530 constexpr _Iterator&
5533 for (
auto& __i : _M_current)
5546 constexpr _Iterator&
5547 operator--()
requires bidirectional_range<_Base>
5549 for (
auto& __i : _M_current)
5555 operator--(
int)
requires bidirectional_range<_Base>
5562 constexpr _Iterator&
5563 operator+=(difference_type __x)
5564 requires random_access_range<_Base>
5566 for (
auto& __i : _M_current)
5571 constexpr _Iterator&
5572 operator-=(difference_type __x)
5573 requires random_access_range<_Base>
5575 for (
auto& __i : _M_current)
5581 operator[](difference_type __n)
const
5582 requires random_access_range<_Base>
5584 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5585 return __detail::__tuple_transform(__f, _M_current);
5588 friend constexpr bool
5589 operator==(
const _Iterator& __x,
const _Iterator& __y)
5590 {
return __x._M_current.back() == __y._M_current.back(); }
5592 friend constexpr bool
5593 operator<(
const _Iterator& __x,
const _Iterator& __y)
5594 requires random_access_range<_Base>
5595 {
return __x._M_current.back() < __y._M_current.back(); }
5597 friend constexpr bool
5598 operator>(
const _Iterator& __x,
const _Iterator& __y)
5599 requires random_access_range<_Base>
5600 {
return __y < __x; }
5602 friend constexpr bool
5603 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5604 requires random_access_range<_Base>
5605 {
return !(__y < __x); }
5607 friend constexpr bool
5608 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5609 requires random_access_range<_Base>
5610 {
return !(__x < __y); }
5612 friend constexpr auto
5613 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5614 requires random_access_range<_Base>
5615 && three_way_comparable<iterator_t<_Base>>
5616 {
return __x._M_current.back() <=> __y._M_current.back(); }
5618 friend constexpr _Iterator
5619 operator+(
const _Iterator& __i, difference_type __n)
5620 requires random_access_range<_Base>
5627 friend constexpr _Iterator
5628 operator+(difference_type __n,
const _Iterator& __i)
5629 requires random_access_range<_Base>
5636 friend constexpr _Iterator
5637 operator-(
const _Iterator& __i, difference_type __n)
5638 requires random_access_range<_Base>
5645 friend constexpr difference_type
5646 operator-(
const _Iterator& __x,
const _Iterator& __y)
5647 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5648 {
return __x._M_current.back() - __y._M_current.back(); }
5650 friend constexpr auto
5651 iter_move(
const _Iterator& __i)
5652 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5654 friend constexpr void
5655 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5656 requires indirectly_swappable<iterator_t<_Base>>
5658 for (
size_t __i = 0; __i < _Nm; __i++)
5659 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5663 template<forward_range _Vp,
size_t _Nm>
5664 requires view<_Vp> && (_Nm > 0)
5665 template<bool _Const>
5666 class adjacent_view<_Vp, _Nm>::_Sentinel
5668 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5670 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5673 _Sentinel(sentinel_t<_Base> __end)
5677 friend class adjacent_view;
5680 _Sentinel() =
default;
5683 _Sentinel(_Sentinel<!_Const> __i)
5684 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5688 template<
bool _OtherConst>
5689 requires sentinel_for<sentinel_t<_Base>,
5690 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5691 friend constexpr bool
5692 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5693 {
return __x._M_current.back() == __y._M_end; }
5695 template<
bool _OtherConst>
5696 requires sized_sentinel_for<sentinel_t<_Base>,
5697 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5698 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5699 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5700 {
return __x._M_current.back() - __y._M_end; }
5702 template<
bool _OtherConst>
5703 requires sized_sentinel_for<sentinel_t<_Base>,
5704 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5705 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5706 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5707 {
return __y._M_end - __x._M_current.back(); }
5714 template<
size_t _Nm,
typename _Range>
5715 concept __can_adjacent_view
5716 =
requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5719 template<
size_t _Nm>
5720 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5722 template<viewable_range _Range>
5723 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5725 operator() [[nodiscard]] (_Range&& __r)
const
5727 if constexpr (_Nm == 0)
5728 return views::empty<tuple<>>;
5730 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5734 template<
size_t _Nm>
5735 inline constexpr _Adjacent<_Nm> adjacent;
5737 inline constexpr auto pairwise = adjacent<2>;
5740 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5741 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5742 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5743 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5744 range_reference_t<_Vp>>>
5745 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5747 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5748 adjacent_view<_Vp, _Nm> _M_inner;
5750 using _InnerView = adjacent_view<_Vp, _Nm>;
5752 template<
bool _Const>
5753 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5755 template<
bool _Const>
5756 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5758 template<
bool>
class _Iterator;
5759 template<
bool>
class _Sentinel;
5762 adjacent_transform_view() =
default;
5765 adjacent_transform_view(_Vp __base, _Fp __fun)
5773 base() const & requires copy_constructible<_Vp>
5774 {
return _M_inner.base(); }
5782 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5786 requires range<const _InnerView>
5787 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5788 range_reference_t<const _Vp>>
5789 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5794 if constexpr (common_range<_InnerView>)
5795 return _Iterator<false>(*
this, _M_inner.end());
5797 return _Sentinel<false>(_M_inner.end());
5802 requires range<const _InnerView>
5803 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5804 range_reference_t<const _Vp>>
5806 if constexpr (common_range<const _InnerView>)
5807 return _Iterator<true>(*
this, _M_inner.end());
5809 return _Sentinel<true>(_M_inner.end());
5813 size()
requires sized_range<_InnerView>
5814 {
return _M_inner.size(); }
5817 size() const requires sized_range<const _InnerView>
5818 {
return _M_inner.size(); }
5821 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5822 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5823 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5824 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5825 range_reference_t<_Vp>>>
5826 template<bool _Const>
5827 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5829 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5830 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5832 _Parent* _M_parent =
nullptr;
5833 _InnerIter<_Const> _M_inner;
5836 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5843 using __detail::__maybe_const_t;
5844 using __detail::__unarize;
5845 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5846 range_reference_t<_Base>>;
5847 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
5850 if constexpr (!is_reference_v<_Res>)
5851 return input_iterator_tag{};
5852 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5853 return random_access_iterator_tag{};
5854 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5855 return bidirectional_iterator_tag{};
5856 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5857 return forward_iterator_tag{};
5859 return input_iterator_tag{};
5862 friend class adjacent_transform_view;
5865 using iterator_category =
decltype(_S_iter_cat());
5866 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
5868 = remove_cvref_t<invoke_result_t
5869 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5870 range_reference_t<_Base>>>;
5871 using difference_type = range_difference_t<_Base>;
5873 _Iterator() =
default;
5876 _Iterator(_Iterator<!_Const> __i)
5877 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5878 : _M_parent(__i._M_parent), _M_inner(
std::move(__i._M_inner))
5881 constexpr decltype(
auto)
5884 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5886 }, _M_inner._M_current);
5889 constexpr _Iterator&
5904 constexpr _Iterator&
5905 operator--()
requires bidirectional_range<_Base>
5912 operator--(
int)
requires bidirectional_range<_Base>
5919 constexpr _Iterator&
5920 operator+=(difference_type __x)
requires random_access_range<_Base>
5926 constexpr _Iterator&
5927 operator-=(difference_type __x)
requires random_access_range<_Base>
5933 constexpr decltype(
auto)
5934 operator[](difference_type __n)
const requires random_access_range<_Base>
5936 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5938 }, _M_inner._M_current);
5941 friend constexpr bool
5942 operator==(
const _Iterator& __x,
const _Iterator& __y)
5943 {
return __x._M_inner == __y._M_inner; }
5945 friend constexpr bool
5946 operator<(
const _Iterator& __x,
const _Iterator& __y)
5947 requires random_access_range<_Base>
5948 {
return __x._M_inner < __y._M_inner; }
5950 friend constexpr bool
5951 operator>(
const _Iterator& __x,
const _Iterator& __y)
5952 requires random_access_range<_Base>
5953 {
return __x._M_inner > __y._M_inner; }
5955 friend constexpr bool
5956 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5957 requires random_access_range<_Base>
5958 {
return __x._M_inner <= __y._M_inner; }
5960 friend constexpr bool
5961 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5962 requires random_access_range<_Base>
5963 {
return __x._M_inner >= __y._M_inner; }
5965 friend constexpr auto
5966 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5967 requires random_access_range<_Base> &&
5968 three_way_comparable<_InnerIter<_Const>>
5969 {
return __x._M_inner <=> __y._M_inner; }
5971 friend constexpr _Iterator
5972 operator+(
const _Iterator& __i, difference_type __n)
5973 requires random_access_range<_Base>
5974 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5976 friend constexpr _Iterator
5977 operator+(difference_type __n,
const _Iterator& __i)
5978 requires random_access_range<_Base>
5979 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5981 friend constexpr _Iterator
5982 operator-(
const _Iterator& __i, difference_type __n)
5983 requires random_access_range<_Base>
5984 {
return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5986 friend constexpr difference_type
5987 operator-(
const _Iterator& __x,
const _Iterator& __y)
5988 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5989 {
return __x._M_inner - __y._M_inner; }
5992 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5993 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5994 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5995 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5996 range_reference_t<_Vp>>>
5997 template<bool _Const>
5998 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6000 _InnerSent<_Const> _M_inner;
6003 _Sentinel(_InnerSent<_Const> __inner)
6007 friend class adjacent_transform_view;
6010 _Sentinel() =
default;
6013 _Sentinel(_Sentinel<!_Const> __i)
6014 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6018 template<
bool _OtherConst>
6019 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6020 friend constexpr bool
6021 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6022 {
return __x._M_inner == __y._M_inner; }
6024 template<
bool _OtherConst>
6025 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6026 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6027 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6028 {
return __x._M_inner - __y._M_inner; }
6030 template<
bool _OtherConst>
6031 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6032 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6033 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
6034 {
return __x._M_inner - __y._M_inner; }
6041 template<
size_t _Nm,
typename _Range,
typename _Fp>
6042 concept __can_adjacent_transform_view
6043 =
requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6044 (std::declval<_Range>(), std::declval<_Fp>()); };
6047 template<
size_t _Nm>
6048 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6050 template<viewable_range _Range,
typename _Fp>
6051 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6053 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
6055 if constexpr (_Nm == 0)
6056 return zip_transform(std::forward<_Fp>(__f));
6058 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6059 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6062 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6063 static constexpr int _S_arity = 2;
6064 static constexpr bool _S_has_simple_extra_args =
true;
6067 template<
size_t _Nm>
6068 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6070 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6074#ifdef __cpp_lib_ranges_chunk
6077 template<
typename _Tp>
6078 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6080 _Tp __r = __num / __denom;
6081 if (__num % __denom)
6088 requires input_range<_Vp>
6089 class chunk_view :
public view_interface<chunk_view<_Vp>>
6092 range_difference_t<_Vp> _M_n;
6093 range_difference_t<_Vp> _M_remainder = 0;
6094 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6101 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6103 { __glibcxx_assert(__n >= 0); }
6106 base() const & requires copy_constructible<_Vp>
6113 constexpr _OuterIter
6116 _M_current = ranges::begin(_M_base);
6117 _M_remainder = _M_n;
6118 return _OuterIter(*
this);
6121 constexpr default_sentinel_t
6122 end() const noexcept
6126 size()
requires sized_range<_Vp>
6128 return __detail::__to_unsigned_like(__detail::__div_ceil
6129 (ranges::distance(_M_base), _M_n));
6133 size() const requires sized_range<const _Vp>
6135 return __detail::__to_unsigned_like(__detail::__div_ceil
6136 (ranges::distance(_M_base), _M_n));
6140 template<
typename _Range>
6141 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6144 requires input_range<_Vp>
6145 class chunk_view<_Vp>::_OuterIter
6147 chunk_view* _M_parent;
6150 _OuterIter(chunk_view& __parent) noexcept
6157 using iterator_concept = input_iterator_tag;
6158 using difference_type = range_difference_t<_Vp>;
6162 _OuterIter(_OuterIter&&) =
default;
6163 _OuterIter& operator=(_OuterIter&&) =
default;
6165 constexpr value_type
6168 __glibcxx_assert(*
this != default_sentinel);
6169 return value_type(*_M_parent);
6172 constexpr _OuterIter&
6175 __glibcxx_assert(*
this != default_sentinel);
6176 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6177 ranges::end(_M_parent->_M_base));
6178 _M_parent->_M_remainder = _M_parent->_M_n;
6186 friend constexpr bool
6187 operator==(
const _OuterIter& __x, default_sentinel_t)
6189 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6190 && __x._M_parent->_M_remainder != 0;
6193 friend constexpr difference_type
6194 operator-(default_sentinel_t,
const _OuterIter& __x)
6195 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6197 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6199 if (__dist < __x._M_parent->_M_remainder)
6200 return __dist == 0 ? 0 : 1;
6202 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6203 __x._M_parent->_M_n);
6206 friend constexpr difference_type
6207 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6208 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6209 {
return -(__y - __x); }
6213 requires input_range<_Vp>
6214 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6217 chunk_view* _M_parent;
6220 value_type(chunk_view& __parent) noexcept
6227 constexpr _InnerIter
6228 begin() const noexcept
6229 {
return _InnerIter(*_M_parent); }
6231 constexpr default_sentinel_t
6232 end() const noexcept
6237 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6239 return __detail::__to_unsigned_like
6240 (ranges::min(_M_parent->_M_remainder,
6241 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6246 requires input_range<_Vp>
6247 class chunk_view<_Vp>::_InnerIter
6249 chunk_view* _M_parent;
6252 _InnerIter(chunk_view& __parent) noexcept
6256 friend _OuterIter::value_type;
6259 using iterator_concept = input_iterator_tag;
6260 using difference_type = range_difference_t<_Vp>;
6261 using value_type = range_value_t<_Vp>;
6263 _InnerIter(_InnerIter&&) =
default;
6264 _InnerIter& operator=(_InnerIter&&) =
default;
6266 constexpr const iterator_t<_Vp>&
6268 {
return *_M_parent->_M_current; }
6270 constexpr range_reference_t<_Vp>
6273 __glibcxx_assert(*
this != default_sentinel);
6274 return **_M_parent->_M_current;
6277 constexpr _InnerIter&
6280 __glibcxx_assert(*
this != default_sentinel);
6281 ++*_M_parent->_M_current;
6282 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6283 _M_parent->_M_remainder = 0;
6285 --_M_parent->_M_remainder;
6293 friend constexpr bool
6294 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6295 {
return __x._M_parent->_M_remainder == 0; }
6297 friend constexpr difference_type
6298 operator-(default_sentinel_t,
const _InnerIter& __x)
6299 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6301 return ranges::min(__x._M_parent->_M_remainder,
6302 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6305 friend constexpr difference_type
6306 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6307 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6308 {
return -(__y - __x); }
6312 friend constexpr range_rvalue_reference_t<_Vp>
6313 iter_move(
const _InnerIter& __i)
6314 noexcept(
noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6315 {
return ranges::iter_move(*__i._M_parent->_M_current); }
6317 friend constexpr void
6318 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
6319 noexcept(
noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6320 *__x._M_parent->_M_current)))
6321 requires indirectly_swappable<iterator_t<_Vp>>
6322 {
return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6326 requires forward_range<_Vp>
6327 class chunk_view<_Vp> :
public view_interface<chunk_view<_Vp>>
6330 range_difference_t<_Vp> _M_n;
6331 template<
bool>
class _Iterator;
6335 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6337 { __glibcxx_assert(__n > 0); }
6340 base() const & requires copy_constructible<_Vp>
6348 begin()
requires (!__detail::__simple_view<_Vp>)
6349 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6352 begin() const requires forward_range<const _Vp>
6353 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6356 end()
requires (!__detail::__simple_view<_Vp>)
6358 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6360 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6361 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6363 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6364 return _Iterator<false>(
this, ranges::end(_M_base));
6370 end() const requires forward_range<const _Vp>
6372 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6374 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6375 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6377 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6378 return _Iterator<true>(
this, ranges::end(_M_base));
6384 size()
requires sized_range<_Vp>
6386 return __detail::__to_unsigned_like(__detail::__div_ceil
6387 (ranges::distance(_M_base), _M_n));
6391 size() const requires sized_range<const _Vp>
6393 return __detail::__to_unsigned_like(__detail::__div_ceil
6394 (ranges::distance(_M_base), _M_n));
6398 template<
typename _Vp>
6399 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6400 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6403 requires forward_range<_Vp>
6404 template<
bool _Const>
6405 class chunk_view<_Vp>::_Iterator
6407 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6408 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6410 iterator_t<_Base> _M_current = iterator_t<_Base>();
6411 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6412 range_difference_t<_Base> _M_n = 0;
6413 range_difference_t<_Base> _M_missing = 0;
6416 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6417 range_difference_t<_Base> __missing = 0)
6418 : _M_current(__current), _M_end(ranges::
end(__parent->_M_base)),
6419 _M_n(__parent->_M_n), _M_missing(__missing)
6425 if constexpr (random_access_range<_Base>)
6426 return random_access_iterator_tag{};
6427 else if constexpr (bidirectional_range<_Base>)
6428 return bidirectional_iterator_tag{};
6430 return forward_iterator_tag{};
6436 using iterator_category = input_iterator_tag;
6437 using iterator_concept =
decltype(_S_iter_cat());
6438 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6439 using difference_type = range_difference_t<_Base>;
6441 _Iterator() =
default;
6443 constexpr _Iterator(_Iterator<!_Const> __i)
6445 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6446 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6448 _M_n(__i._M_n), _M_missing(__i._M_missing)
6451 constexpr iterator_t<_Base>
6453 {
return _M_current; }
6455 constexpr value_type
6458 __glibcxx_assert(_M_current != _M_end);
6459 return views::take(subrange(_M_current, _M_end), _M_n);
6462 constexpr _Iterator&
6465 __glibcxx_assert(_M_current != _M_end);
6466 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6478 constexpr _Iterator&
6479 operator--()
requires bidirectional_range<_Base>
6481 ranges::advance(_M_current, _M_missing - _M_n);
6487 operator--(
int)
requires bidirectional_range<_Base>
6494 constexpr _Iterator&
6495 operator+=(difference_type __x)
6496 requires random_access_range<_Base>
6500 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6501 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6505 ranges::advance(_M_current, _M_n * __x + _M_missing);
6511 constexpr _Iterator&
6512 operator-=(difference_type __x)
6513 requires random_access_range<_Base>
6514 {
return *
this += -__x; }
6516 constexpr value_type
6517 operator[](difference_type __n)
const
6518 requires random_access_range<_Base>
6519 {
return *(*
this + __n); }
6521 friend constexpr bool
6522 operator==(
const _Iterator& __x,
const _Iterator& __y)
6523 {
return __x._M_current == __y._M_current; }
6525 friend constexpr bool
6526 operator==(
const _Iterator& __x, default_sentinel_t)
6527 {
return __x._M_current == __x._M_end; }
6529 friend constexpr bool
6530 operator<(
const _Iterator& __x,
const _Iterator& __y)
6531 requires random_access_range<_Base>
6532 {
return __x._M_current > __y._M_current; }
6534 friend constexpr bool
6535 operator>(
const _Iterator& __x,
const _Iterator& __y)
6536 requires random_access_range<_Base>
6537 {
return __y < __x; }
6539 friend constexpr bool
6540 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6541 requires random_access_range<_Base>
6542 {
return !(__y < __x); }
6544 friend constexpr bool
6545 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6546 requires random_access_range<_Base>
6547 {
return !(__x < __y); }
6549 friend constexpr auto
6550 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6551 requires random_access_range<_Base>
6552 && three_way_comparable<iterator_t<_Base>>
6553 {
return __x._M_current <=> __y._M_current; }
6555 friend constexpr _Iterator
6556 operator+(
const _Iterator& __i, difference_type __n)
6557 requires random_access_range<_Base>
6564 friend constexpr _Iterator
6565 operator+(difference_type __n,
const _Iterator& __i)
6566 requires random_access_range<_Base>
6573 friend constexpr _Iterator
6574 operator-(
const _Iterator& __i, difference_type __n)
6575 requires random_access_range<_Base>
6582 friend constexpr difference_type
6583 operator-(
const _Iterator& __x,
const _Iterator& __y)
6584 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6586 return (__x._M_current - __y._M_current
6587 + __x._M_missing - __y._M_missing) / __x._M_n;
6590 friend constexpr difference_type
6591 operator-(default_sentinel_t __y,
const _Iterator& __x)
6592 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6593 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6595 friend constexpr difference_type
6596 operator-(
const _Iterator& __x, default_sentinel_t __y)
6597 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6598 {
return -(__y - __x); }
6605 template<
typename _Range,
typename _Dp>
6606 concept __can_chunk_view
6607 =
requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6610 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6612 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6613 requires __detail::__can_chunk_view<_Range, _Dp>
6615 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6616 {
return chunk_view(std::forward<_Range>(__r), __n); }
6618 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6619 static constexpr int _S_arity = 2;
6620 static constexpr bool _S_has_simple_extra_args =
true;
6623 inline constexpr _Chunk chunk;
6627#ifdef __cpp_lib_ranges_slide
6630 template<
typename _Vp>
6631 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6633 template<
typename _Vp>
6634 concept __slide_caches_last
6635 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6637 template<
typename _Vp>
6638 concept __slide_caches_first
6639 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6642 template<forward_range _Vp>
6644 class slide_view :
public view_interface<slide_view<_Vp>>
6647 range_difference_t<_Vp> _M_n;
6648 [[no_unique_address]]
6649 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6650 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6651 [[no_unique_address]]
6652 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6653 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6655 template<
bool>
class _Iterator;
6660 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6662 { __glibcxx_assert(__n > 0); }
6667 base() const & requires copy_constructible<_Vp>
6675 begin()
requires (!(__detail::__simple_view<_Vp>
6676 && __detail::__slide_caches_nothing<const _Vp>))
6678 if constexpr (__detail::__slide_caches_first<_Vp>)
6680 iterator_t<_Vp> __it;
6681 if (_M_cached_begin._M_has_value())
6682 __it = _M_cached_begin._M_get(_M_base);
6685 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6686 _M_cached_begin._M_set(_M_base, __it);
6688 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6691 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6695 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6696 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6699 end()
requires (!(__detail::__simple_view<_Vp>
6700 && __detail::__slide_caches_nothing<const _Vp>))
6702 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6703 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(
size()),
6705 else if constexpr (__detail::__slide_caches_last<_Vp>)
6707 iterator_t<_Vp> __it;
6708 if (_M_cached_end._M_has_value())
6709 __it = _M_cached_end._M_get(_M_base);
6712 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6713 _M_cached_end._M_set(_M_base, __it);
6715 return _Iterator<false>(
std::move(__it), _M_n);
6717 else if constexpr (common_range<_Vp>)
6718 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6720 return _Sentinel(ranges::end(_M_base));
6724 end() const requires __detail::__slide_caches_nothing<const _Vp>
6725 {
return begin() + range_difference_t<const _Vp>(
size()); }
6728 size()
requires sized_range<_Vp>
6730 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6733 return __detail::__to_unsigned_like(__sz);
6737 size() const requires sized_range<const _Vp>
6739 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6742 return __detail::__to_unsigned_like(__sz);
6746 template<
typename _Range>
6747 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6749 template<
typename _Vp>
6750 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6751 = enable_borrowed_range<_Vp>;
6753 template<forward_range _Vp>
6755 template<
bool _Const>
6756 class slide_view<_Vp>::_Iterator
6758 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6759 static constexpr bool _S_last_elt_present
6760 = __detail::__slide_caches_first<_Base>;
6762 iterator_t<_Base> _M_current = iterator_t<_Base>();
6763 [[no_unique_address]]
6764 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6765 _M_last_elt =
decltype(_M_last_elt)();
6766 range_difference_t<_Base> _M_n = 0;
6769 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6770 requires (!_S_last_elt_present)
6771 : _M_current(__current), _M_n(__n)
6775 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6776 range_difference_t<_Base> __n)
6777 requires _S_last_elt_present
6778 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6784 if constexpr (random_access_range<_Base>)
6785 return random_access_iterator_tag{};
6786 else if constexpr (bidirectional_range<_Base>)
6787 return bidirectional_iterator_tag{};
6789 return forward_iterator_tag{};
6793 friend slide_view::_Sentinel;
6796 using iterator_category = input_iterator_tag;
6797 using iterator_concept =
decltype(_S_iter_concept());
6798 using value_type =
decltype(views::counted(_M_current, _M_n));
6799 using difference_type = range_difference_t<_Base>;
6801 _Iterator() =
default;
6804 _Iterator(_Iterator<!_Const> __i)
6805 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6806 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
6811 {
return views::counted(_M_current, _M_n); }
6813 constexpr _Iterator&
6817 if constexpr (_S_last_elt_present)
6830 constexpr _Iterator&
6831 operator--()
requires bidirectional_range<_Base>
6834 if constexpr (_S_last_elt_present)
6840 operator--(
int)
requires bidirectional_range<_Base>
6847 constexpr _Iterator&
6848 operator+=(difference_type __x)
6849 requires random_access_range<_Base>
6852 if constexpr (_S_last_elt_present)
6857 constexpr _Iterator&
6858 operator-=(difference_type __x)
6859 requires random_access_range<_Base>
6862 if constexpr (_S_last_elt_present)
6868 operator[](difference_type __n)
const
6869 requires random_access_range<_Base>
6870 {
return views::counted(_M_current + __n, _M_n); }
6872 friend constexpr bool
6873 operator==(
const _Iterator& __x,
const _Iterator& __y)
6875 if constexpr (_S_last_elt_present)
6876 return __x._M_last_elt == __y._M_last_elt;
6878 return __x._M_current == __y._M_current;
6881 friend constexpr bool
6882 operator<(
const _Iterator& __x,
const _Iterator& __y)
6883 requires random_access_range<_Base>
6884 {
return __x._M_current < __y._M_current; }
6886 friend constexpr bool
6887 operator>(
const _Iterator& __x,
const _Iterator& __y)
6888 requires random_access_range<_Base>
6889 {
return __y < __x; }
6891 friend constexpr bool
6892 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6893 requires random_access_range<_Base>
6894 {
return !(__y < __x); }
6896 friend constexpr bool
6897 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6898 requires random_access_range<_Base>
6899 {
return !(__x < __y); }
6901 friend constexpr auto
6902 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6903 requires random_access_range<_Base>
6904 && three_way_comparable<iterator_t<_Base>>
6905 {
return __x._M_current <=> __y._M_current; }
6907 friend constexpr _Iterator
6908 operator+(
const _Iterator& __i, difference_type __n)
6909 requires random_access_range<_Base>
6916 friend constexpr _Iterator
6917 operator+(difference_type __n,
const _Iterator& __i)
6918 requires random_access_range<_Base>
6925 friend constexpr _Iterator
6926 operator-(
const _Iterator& __i, difference_type __n)
6927 requires random_access_range<_Base>
6934 friend constexpr difference_type
6935 operator-(
const _Iterator& __x,
const _Iterator& __y)
6936 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6938 if constexpr (_S_last_elt_present)
6939 return __x._M_last_elt - __y._M_last_elt;
6941 return __x._M_current - __y._M_current;
6945 template<forward_range _Vp>
6947 class slide_view<_Vp>::_Sentinel
6949 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6952 _Sentinel(sentinel_t<_Vp> __end)
6959 _Sentinel() =
default;
6961 friend constexpr bool
6962 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
6963 {
return __x._M_last_elt == __y._M_end; }
6965 friend constexpr range_difference_t<_Vp>
6966 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
6967 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6968 {
return __x._M_last_elt - __y._M_end; }
6970 friend constexpr range_difference_t<_Vp>
6971 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
6972 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6973 {
return __y._M_end -__x._M_last_elt; }
6980 template<
typename _Range,
typename _Dp>
6981 concept __can_slide_view
6982 =
requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6985 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6987 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6988 requires __detail::__can_slide_view<_Range, _Dp>
6990 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6991 {
return slide_view(std::forward<_Range>(__r), __n); }
6993 using __adaptor::_RangeAdaptor<_Slide>::operator();
6994 static constexpr int _S_arity = 2;
6995 static constexpr bool _S_has_simple_extra_args =
true;
6998 inline constexpr _Slide slide;
7002#ifdef __cpp_lib_ranges_chunk_by
7003 template<forward_range _Vp,
7004 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7005 requires view<_Vp> && is_object_v<_Pred>
7006 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
7008 _Vp _M_base = _Vp();
7009 __detail::__box<_Pred> _M_pred;
7010 __detail::_CachedPosition<_Vp> _M_cached_begin;
7012 constexpr iterator_t<_Vp>
7013 _M_find_next(iterator_t<_Vp> __current)
7015 __glibcxx_assert(_M_pred.has_value());
7016 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7017 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
7019 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7020 return ranges::next(__it, 1, ranges::end(_M_base));
7023 constexpr iterator_t<_Vp>
7024 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
7026 __glibcxx_assert(_M_pred.has_value());
7027 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7028 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
7032 __glibcxx_assert(__rbegin != __rend);
7033 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7034 return ranges::prev(__it, 1, ranges::begin(_M_base));
7040 chunk_by_view()
requires (default_initializable<_Vp>
7041 && default_initializable<_Pred>)
7045 chunk_by_view(_Vp __base, _Pred __pred)
7050 base() const & requires copy_constructible<_Vp>
7057 constexpr const _Pred&
7059 {
return *_M_pred; }
7064 __glibcxx_assert(_M_pred.has_value());
7065 iterator_t<_Vp> __it;
7066 if (_M_cached_begin._M_has_value())
7067 __it = _M_cached_begin._M_get(_M_base);
7070 __it = _M_find_next(ranges::begin(_M_base));
7071 _M_cached_begin._M_set(_M_base, __it);
7073 return _Iterator(*
this, ranges::begin(_M_base), __it);
7079 if constexpr (common_range<_Vp>)
7080 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
7086 template<
typename _Range,
typename _Pred>
7087 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7089 template<forward_range _Vp,
7090 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7091 requires view<_Vp> && is_object_v<_Pred>
7092 class chunk_by_view<_Vp, _Pred>::_Iterator
7094 chunk_by_view* _M_parent =
nullptr;
7095 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7096 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7099 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7100 : _M_parent(
std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7106 if constexpr (bidirectional_range<_Vp>)
7107 return bidirectional_iterator_tag{};
7109 return forward_iterator_tag{};
7112 friend chunk_by_view;
7115 using value_type = subrange<iterator_t<_Vp>>;
7116 using difference_type = range_difference_t<_Vp>;
7117 using iterator_category = input_iterator_tag;
7118 using iterator_concept =
decltype(_S_iter_concept());
7120 _Iterator() =
default;
7122 constexpr value_type
7125 __glibcxx_assert(_M_current != _M_next);
7126 return ranges::subrange(_M_current, _M_next);
7129 constexpr _Iterator&
7132 __glibcxx_assert(_M_current != _M_next);
7133 _M_current = _M_next;
7134 _M_next = _M_parent->_M_find_next(_M_current);
7146 constexpr _Iterator&
7147 operator--()
requires bidirectional_range<_Vp>
7149 _M_next = _M_current;
7150 _M_current = _M_parent->_M_find_prev(_M_next);
7155 operator--(
int)
requires bidirectional_range<_Vp>
7162 friend constexpr bool
7163 operator==(
const _Iterator& __x,
const _Iterator& __y)
7164 {
return __x._M_current == __y._M_current; }
7166 friend constexpr bool
7167 operator==(
const _Iterator& __x, default_sentinel_t)
7168 {
return __x._M_current == __x._M_next; }
7175 template<
typename _Range,
typename _Pred>
7176 concept __can_chunk_by_view
7177 =
requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7180 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7182 template<viewable_range _Range,
typename _Pred>
7183 requires __detail::__can_chunk_by_view<_Range, _Pred>
7185 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7186 {
return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7188 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7189 static constexpr int _S_arity = 2;
7190 static constexpr bool _S_has_simple_extra_args =
true;
7193 inline constexpr _ChunkBy chunk_by;
7197#ifdef __cpp_lib_ranges_join_with
7200 template<
typename _Range,
typename _Pattern>
7201 concept __compatible_joinable_ranges
7202 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7203 && common_reference_with<range_reference_t<_Range>,
7204 range_reference_t<_Pattern>>
7205 && common_reference_with<range_rvalue_reference_t<_Range>,
7206 range_rvalue_reference_t<_Pattern>>;
7208 template<
typename _Range>
7209 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7212 template<input_range _Vp, forward_range _Pattern>
7213 requires view<_Vp> && view<_Pattern>
7214 && input_range<range_reference_t<_Vp>>
7215 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7216 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7218 using _InnerRange = range_reference_t<_Vp>;
7220 _Vp _M_base = _Vp();
7221 [[no_unique_address]]
7222 __detail::__maybe_present_t<!forward_range<_Vp>,
7223 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7224 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7225 _Pattern _M_pattern = _Pattern();
7227 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7228 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7229 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7231 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7232 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7233 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7235 template<
bool _Const>
7236 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7238 template<
bool _Const>
7242 template<
bool _Const>
7243 requires _S_ref_is_glvalue<_Const>
7244 && forward_range<_Base<_Const>>
7245 && forward_range<_InnerBase<_Const>>
7246 struct __iter_cat<_Const>
7252 using _OuterIter = join_with_view::_OuterIter<_Const>;
7253 using _InnerIter = join_with_view::_InnerIter<_Const>;
7254 using _PatternIter = join_with_view::_PatternIter<_Const>;
7255 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7256 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7257 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7260 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7261 iter_reference_t<_PatternIter>>>)
7262 return input_iterator_tag{};
7263 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7264 && derived_from<_InnerCat, bidirectional_iterator_tag>
7265 && derived_from<_PatternCat, bidirectional_iterator_tag>
7266 && common_range<_InnerBase<_Const>>
7267 && common_range<_PatternBase<_Const>>)
7268 return bidirectional_iterator_tag{};
7269 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7270 && derived_from<_InnerCat, forward_iterator_tag>
7271 && derived_from<_PatternCat, forward_iterator_tag>)
7272 return forward_iterator_tag{};
7274 return input_iterator_tag{};
7277 using iterator_category =
decltype(_S_iter_cat());
7280 template<
bool>
struct _Iterator;
7281 template<
bool>
struct _Sentinel;
7284 join_with_view()
requires (default_initializable<_Vp>
7285 && default_initializable<_Pattern>)
7289 join_with_view(_Vp __base, _Pattern __pattern)
7293 template<input_range _Range>
7294 requires constructible_from<_Vp, views::all_t<_Range>>
7295 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7297 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7298 : _M_base(views::all(
std::
forward<_Range>(__r))),
7299 _M_pattern(views::single(
std::
move(__e)))
7303 base() const& requires copy_constructible<_Vp>
7313 if constexpr (forward_range<_Vp>)
7315 constexpr bool __use_const = is_reference_v<_InnerRange>
7316 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7317 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7321 _M_outer_it = ranges::begin(_M_base);
7322 return _Iterator<false>{*
this};
7328 requires forward_range<const _Vp>
7329 && forward_range<const _Pattern>
7330 && is_reference_v<range_reference_t<const _Vp>>
7331 && input_range<range_reference_t<const _Vp>>
7332 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7337 constexpr bool __use_const
7338 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7339 if constexpr (is_reference_v<_InnerRange>
7340 && forward_range<_Vp> && common_range<_Vp>
7341 && forward_range<_InnerRange> && common_range<_InnerRange>)
7342 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7344 return _Sentinel<__use_const>{*
this};
7349 requires forward_range<const _Vp>
7350 && forward_range<const _Pattern>
7351 && is_reference_v<range_reference_t<const _Vp>>
7352 && input_range<range_reference_t<const _Vp>>
7354 using _InnerConstRange = range_reference_t<const _Vp>;
7355 if constexpr (forward_range<_InnerConstRange>
7356 && common_range<const _Vp>
7357 && common_range<_InnerConstRange>)
7358 return _Iterator<true>{*
this, ranges::end(_M_base)};
7360 return _Sentinel<true>{*
this};
7364 template<
typename _Range,
typename _Pattern>
7365 join_with_view(_Range&&, _Pattern&&)
7366 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7368 template<input_range _Range>
7369 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7370 -> join_with_view<views::all_t<_Range>,
7371 single_view<range_value_t<range_reference_t<_Range>>>>;
7373 template<input_range _Vp, forward_range _Pattern>
7374 requires view<_Vp> && view<_Pattern>
7375 && input_range<range_reference_t<_Vp>>
7376 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7377 template<
bool _Const>
7378 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7380 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7381 using _Base = join_with_view::_Base<_Const>;
7382 using _InnerBase = join_with_view::_InnerBase<_Const>;
7383 using _PatternBase = join_with_view::_PatternBase<_Const>;
7385 using _OuterIter = join_with_view::_OuterIter<_Const>;
7386 using _InnerIter = join_with_view::_InnerIter<_Const>;
7387 using _PatternIter = join_with_view::_PatternIter<_Const>;
7389 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7391 _Parent* _M_parent =
nullptr;
7392 [[no_unique_address]]
7393 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7394 variant<_PatternIter, _InnerIter> _M_inner_it;
7396 constexpr _OuterIter&
7399 if constexpr (forward_range<_Base>)
7402 return *_M_parent->_M_outer_it;
7405 constexpr const _OuterIter&
7406 _M_get_outer()
const
7408 if constexpr (forward_range<_Base>)
7411 return *_M_parent->_M_outer_it;
7415 _Iterator(_Parent& __parent, _OuterIter __outer)
7416 requires forward_range<_Base>
7419 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7421 auto&& __inner = _M_update_inner();
7422 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7428 _Iterator(_Parent& __parent)
7429 requires (!forward_range<_Base>)
7432 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7434 auto&& __inner = _M_update_inner();
7435 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7443 _OuterIter& __outer = _M_get_outer();
7444 if constexpr (_S_ref_is_glvalue)
7445 return __detail::__as_lvalue(*__outer);
7447 return _M_parent->_M_inner._M_emplace_deref(__outer);
7453 if constexpr (_S_ref_is_glvalue)
7454 return __detail::__as_lvalue(*_M_get_outer());
7456 return *_M_parent->_M_inner;
7464 if (_M_inner_it.index() == 0)
7466 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7469 auto&& __inner = _M_update_inner();
7470 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7474 auto&& __inner = _M_get_inner();
7475 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7478 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7480 if constexpr (_S_ref_is_glvalue)
7481 _M_inner_it.template emplace<0>();
7485 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7493 if constexpr (_S_ref_is_glvalue
7494 && bidirectional_range<_Base>
7495 && __detail::__bidirectional_common<_InnerBase>
7496 && __detail::__bidirectional_common<_PatternBase>)
7497 return bidirectional_iterator_tag{};
7498 else if constexpr (_S_ref_is_glvalue
7499 && forward_range<_Base>
7500 && forward_range<_InnerBase>)
7501 return forward_iterator_tag{};
7503 return input_iterator_tag{};
7506 friend join_with_view;
7509 using iterator_concept =
decltype(_S_iter_concept());
7511 using value_type = common_type_t<iter_value_t<_InnerIter>,
7512 iter_value_t<_PatternIter>>;
7513 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7514 iter_difference_t<_InnerIter>,
7515 iter_difference_t<_PatternIter>>;
7517 _Iterator() =
default;
7520 _Iterator(_Iterator<!_Const> __i)
7522 && convertible_to<iterator_t<_Vp>, _OuterIter>
7523 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7524 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7525 : _M_parent(__i._M_parent),
7528 if (__i._M_inner_it.index() == 0)
7529 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7531 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7534 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7535 iter_reference_t<_PatternIter>>
7538 if (_M_inner_it.index() == 0)
7539 return *std::get<0>(_M_inner_it);
7541 return *std::get<1>(_M_inner_it);
7544 constexpr _Iterator&
7547 if (_M_inner_it.index() == 0)
7548 ++std::get<0>(_M_inner_it);
7550 ++std::get<1>(_M_inner_it);
7561 requires _S_ref_is_glvalue
7562 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7564 _Iterator __tmp = *
this;
7569 constexpr _Iterator&
7571 requires _S_ref_is_glvalue
7572 && bidirectional_range<_Base>
7573 && __detail::__bidirectional_common<_InnerBase>
7574 && __detail::__bidirectional_common<_PatternBase>
7576 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7578 auto&& __inner = *--_M_outer_it;
7579 _M_inner_it.template emplace<1>(ranges::end(__inner));
7584 if (_M_inner_it.index() == 0)
7586 auto& __it = std::get<0>(_M_inner_it);
7587 if (__it == ranges::begin(_M_parent->_M_pattern))
7589 auto&& __inner = *--_M_outer_it;
7590 _M_inner_it.template emplace<1>(ranges::end(__inner));
7597 auto& __it = std::get<1>(_M_inner_it);
7598 auto&& __inner = *_M_outer_it;
7599 if (__it == ranges::begin(__inner))
7600 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7606 if (_M_inner_it.index() == 0)
7607 --std::get<0>(_M_inner_it);
7609 --std::get<1>(_M_inner_it);
7615 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7616 && __detail::__bidirectional_common<_InnerBase>
7617 && __detail::__bidirectional_common<_PatternBase>
7619 _Iterator __tmp = *
this;
7624 friend constexpr bool
7625 operator==(
const _Iterator& __x,
const _Iterator& __y)
7626 requires _S_ref_is_glvalue
7627 && forward_range<_Base> && equality_comparable<_InnerIter>
7628 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7630 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7631 iter_rvalue_reference_t<_PatternIter>>
7632 iter_move(
const _Iterator& __x)
7634 if (__x._M_inner_it.index() == 0)
7635 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7637 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7640 friend constexpr void
7641 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7642 requires indirectly_swappable<_InnerIter, _PatternIter>
7644 if (__x._M_inner_it.index() == 0)
7646 if (__y._M_inner_it.index() == 0)
7647 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7649 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7653 if (__y._M_inner_it.index() == 0)
7654 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7656 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7661 template<input_range _Vp, forward_range _Pattern>
7662 requires view<_Vp> && view<_Pattern>
7663 && input_range<range_reference_t<_Vp>>
7664 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7665 template<
bool _Const>
7666 class join_with_view<_Vp, _Pattern>::_Sentinel
7668 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7669 using _Base = join_with_view::_Base<_Const>;
7671 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7674 _Sentinel(_Parent& __parent)
7675 : _M_end(ranges::
end(__parent._M_base))
7678 friend join_with_view;
7681 _Sentinel() =
default;
7684 _Sentinel(_Sentinel<!_Const> __s)
7685 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7689 template<
bool _OtherConst>
7690 requires sentinel_for<sentinel_t<_Base>,
7691 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7692 friend constexpr bool
7693 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7694 {
return __x._M_get_outer() == __y._M_end; }
7701 template<
typename _Range,
typename _Pattern>
7702 concept __can_join_with_view
7703 =
requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7706 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7708 template<viewable_range _Range,
typename _Pattern>
7709 requires __detail::__can_join_with_view<_Range, _Pattern>
7711 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7713 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7716 using _RangeAdaptor<_JoinWith>::operator();
7717 static constexpr int _S_arity = 2;
7718 template<
typename _Pattern>
7719 static constexpr bool _S_has_simple_extra_args
7720 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7723 inline constexpr _JoinWith join_with;
7727#ifdef __cpp_lib_ranges_repeat
7728 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7729 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7730 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7731 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7733 __detail::__box<_Tp> _M_value;
7734 [[no_unique_address]] _Bound _M_bound = _Bound();
7738 template<
typename _Range>
7739 friend constexpr auto
7740 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7742 template<
typename _Range>
7743 friend constexpr auto
7744 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7747 repeat_view()
requires default_initializable<_Tp> = default;
7750 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7751 requires copy_constructible<_Tp>
7752 : _M_value(__value), _M_bound(__bound)
7754 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7755 __glibcxx_assert(__bound >= 0);
7759 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7760 : _M_value(
std::
move(__value)), _M_bound(__bound)
7763 template<
typename... _Args,
typename... _BoundArgs>
7764 requires constructible_from<_Tp, _Args...>
7765 && constructible_from<_Bound, _BoundArgs...>
7767 repeat_view(piecewise_construct_t,
7768 tuple<_Args...> __args,
7769 tuple<_BoundArgs...> __bound_args = tuple<>{})
7770 : _M_value(
std::make_from_tuple<_Tp>(
std::
move(__args))),
7771 _M_bound(
std::make_from_tuple<_Bound>(
std::
move(__bound_args)))
7779 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7782 constexpr unreachable_sentinel_t
7783 end() const noexcept
7784 {
return unreachable_sentinel; }
7787 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7788 {
return __detail::__to_unsigned_like(_M_bound); }
7793 template<
typename _Tp,
typename _Bound = unreachable_sentinel_t>
7794 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7796 template<move_constructible _Tp, semiregular _Bound>
7797 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7798 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7799 class repeat_view<_Tp, _Bound>::_Iterator
7802 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7804 const _Tp* _M_value =
nullptr;
7805 __index_type _M_current = __index_type();
7808 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
7809 : _M_value(__value), _M_current(__bound)
7811 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7812 __glibcxx_assert(__bound >= 0);
7818 using iterator_concept = random_access_iterator_tag;
7819 using iterator_category = random_access_iterator_tag;
7820 using value_type = _Tp;
7821 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7823 __detail::__iota_diff_t<__index_type>>;
7825 _Iterator() =
default;
7827 constexpr const _Tp&
7829 {
return *_M_value; }
7831 constexpr _Iterator&
7846 constexpr _Iterator&
7849 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7850 __glibcxx_assert(_M_current > 0);
7863 constexpr _Iterator&
7864 operator+=(difference_type __n)
7866 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7867 __glibcxx_assert(_M_current + __n >= 0);
7872 constexpr _Iterator&
7873 operator-=(difference_type __n)
7875 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7876 __glibcxx_assert(_M_current - __n >= 0);
7881 constexpr const _Tp&
7882 operator[](difference_type __n)
const noexcept
7883 {
return *(*
this + __n); }
7885 friend constexpr bool
7886 operator==(
const _Iterator& __x,
const _Iterator& __y)
7887 {
return __x._M_current == __y._M_current; }
7889 friend constexpr auto
7890 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7891 {
return __x._M_current <=> __y._M_current; }
7893 friend constexpr _Iterator
7894 operator+(_Iterator __i, difference_type __n)
7900 friend constexpr _Iterator
7901 operator+(difference_type __n, _Iterator __i)
7902 {
return __i + __n; }
7904 friend constexpr _Iterator
7905 operator-(_Iterator __i, difference_type __n)
7911 friend constexpr difference_type
7912 operator-(
const _Iterator& __x,
const _Iterator& __y)
7914 return (
static_cast<difference_type
>(__x._M_current)
7915 -
static_cast<difference_type
>(__y._M_current));
7923 template<
typename _Tp,
typename _Bound>
7924 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
7926 template<
typename _Tp>
7927 concept __can_repeat_view
7928 =
requires { repeat_view(std::declval<_Tp>()); };
7930 template<
typename _Tp,
typename _Bound>
7931 concept __can_bounded_repeat_view
7932 =
requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7937 template<
typename _Tp>
7938 requires __detail::__can_repeat_view<_Tp>
7940 operator() [[nodiscard]] (_Tp&& __value)
const
7944 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7947 template<
typename _Tp,
typename _Bound>
7948 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7950 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
7951 {
return repeat_view(std::forward<_Tp>(__value), __bound); }
7954 inline constexpr _Repeat repeat;
7958 template<
typename _Range>
7960 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7962 using _Tp = remove_cvref_t<_Range>;
7963 static_assert(__is_repeat_view<_Tp>);
7964 if constexpr (sized_range<_Tp>)
7965 return views::repeat(*std::forward<_Range>(__r)._M_value,
7966 std::min(ranges::distance(__r), __n));
7968 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7971 template<
typename _Range>
7973 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7975 using _Tp = remove_cvref_t<_Range>;
7976 static_assert(__is_repeat_view<_Tp>);
7977 if constexpr (sized_range<_Tp>)
7979 auto __sz = ranges::distance(__r);
7980 return views::repeat(*std::forward<_Range>(__r)._M_value,
7990#ifdef __cpp_lib_ranges_stride
7991 template<input_range _Vp>
7993 class stride_view :
public view_interface<stride_view<_Vp>>
7996 range_difference_t<_Vp> _M_stride;
7998 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8000 template<
bool _Const>
8004 template<
bool _Const>
8005 requires forward_range<_Base<_Const>>
8006 struct __iter_cat<_Const>
8012 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8013 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8014 return random_access_iterator_tag{};
8019 using iterator_category =
decltype(_S_iter_cat());
8022 template<
bool>
class _Iterator;
8026 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8028 { __glibcxx_assert(__stride > 0); }
8031 base() const& requires copy_constructible<_Vp>
8038 constexpr range_difference_t<_Vp>
8039 stride() const noexcept
8040 {
return _M_stride; }
8043 begin()
requires (!__detail::__simple_view<_Vp>)
8044 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
8047 begin() const requires range<const _Vp>
8048 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
8051 end()
requires (!__detail::__simple_view<_Vp>)
8053 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8055 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8056 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
8058 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8059 return _Iterator<false>(
this, ranges::end(_M_base));
8065 end() const requires range<const _Vp>
8067 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8068 && forward_range<const _Vp>)
8070 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8071 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
8073 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8074 return _Iterator<true>(
this, ranges::end(_M_base));
8080 size()
requires sized_range<_Vp>
8082 return __detail::__to_unsigned_like
8083 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8087 size() const requires sized_range<const _Vp>
8089 return __detail::__to_unsigned_like
8090 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8094 template<
typename _Range>
8095 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8097 template<
typename _Vp>
8098 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8099 = enable_borrowed_range<_Vp>;
8101 template<input_range _Vp>
8103 template<
bool _Const>
8104 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8106 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8107 using _Base = stride_view::_Base<_Const>;
8109 iterator_t<_Base> _M_current = iterator_t<_Base>();
8110 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8111 range_difference_t<_Base> _M_stride = 0;
8112 range_difference_t<_Base> _M_missing = 0;
8115 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8116 range_difference_t<_Base> __missing = 0)
8117 : _M_current(
std::
move(__current)), _M_end(ranges::
end(__parent->_M_base)),
8118 _M_stride(__parent->_M_stride), _M_missing(__missing)
8124 if constexpr (random_access_range<_Base>)
8125 return random_access_iterator_tag{};
8126 else if constexpr (bidirectional_range<_Base>)
8127 return bidirectional_iterator_tag{};
8128 else if constexpr (forward_range<_Base>)
8129 return forward_iterator_tag{};
8131 return input_iterator_tag{};
8137 using difference_type = range_difference_t<_Base>;
8138 using value_type = range_value_t<_Base>;
8139 using iterator_concept =
decltype(_S_iter_concept());
8142 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8145 _Iterator(_Iterator<!_Const> __other)
8147 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8148 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8149 : _M_current(
std::move(__other._M_current)), _M_end(
std::move(__other._M_end)),
8150 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8153 constexpr iterator_t<_Base>
8157 constexpr const iterator_t<_Base>&
8158 base() const & noexcept
8159 {
return _M_current; }
8161 constexpr decltype(
auto)
8163 {
return *_M_current; }
8165 constexpr _Iterator&
8168 __glibcxx_assert(_M_current != _M_end);
8169 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8178 operator++(
int)
requires forward_range<_Base>
8185 constexpr _Iterator&
8186 operator--()
requires bidirectional_range<_Base>
8188 ranges::advance(_M_current, _M_missing - _M_stride);
8194 operator--(
int)
requires bidirectional_range<_Base>
8201 constexpr _Iterator&
8202 operator+=(difference_type __n)
requires random_access_range<_Base>
8206 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8207 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8211 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8217 constexpr _Iterator&
8218 operator-=(difference_type __n)
requires random_access_range<_Base>
8219 {
return *
this += -__n; }
8221 constexpr decltype(
auto)
operator[](difference_type __n)
const
8222 requires random_access_range<_Base>
8223 {
return *(*
this + __n); }
8225 friend constexpr bool
8226 operator==(
const _Iterator& __x, default_sentinel_t)
8227 {
return __x._M_current == __x._M_end; }
8229 friend constexpr bool
8230 operator==(
const _Iterator& __x,
const _Iterator& __y)
8231 requires equality_comparable<iterator_t<_Base>>
8232 {
return __x._M_current == __y._M_current; }
8234 friend constexpr bool
8235 operator<(
const _Iterator& __x,
const _Iterator& __y)
8236 requires random_access_range<_Base>
8237 {
return __x._M_current < __y._M_current; }
8239 friend constexpr bool
8240 operator>(
const _Iterator& __x,
const _Iterator& __y)
8241 requires random_access_range<_Base>
8242 {
return __y._M_current < __x._M_current; }
8244 friend constexpr bool
8245 operator<=(
const _Iterator& __x,
const _Iterator& __y)
8246 requires random_access_range<_Base>
8247 {
return !(__y._M_current < __x._M_current); }
8249 friend constexpr bool
8250 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8251 requires random_access_range<_Base>
8252 {
return !(__x._M_current < __y._M_current); }
8254 friend constexpr auto
8255 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8256 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8257 {
return __x._M_current <=> __y._M_current; }
8259 friend constexpr _Iterator
8260 operator+(
const _Iterator& __i, difference_type __n)
8261 requires random_access_range<_Base>
8268 friend constexpr _Iterator
8269 operator+(difference_type __n,
const _Iterator& __i)
8270 requires random_access_range<_Base>
8271 {
return __i + __n; }
8273 friend constexpr _Iterator
8274 operator-(
const _Iterator& __i, difference_type __n)
8275 requires random_access_range<_Base>
8282 friend constexpr difference_type
8283 operator-(
const _Iterator& __x,
const _Iterator& __y)
8284 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8286 auto __n = __x._M_current - __y._M_current;
8287 if constexpr (forward_range<_Base>)
8288 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8290 return -__detail::__div_ceil(-__n, __x._M_stride);
8292 return __detail::__div_ceil(__n, __x._M_stride);
8295 friend constexpr difference_type
8296 operator-(default_sentinel_t __y,
const _Iterator& __x)
8297 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8298 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8300 friend constexpr difference_type
8301 operator-(
const _Iterator& __x, default_sentinel_t __y)
8302 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8303 {
return -(__y - __x); }
8305 friend constexpr range_rvalue_reference_t<_Base>
8306 iter_move(
const _Iterator& __i)
8307 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8308 {
return ranges::iter_move(__i._M_current); }
8310 friend constexpr void
8311 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8312 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8313 requires indirectly_swappable<iterator_t<_Base>>
8314 { ranges::iter_swap(__x._M_current, __y._M_current); }
8321 template<
typename _Range,
typename _Dp>
8322 concept __can_stride_view
8323 =
requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8326 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8328 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8329 requires __detail::__can_stride_view<_Range, _Dp>
8331 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8332 {
return stride_view(std::forward<_Range>(__r), __n); }
8334 using __adaptor::_RangeAdaptor<_Stride>::operator();
8335 static constexpr int _S_arity = 2;
8336 static constexpr bool _S_has_simple_extra_args =
true;
8339 inline constexpr _Stride stride;
8343#ifdef __cpp_lib_ranges_cartesian_product
8346 template<
bool _Const,
typename _First,
typename... _Vs>
8347 concept __cartesian_product_is_random_access
8348 = (random_access_range<__maybe_const_t<_Const, _First>>
8350 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8351 && sized_range<__maybe_const_t<_Const, _Vs>>));
8353 template<
typename _Range>
8354 concept __cartesian_product_common_arg
8355 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8357 template<
bool _Const,
typename _First,
typename... _Vs>
8358 concept __cartesian_product_is_bidirectional
8359 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8361 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8362 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8364 template<
typename _First,
typename... _Vs>
8365 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8367 template<
typename... _Vs>
8368 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8370 template<
bool _Const,
template<
typename>
class FirstSent,
typename _First,
typename... _Vs>
8371 concept __cartesian_is_sized_sentinel
8372 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8373 iterator_t<__maybe_const_t<_Const, _First>>>
8375 && (sized_range<__maybe_const_t<_Const, _Vs>>
8376 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8377 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8379 template<__cartesian_product_common_arg _Range>
8381 __cartesian_common_arg_end(_Range& __r)
8383 if constexpr (common_range<_Range>)
8384 return ranges::end(__r);
8386 return ranges::begin(__r) + ranges::distance(__r);
8390 template<input_range _First, forward_range... _Vs>
8391 requires (view<_First> && ... && view<_Vs>)
8392 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8394 tuple<_First, _Vs...> _M_bases;
8396 template<
bool>
class _Iterator;
8399 _S_difference_type()
8405 range_difference_t<_First>,
8406 range_difference_t<_Vs>...>{};
8410 cartesian_product_view() =
default;
8413 cartesian_product_view(_First __first, _Vs... __rest)
8417 constexpr _Iterator<false>
8418 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8419 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8421 constexpr _Iterator<true>
8422 begin() const requires (range<const _First> && ... && range<const _Vs>)
8423 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8425 constexpr _Iterator<false>
8426 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8427 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8430 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8431 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8432 auto& __first = std::get<0>(_M_bases);
8433 return _Ret{(__empty_tail
8434 ? ranges::begin(__first)
8435 : __detail::__cartesian_common_arg_end(__first)),
8436 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8439 return _Iterator<false>{*
this,
std::move(__its)};
8442 constexpr _Iterator<true>
8443 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8446 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8447 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8448 auto& __first = std::get<0>(_M_bases);
8449 return _Ret{(__empty_tail
8450 ? ranges::begin(__first)
8451 : __detail::__cartesian_common_arg_end(__first)),
8452 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8455 return _Iterator<true>{*
this,
std::move(__its)};
8458 constexpr default_sentinel_t
8459 end() const noexcept
8463 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8465 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8467 auto __size =
static_cast<_ST
>(1);
8468#ifdef _GLIBCXX_ASSERTIONS
8469 if constexpr (integral<_ST>)
8472 = (__builtin_mul_overflow(__size,
8473 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8476 __glibcxx_assert(!__overflow);
8480 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8486 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8488 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8490 auto __size =
static_cast<_ST
>(1);
8491#ifdef _GLIBCXX_ASSERTIONS
8492 if constexpr (integral<_ST>)
8495 = (__builtin_mul_overflow(__size,
8496 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8499 __glibcxx_assert(!__overflow);
8503 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8509 template<
typename... _Vs>
8510 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8512 template<input_range _First, forward_range... _Vs>
8513 requires (view<_First> && ... && view<_Vs>)
8514 template<bool _Const>
8515 class cartesian_product_view<_First, _Vs...>::_Iterator
8517 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8518 _Parent* _M_parent =
nullptr;
8519 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8520 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8523 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8525 _M_current(
std::
move(__current))
8531 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8532 return random_access_iterator_tag{};
8533 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8534 return bidirectional_iterator_tag{};
8535 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8536 return forward_iterator_tag{};
8538 return input_iterator_tag{};
8541 friend cartesian_product_view;
8544 using iterator_category = input_iterator_tag;
8545 using iterator_concept =
decltype(_S_iter_concept());
8547 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8548 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8550 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8551 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8552 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8554 _Iterator() =
default;
8557 _Iterator(_Iterator<!_Const> __i)
8559 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8560 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8562 _M_current(
std::
move(__i._M_current))
8568 auto __f = [](
auto& __i) ->
decltype(
auto) {
8571 return __detail::__tuple_transform(__f, _M_current);
8574 constexpr _Iterator&
8586 operator++(
int)
requires forward_range<__maybe_const_t<_Const, _First>>
8593 constexpr _Iterator&
8595 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8603 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8610 constexpr _Iterator&
8611 operator+=(difference_type __x)
8612 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8618 constexpr _Iterator&
8619 operator-=(difference_type __x)
8620 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8621 {
return *
this += -__x; }
8624 operator[](difference_type __n)
const
8625 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8626 {
return *((*this) + __n); }
8628 friend constexpr bool
8629 operator==(
const _Iterator& __x,
const _Iterator& __y)
8630 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8631 {
return __x._M_current == __y._M_current; }
8633 friend constexpr bool
8634 operator==(
const _Iterator& __x, default_sentinel_t)
8637 return ((std::get<_Is>(__x._M_current)
8638 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8643 friend constexpr auto
8644 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8645 requires __detail::__all_random_access<_Const, _First, _Vs...>
8646 {
return __x._M_current <=> __y._M_current; }
8648 friend constexpr _Iterator
8649 operator+(_Iterator __x, difference_type __y)
8650 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8651 {
return __x += __y; }
8653 friend constexpr _Iterator
8654 operator+(difference_type __x, _Iterator __y)
8655 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8656 {
return __y += __x; }
8658 friend constexpr _Iterator
8659 operator-(_Iterator __x, difference_type __y)
8660 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8661 {
return __x -= __y; }
8663 friend constexpr difference_type
8664 operator-(
const _Iterator& __x,
const _Iterator& __y)
8665 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8666 {
return __x._M_distance_from(__y._M_current); }
8668 friend constexpr difference_type
8669 operator-(
const _Iterator& __i, default_sentinel_t)
8670 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8673 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8674 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8676 return __i._M_distance_from(__end_tuple);
8679 friend constexpr difference_type
8680 operator-(default_sentinel_t,
const _Iterator& __i)
8681 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8684 friend constexpr auto
8685 iter_move(
const _Iterator& __i)
8686 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8688 friend constexpr void
8689 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8690 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8692 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8695 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8700 template<
size_t _Nm =
sizeof...(_Vs)>
8704 auto& __it = std::get<_Nm>(_M_current);
8706 if constexpr (_Nm > 0)
8707 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8709 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8714 template<
size_t _Nm =
sizeof...(_Vs)>
8718 auto& __it = std::get<_Nm>(_M_current);
8719 if constexpr (_Nm > 0)
8720 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8722 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8728 template<
size_t _Nm =
sizeof...(_Vs)>
8730 _M_advance(difference_type __x)
8731 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8740 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8741 auto& __it = std::get<_Nm>(_M_current);
8742 if constexpr (_Nm == 0)
8744#ifdef _GLIBCXX_ASSERTIONS
8745 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8747 auto __size = ranges::ssize(__r);
8748 auto __begin = ranges::begin(__r);
8749 auto __offset = __it - __begin;
8750 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8757 auto __size = ranges::ssize(__r);
8758 auto __begin = ranges::begin(__r);
8759 auto __offset = __it - __begin;
8761 __x = __offset / __size;
8765 __offset = __size + __offset;
8768 __it = __begin + __offset;
8769 _M_advance<_Nm - 1>(__x);
8774 template<
typename _Tuple>
8775 constexpr difference_type
8776 _M_distance_from(
const _Tuple& __t)
const
8779 auto __sum =
static_cast<difference_type
>(0);
8780#ifdef _GLIBCXX_ASSERTIONS
8781 if constexpr (integral<difference_type>)
8784 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8786 __glibcxx_assert(!__overflow);
8790 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8795 template<
size_t _Nm,
typename _Tuple>
8796 constexpr difference_type
8797 _M_scaled_distance(
const _Tuple& __t)
const
8799 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8800 - std::get<_Nm>(__t));
8801#ifdef _GLIBCXX_ASSERTIONS
8802 if constexpr (integral<difference_type>)
8804 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8805 __glibcxx_assert(!__overflow);
8809 __dist *= _M_scaled_size<_Nm+1>();
8813 template<
size_t _Nm>
8814 constexpr difference_type
8815 _M_scaled_size()
const
8817 if constexpr (_Nm <=
sizeof...(_Vs))
8819 auto __size =
static_cast<difference_type
>(ranges::size
8820 (std::get<_Nm>(_M_parent->_M_bases)));
8821#ifdef _GLIBCXX_ASSERTIONS
8822 if constexpr (integral<difference_type>)
8824 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8825 __glibcxx_assert(!__overflow);
8829 __size *= _M_scaled_size<_Nm+1>();
8833 return static_cast<difference_type
>(1);
8841 template<
typename... _Ts>
8842 concept __can_cartesian_product_view
8843 =
requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8846 struct _CartesianProduct
8848 template<
typename... _Ts>
8849 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8851 operator() [[nodiscard]] (_Ts&&... __ts)
const
8853 if constexpr (
sizeof...(_Ts) == 0)
8854 return views::single(tuple{});
8856 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8860 inline constexpr _CartesianProduct cartesian_product;
8864#ifdef __cpp_lib_ranges_as_rvalue
8865 template<input_range _Vp>
8867 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
8869 _Vp _M_base = _Vp();
8872 as_rvalue_view()
requires default_initializable<_Vp> = default;
8875 as_rvalue_view(_Vp __base)
8876 : _M_base(
std::move(__base))
8880 base() const& requires copy_constructible<_Vp>
8888 begin()
requires (!__detail::__simple_view<_Vp>)
8889 {
return move_iterator(ranges::begin(_M_base)); }
8892 begin() const requires range<const _Vp>
8893 {
return move_iterator(ranges::begin(_M_base)); }
8896 end()
requires (!__detail::__simple_view<_Vp>)
8898 if constexpr (common_range<_Vp>)
8899 return move_iterator(ranges::end(_M_base));
8901 return move_sentinel(ranges::end(_M_base));
8905 end() const requires range<const _Vp>
8907 if constexpr (common_range<const _Vp>)
8908 return move_iterator(ranges::end(_M_base));
8910 return move_sentinel(ranges::end(_M_base));
8914 size()
requires sized_range<_Vp>
8915 {
return ranges::size(_M_base); }
8918 size() const requires sized_range<const _Vp>
8919 {
return ranges::size(_M_base); }
8922 template<
typename _Range>
8923 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8925 template<
typename _Tp>
8926 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8927 = enable_borrowed_range<_Tp>;
8933 template<
typename _Tp>
8934 concept __can_as_rvalue_view =
requires { as_rvalue_view(std::declval<_Tp>()); };
8937 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8939 template<viewable_range _Range>
8940 requires __detail::__can_as_rvalue_view<_Range>
8942 operator() [[nodiscard]] (_Range&& __r)
const
8944 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8945 range_reference_t<_Range>>)
8946 return views::all(std::forward<_Range>(__r));
8948 return as_rvalue_view(std::forward<_Range>(__r));
8952 inline constexpr _AsRvalue as_rvalue;
8956#ifdef __cpp_lib_ranges_enumerate
8959 template<
typename _Range>
8960 concept __range_with_movable_reference = input_range<_Range>
8961 && move_constructible<range_reference_t<_Range>>
8962 && move_constructible<range_rvalue_reference_t<_Range>>;
8966 requires __detail::__range_with_movable_reference<_Vp>
8967 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
8969 _Vp _M_base = _Vp();
8971 template<
bool _Const>
class _Iterator;
8972 template<
bool _Const>
class _Sentinel;
8975 enumerate_view()
requires default_initializable<_Vp> = default;
8978 enumerate_view(_Vp __base)
8979 : _M_base(
std::move(__base))
8983 begin()
requires (!__detail::__simple_view<_Vp>)
8984 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
8987 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8988 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
8991 end()
requires (!__detail::__simple_view<_Vp>)
8993 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8994 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8996 return _Sentinel<false>(ranges::end(_M_base));
9000 end() const requires __detail::__range_with_movable_reference<const _Vp>
9002 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9003 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9005 return _Sentinel<true>(ranges::end(_M_base));
9009 size()
requires sized_range<_Vp>
9010 {
return ranges::size(_M_base); }
9013 size() const requires sized_range<const _Vp>
9014 {
return ranges::size(_M_base); }
9017 base() const & requires copy_constructible<_Vp>
9025 template<
typename _Range>
9026 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9028 template<
typename _Tp>
9029 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9030 = enable_borrowed_range<_Tp>;
9033 requires __detail::__range_with_movable_reference<_Vp>
9034 template<
bool _Const>
9035 class enumerate_view<_Vp>::_Iterator
9037 using _Base = __maybe_const_t<_Const, _Vp>;
9042 if constexpr (random_access_range<_Base>)
9043 return random_access_iterator_tag{};
9044 else if constexpr (bidirectional_range<_Base>)
9045 return bidirectional_iterator_tag{};
9046 else if constexpr (forward_range<_Base>)
9047 return forward_iterator_tag{};
9049 return input_iterator_tag{};
9052 friend enumerate_view;
9055 using iterator_category = input_iterator_tag;
9056 using iterator_concept =
decltype(_S_iter_concept());
9057 using difference_type = range_difference_t<_Base>;
9058 using value_type = tuple<difference_type, range_value_t<_Base>>;
9061 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9063 iterator_t<_Base> _M_current = iterator_t<_Base>();
9064 difference_type _M_pos = 0;
9067 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9068 : _M_current(
std::
move(__current)), _M_pos(__pos)
9072 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
9075 _Iterator(_Iterator<!_Const> __i)
9076 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9077 : _M_current(
std::move(__i._M_current)), _M_pos(__i._M_pos)
9080 constexpr const iterator_t<_Base> &
9081 base() const & noexcept
9082 {
return _M_current; }
9084 constexpr iterator_t<_Base>
9088 constexpr difference_type
9089 index() const noexcept
9094 {
return __reference_type(_M_pos, *_M_current); }
9096 constexpr _Iterator&
9109 operator++(
int)
requires forward_range<_Base>
9116 constexpr _Iterator&
9117 operator--()
requires bidirectional_range<_Base>
9125 operator--(
int)
requires bidirectional_range<_Base>
9132 constexpr _Iterator&
9133 operator+=(difference_type __n)
requires random_access_range<_Base>
9140 constexpr _Iterator&
9141 operator-=(difference_type __n)
requires random_access_range<_Base>
9149 operator[](difference_type __n)
const requires random_access_range<_Base>
9150 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9152 friend constexpr bool
9153 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9154 {
return __x._M_pos == __y._M_pos; }
9156 friend constexpr strong_ordering
9157 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9158 {
return __x._M_pos <=> __y._M_pos; }
9160 friend constexpr _Iterator
9161 operator+(
const _Iterator& __x, difference_type __y)
9162 requires random_access_range<_Base>
9163 {
return (
auto(__x) += __y); }
9165 friend constexpr _Iterator
9166 operator+(difference_type __x,
const _Iterator& __y)
9167 requires random_access_range<_Base>
9168 {
return auto(__y) += __x; }
9170 friend constexpr _Iterator
9171 operator-(
const _Iterator& __x, difference_type __y)
9172 requires random_access_range<_Base>
9173 {
return auto(__x) -= __y; }
9175 friend constexpr difference_type
9176 operator-(
const _Iterator& __x,
const _Iterator& __y)
9177 {
return __x._M_pos - __y._M_pos; }
9179 friend constexpr auto
9180 iter_move(
const _Iterator& __i)
9181 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9182 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9184 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9185 (__i._M_pos, ranges::iter_move(__i._M_current));
9190 requires __detail::__range_with_movable_reference<_Vp>
9191 template<
bool _Const>
9192 class enumerate_view<_Vp>::_Sentinel
9194 using _Base = __maybe_const_t<_Const, _Vp>;
9196 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9199 _Sentinel(sentinel_t<_Base> __end)
9203 friend enumerate_view;
9206 _Sentinel() =
default;
9209 _Sentinel(_Sentinel<!_Const> __other)
9210 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9214 constexpr sentinel_t<_Base>
9218 template<
bool _OtherConst>
9219 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9220 friend constexpr bool
9221 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9222 {
return __x._M_current == __y._M_end; }
9224 template<
bool _OtherConst>
9225 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9226 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9227 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9228 {
return __x._M_current - __y._M_end; }
9230 template<
bool _OtherConst>
9231 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9232 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9233 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9234 {
return __x._M_end - __y._M_current; }
9241 template<
typename _Tp>
9242 concept __can_enumerate_view
9243 =
requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9246 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9248 template<viewable_range _Range>
9249 requires __detail::__can_enumerate_view<_Range>
9251 operator() [[nodiscard]] (_Range&& __r)
const
9252 {
return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9255 inline constexpr _Enumerate enumerate;
9259#ifdef __cpp_lib_ranges_as_const
9261 requires input_range<_Vp>
9262 class as_const_view :
public view_interface<as_const_view<_Vp>>
9264 _Vp _M_base = _Vp();
9267 as_const_view()
requires default_initializable<_Vp> = default;
9270 as_const_view(_Vp __base)
9271 noexcept(is_nothrow_move_constructible_v<_Vp>)
9272 : _M_base(
std::move(__base))
9277 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9278 requires copy_constructible<_Vp>
9283 noexcept(is_nothrow_move_constructible_v<_Vp>)
9287 begin()
requires (!__detail::__simple_view<_Vp>)
9288 {
return ranges::cbegin(_M_base); }
9291 begin() const requires range<const _Vp>
9292 {
return ranges::cbegin(_M_base); }
9295 end()
requires (!__detail::__simple_view<_Vp>)
9296 {
return ranges::cend(_M_base); }
9299 end() const requires range<const _Vp>
9300 {
return ranges::cend(_M_base); }
9303 size()
requires sized_range<_Vp>
9304 {
return ranges::size(_M_base); }
9307 size() const requires sized_range<const _Vp>
9308 {
return ranges::size(_M_base); }
9311 template<
typename _Range>
9312 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9314 template<
typename _Tp>
9315 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9316 = enable_borrowed_range<_Tp>;
9322 template<
typename _Tp>
9323 inline constexpr bool __is_ref_view =
false;
9325 template<
typename _Range>
9326 inline constexpr bool __is_ref_view<ref_view<_Range>> =
true;
9328 template<
typename _Range>
9329 concept __can_as_const_view =
requires { as_const_view(std::declval<_Range>()); };
9332 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9334 template<viewable_range _Range>
9336 operator()(_Range&& __r)
const
9337 noexcept(
noexcept(as_const_view(std::declval<_Range>())))
9338 requires __detail::__can_as_const_view<_Range>
9340 using _Tp = remove_cvref_t<_Range>;
9341 using element_type = remove_reference_t<range_reference_t<_Range>>;
9342 if constexpr (constant_range<views::all_t<_Range>>)
9343 return views::all(std::forward<_Range>(__r));
9344 else if constexpr (__detail::__is_empty_view<_Tp>)
9345 return views::empty<const element_type>;
9346 else if constexpr (std::__detail::__is_span<_Tp>)
9347 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9348 else if constexpr (__detail::__is_ref_view<_Tp>
9349 && constant_range<const element_type>)
9350 return ref_view(
static_cast<const element_type&
>
9351 (std::forward<_Range>(__r).base()));
9352 else if constexpr (is_lvalue_reference_v<_Range>
9353 && constant_range<const _Tp>
9355 return ref_view(
static_cast<const _Tp&
>(__r));
9357 return as_const_view(std::forward<_Range>(__r));
9361 inline constexpr _AsConst as_const;
9366 namespace views = ranges::views;
9368#if __cpp_lib_ranges_to_container
9374 template<
typename _Container>
9375 constexpr bool __reservable_container
9376 = sized_range<_Container>
9377 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9379 { __c.capacity() } -> same_as<
decltype(__n)>;
9380 { __c.max_size() } -> same_as<
decltype(__n)>;
9383 template<
typename _Cont,
typename _Range>
9384 constexpr bool __toable =
requires {
9385 requires (!input_range<_Cont>
9386 || convertible_to<range_reference_t<_Range>,
9387 range_value_t<_Cont>>);
9408 template<
typename _Cont, input_range _Rg,
typename... _Args>
9409 requires (!view<_Cont>)
9411 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9413 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9414 static_assert(is_class_v<_Cont>);
9416 if constexpr (__detail::__toable<_Cont, _Rg>)
9418 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9419 return _Cont(std::forward<_Rg>(__r),
9420 std::forward<_Args>(__args)...);
9421 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9422 return _Cont(from_range, std::forward<_Rg>(__r),
9423 std::forward<_Args>(__args)...);
9424 else if constexpr (
requires {
requires common_range<_Rg>;
9425 typename __iter_category_t<iterator_t<_Rg>>;
9426 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9427 input_iterator_tag>;
9428 requires constructible_from<_Cont, iterator_t<_Rg>,
9429 sentinel_t<_Rg>, _Args...>;
9431 return _Cont(ranges::begin(__r), ranges::end(__r),
9432 std::forward<_Args>(__args)...);
9435 static_assert(constructible_from<_Cont, _Args...>);
9436 _Cont __c(std::forward<_Args>(__args)...);
9437 if constexpr (sized_range<_Rg>
9438 && __detail::__reservable_container<_Cont>)
9439 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9443 auto __it = ranges::begin(__r);
9444 const auto __sent = ranges::end(__r);
9445 while (__it != __sent)
9447 if constexpr (
requires { __c.emplace_back(*__it); })
9448 __c.emplace_back(*__it);
9449 else if constexpr (
requires { __c.push_back(*__it); })
9450 __c.push_back(*__it);
9451 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9452 __c.emplace(__c.end(), *__it);
9454 __c.insert(__c.end(), *__it);
9462 static_assert(input_range<range_reference_t<_Rg>>);
9465 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9466 []<
typename _Elt>(_Elt&& __elem) {
9467 using _ValT = range_value_t<_Cont>;
9468 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9469 }), std::forward<_Args>(__args)...);
9476 template<
typename _Rg>
9479 using iterator_category = input_iterator_tag;
9480 using value_type = range_value_t<_Rg>;
9481 using difference_type = ptrdiff_t;
9482 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9483 using reference = range_reference_t<_Rg>;
9485 pointer operator->()
const;
9486 _InputIter& operator++();
9487 _InputIter operator++(
int);
9488 bool operator==(
const _InputIter&)
const;
9491 template<
template<
typename...>
typename _Cont, input_range _Rg,
9494 =
decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9496 template<
template<
typename...>
typename _Cont, input_range _Rg,
9499 =
decltype(_Cont(from_range, std::declval<_Rg>(),
9500 std::declval<_Args>()...));
9502 template<
template<
typename...>
typename _Cont, input_range _Rg,
9507 std::declval<_Args>()...));
9512 template<
template<
typename...>
typename _Cont, input_range _Rg,
9515 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9517 using __detail::_DeduceExpr1;
9518 using __detail::_DeduceExpr2;
9519 using __detail::_DeduceExpr3;
9520 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9521 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9522 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9523 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9524 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9525 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9526 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9527 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9528 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9530 static_assert(
false);
9536 template<
typename _Cont>
9539 template<
typename _Range,
typename... _Args>
9540 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9541 std::declval<_Args>()...); }
9543 operator()(_Range&& __r, _Args&&... __args)
const
9545 return ranges::to<_Cont>(std::forward<_Range>(__r),
9546 std::forward<_Args>(__args)...);
9567 template<
typename _Cont,
typename... _Args>
9568 requires (!view<_Cont>)
9570 to [[nodiscard]] (_Args&&... __args)
9572 using __detail::_To;
9573 using views::__adaptor::_Partial;
9574 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9580 template<
template<
typename...>
typename _Cont>
9583 template<
typename _Range,
typename... _Args>
9584 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9585 std::declval<_Args>()...); }
9587 operator()(_Range&& __r, _Args&&... __args)
const
9589 return ranges::to<_Cont>(std::forward<_Range>(__r),
9590 std::forward<_Args>(__args)...);
9613 template<
template<
typename...>
typename _Cont,
typename... _Args>
9615 to [[nodiscard]] (_Args&&... __args)
9617 using __detail::_To2;
9618 using views::__adaptor::_Partial;
9619 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9625#if __cpp_lib_ranges_concat
9630 template<
typename... _Rs>
9631 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9633 template<
typename... _Rs>
9634 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9636 template<
typename... _Rs>
9637 using __concat_rvalue_reference_t
9638 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9640 template<
typename _Ref,
typename _RRef,
typename _It>
9641 concept __concat_indirectly_readable_impl =
requires(
const _It __it) {
9642 { *__it } -> convertible_to<_Ref>;
9643 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9646 template<
typename... _Rs>
9647 concept __concat_indirectly_readable
9648 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9649 && common_reference_with<__concat_reference_t<_Rs...>&&,
9650 __concat_rvalue_reference_t<_Rs...>&&>
9651 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9652 __concat_value_t<_Rs...>
const&>
9653 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9654 __concat_rvalue_reference_t<_Rs...>,
9658 template<
typename... _Rs>
9659 concept __concatable =
requires {
9660 typename __concat_reference_t<_Rs...>;
9661 typename __concat_value_t<_Rs...>;
9662 typename __concat_rvalue_reference_t<_Rs...>;
9663 } && __concat_indirectly_readable<_Rs...>;
9665 template<
bool _Const,
typename _Range,
typename... _Rs>
9666 struct __all_but_last_common
9668 static inline constexpr bool value
9669 =
requires {
requires (common_range<__maybe_const_t<_Const, _Range>>
9670 && __all_but_last_common<_Const, _Rs...>::value); };
9673 template<
bool _Const,
typename _Range>
9674 struct __all_but_last_common<_Const, _Range>
9675 {
static inline constexpr bool value =
true; };
9677 template<
bool _Const,
typename... _Rs>
9678 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9679 && __all_but_last_common<_Const, _Rs...>::value;
9681 template<
bool _Const,
typename... _Rs>
9682 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9683 && __all_but_last_common<_Const, _Rs...>::value;
9685 template<
typename _Range,
typename... _Rs>
9686 struct __last_is_common
9687 {
static inline constexpr bool value = __last_is_common<_Rs...>::value; };
9689 template<
typename _Range>
9690 struct __last_is_common<_Range>
9691 {
static inline constexpr bool value = common_range<_Range>; };
9694 template<input_range... _Vs>
9695 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9696 class concat_view :
public view_interface<concat_view<_Vs...>>
9698 tuple<_Vs...> _M_views;
9700 template<
bool _Const>
class iterator;
9703 constexpr concat_view() =
default;
9706 concat_view(_Vs... __views)
9707 : _M_views(
std::
move(__views)...)
9710 constexpr iterator<false>
9711 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
9713 iterator<false> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9714 __it.template _M_satisfy<0>();
9718 constexpr iterator<true>
9719 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9721 iterator<true> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9722 __it.template _M_satisfy<0>();
9727 end()
requires (!(__detail::__simple_view<_Vs> && ...))
9729 if constexpr ((semiregular<iterator_t<_Vs>> && ...)
9730 && __detail::__last_is_common<_Vs...>::value)
9732 constexpr auto __n =
sizeof...(_Vs);
9733 return iterator<false>(
this, in_place_index<__n - 1>,
9734 ranges::end(std::get<__n - 1>(_M_views)));
9741 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9743 if constexpr ((semiregular<iterator_t<const _Vs>> && ...)
9744 && __detail::__last_is_common<
const _Vs...>::value)
9746 constexpr auto __n =
sizeof...(_Vs);
9747 return iterator<true>(
this, in_place_index<__n - 1>,
9748 ranges::end(std::get<__n - 1>(_M_views)));
9755 size()
requires (sized_range<_Vs>&&...)
9757 return std::apply([](
auto... __sizes) {
9758 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9759 return (_CT(__sizes) + ...);
9760 }, __detail::__tuple_transform(ranges::size, _M_views));
9764 size() const requires (sized_range<const _Vs>&&...)
9766 return std::apply([](
auto... __sizes) {
9767 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9768 return (_CT(__sizes) + ...);
9769 }, __detail::__tuple_transform(ranges::size, _M_views));
9773 template<
typename... _Rs>
9774 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9778 template<
bool _Const,
typename... _Vs>
9779 struct __concat_view_iter_cat
9782 template<
bool _Const,
typename... _Vs>
9783 requires __detail::__all_forward<_Const, _Vs...>
9784 struct __concat_view_iter_cat<_Const, _Vs...>
9789 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9790 return input_iterator_tag{};
9792 return []<
typename... _Cats>(_Cats... __cats) {
9793 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9794 && __concat_is_random_access<_Const, _Vs...>)
9795 return random_access_iterator_tag{};
9796 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9797 && __concat_is_bidirectional<_Const, _Vs...>)
9798 return bidirectional_iterator_tag{};
9799 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9800 return forward_iterator_tag{};
9802 return input_iterator_tag{};
9803 }(
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9804 ::iterator_category{}...);
9809 template<input_range... _Vs>
9810 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9811 template<
bool _Const>
9812 class concat_view<_Vs...>::iterator
9813 :
public __detail::__concat_view_iter_cat<_Const, _Vs...>
9818 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9819 return random_access_iterator_tag{};
9820 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9821 return bidirectional_iterator_tag{};
9822 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9823 return forward_iterator_tag{};
9825 return input_iterator_tag{};
9829 friend iterator<!_Const>;
9833 using iterator_concept =
decltype(_S_iter_concept());
9834 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9835 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9838 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9840 __maybe_const_t<_Const, concat_view>* _M_parent =
nullptr;
9843 template<
size_t _Nm>
9847 if constexpr (_Nm < (
sizeof...(_Vs) - 1))
9849 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9851 _M_it.template emplace<_Nm + 1>(ranges::begin
9852 (std::get<_Nm + 1>(_M_parent->_M_views)));
9853 _M_satisfy<_Nm + 1>();
9858 template<
size_t _Nm>
9862 if constexpr (_Nm == 0)
9863 --std::get<0>(_M_it);
9866 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9868 _M_it.template emplace<_Nm - 1>(ranges::end
9869 (std::get<_Nm - 1>(_M_parent->_M_views)));
9873 --std::get<_Nm>(_M_it);
9877 template<
size_t _Nm>
9879 _M_advance_fwd(difference_type __offset, difference_type __steps)
9881 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9882 if constexpr (_Nm ==
sizeof...(_Vs) - 1)
9883 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
9886 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9887 if (__offset + __steps < __n_size)
9888 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
9891 _M_it.template emplace<_Nm + 1>(ranges::begin
9892 (std::get<_Nm + 1>(_M_parent->_M_views)));
9893 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9898 template<
size_t _Nm>
9900 _M_advance_bwd(difference_type __offset, difference_type __steps)
9902 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9903 if constexpr (_Nm == 0)
9904 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
9906 if (__offset >= __steps)
9907 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
9910 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9911 _M_it.template emplace<_Nm - 1>(ranges::end
9912 (std::get<_Nm - 1>(_M_parent->_M_views)));
9913 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9921 template<
typename _Fp>
9922 static constexpr auto
9923 _S_invoke_with_runtime_index(_Fp&& __f,
size_t __index)
9925 return [&__f, __index]<
size_t _Idx>(
this auto&& __self) {
9926 if (_Idx == __index)
9927 return __f.template operator()<_Idx>();
9928 if constexpr (_Idx + 1 <
sizeof...(_Vs))
9929 return __self.template operator()<_Idx + 1>();
9930 }.template operator()<0>();
9933 template<
typename _Fp>
9935 _M_invoke_with_runtime_index(_Fp&& __f)
9936 {
return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9938 template<
typename... _Args>
9940 iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9941 requires constructible_from<__base_iter, _Args&&...>
9942 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9946 iterator() =
default;
9949 iterator(iterator<!_Const> __it)
9950 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9951 : _M_parent(__it._M_parent)
9953 _M_invoke_with_runtime_index([
this, &__it]<
size_t _Idx>() {
9954 _M_it.template emplace<_Idx>(std::get<_Idx>(
std::move(__it._M_it)));
9958 constexpr decltype(
auto)
9961 __glibcxx_assert(!_M_it.valueless_by_exception());
9962 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9963 return std::visit([](
auto&& __it) -> reference {
return *__it; }, _M_it);
9969 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
9970 ++std::get<_Idx>(_M_it);
9982 requires __detail::__all_forward<_Const, _Vs...>
9991 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9993 __glibcxx_assert(!_M_it.valueless_by_exception());
9994 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10002 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10004 auto __tmp = *
this;
10009 constexpr iterator&
10010 operator+=(difference_type __n)
10011 requires __detail::__concat_is_random_access<_Const, _Vs...>
10013 __glibcxx_assert(!_M_it.valueless_by_exception());
10014 _M_invoke_with_runtime_index([
this, __n]<
size_t _Idx>() {
10015 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10017 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10019 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10024 constexpr iterator&
10025 operator-=(difference_type __n)
10026 requires __detail::__concat_is_random_access<_Const, _Vs...>
10032 constexpr decltype(
auto)
10033 operator[](difference_type __n)
const
10034 requires __detail::__concat_is_random_access<_Const, _Vs...>
10035 {
return *((*this) + __n); }
10037 friend constexpr bool
10038 operator==(
const iterator& __x,
const iterator& __y)
10039 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10041 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10042 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10043 return __x._M_it == __y._M_it;
10046 friend constexpr bool
10047 operator==(
const iterator& __it, default_sentinel_t)
10049 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10050 constexpr auto __last_idx =
sizeof...(_Vs) - 1;
10051 return (__it._M_it.index() == __last_idx
10052 && (std::get<__last_idx>(__it._M_it)
10053 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10056 friend constexpr bool
10057 operator<(
const iterator& __x,
const iterator& __y)
10058 requires __detail::__all_random_access<_Const, _Vs...>
10059 {
return __x._M_it < __y._M_it; }
10061 friend constexpr bool
10062 operator>(
const iterator& __x,
const iterator& __y)
10063 requires __detail::__all_random_access<_Const, _Vs...>
10064 {
return __x._M_it > __y._M_it; }
10066 friend constexpr bool
10067 operator<=(
const iterator& __x,
const iterator& __y)
10068 requires __detail::__all_random_access<_Const, _Vs...>
10069 {
return __x._M_it <= __y._M_it; }
10071 friend constexpr bool
10072 operator>=(
const iterator& __x,
const iterator& __y)
10073 requires __detail::__all_random_access<_Const, _Vs...>
10074 {
return __x._M_it >= __y._M_it; }
10076 friend constexpr auto
10077 operator<=>(
const iterator& __x,
const iterator& __y)
10078 requires __detail::__all_random_access<_Const, _Vs...>
10079 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10080 {
return __x._M_it <=> __y._M_it; }
10082 friend constexpr iterator
10083 operator+(
const iterator& __it, difference_type __n)
10084 requires __detail::__concat_is_random_access<_Const, _Vs...>
10085 {
return auto(__it) += __n; }
10087 friend constexpr iterator
10088 operator+(difference_type __n,
const iterator& __it)
10089 requires __detail::__concat_is_random_access<_Const, _Vs...>
10090 {
return __it + __n; }
10092 friend constexpr iterator
10093 operator-(
const iterator& __it, difference_type __n)
10094 requires __detail::__concat_is_random_access<_Const, _Vs...>
10095 {
return auto(__it) -= __n; }
10097 friend constexpr difference_type
10098 operator-(
const iterator& __x,
const iterator& __y)
10099 requires __detail::__concat_is_random_access<_Const, _Vs...>
10101 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10102 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> difference_type {
10103 if constexpr (_Ix > _Iy)
10105 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10106 ranges::end(std::get<_Iy>(__y._M_parent
10108 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10110 std::get<_Ix>(__x._M_it));
10111 difference_type __s = 0;
10112 [&]<
size_t _Idx = _Iy + 1>(
this auto&& __self) {
10113 if constexpr (_Idx < _Ix)
10115 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10116 __self.template operator()<_Idx + 1>();
10119 return __dy + __s + __dx;
10121 else if constexpr (_Ix < _Iy)
10122 return -(__y - __x);
10124 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10125 }, __y._M_it.index());
10126 }, __x._M_it.index());
10129 friend constexpr difference_type
10130 operator-(
const iterator& __x, default_sentinel_t)
10131 requires __detail::__concat_is_random_access<_Const, _Vs...>
10132 && __detail::__last_is_common<__maybe_const_t<_Const, _Vs>...>::value
10134 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10135 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10136 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10137 difference_type __s = 0;
10138 [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) {
10139 if constexpr (_Idx <
sizeof...(_Vs))
10141 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10142 __self.template operator()<_Idx + 1>();
10145 return -(__dx + __s);
10146 }, __x._M_it.index());
10149 friend constexpr difference_type
10150 operator-(default_sentinel_t,
const iterator& __x)
10151 requires __detail::__concat_is_random_access<_Const, _Vs...>
10152 && __detail::__last_is_common<__maybe_const_t<_Const, _Vs>...>::value
10155 friend constexpr decltype(
auto)
10156 iter_move(
const iterator& __it)
10158 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10159 return std::visit([](
const auto& __i) -> _Res {
10160 return ranges::iter_move(__i);
10164 friend constexpr void
10165 iter_swap(
const iterator& __x,
const iterator& __y)
10166 requires swappable_with<iter_reference_t<iterator>, iter_reference_t<iterator>>
10167 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10169 std::visit([&]<
typename _Tp,
typename _Up>(
const _Tp& __it1,
const _Up& __it2) {
10170 if constexpr (is_same_v<_Tp, _Up>)
10171 ranges::iter_swap(__it1, __it2);
10173 ranges::swap(*__it1, *__it2);
10174 }, __x._M_it, __y._M_it);
10182 template<
typename... _Ts>
10183 concept __can_concat_view =
requires { concat_view(std::declval<_Ts>()...); };
10188 template<
typename... _Ts>
10189 requires __detail::__can_concat_view<_Ts...>
10191 operator() [[nodiscard]] (_Ts&&... __ts)
const
10193 if constexpr (
sizeof...(_Ts) == 1)
10194 return views::all(std::forward<_Ts>(__ts)...);
10196 return concat_view(std::forward<_Ts>(__ts)...);
10200 inline constexpr _Concat concat;
10206_GLIBCXX_END_NAMESPACE_VERSION
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
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.
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
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.
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)