30#ifndef _GLIBCXX_RANGES
31#define _GLIBCXX_RANGES 1
33#if __cplusplus > 201703L
35#pragma GCC system_header
48#if __cplusplus > 202002L
54#define __glibcxx_want_ranges
55#define __glibcxx_want_ranges_as_const
56#define __glibcxx_want_ranges_as_rvalue
57#define __glibcxx_want_ranges_cartesian_product
58#define __glibcxx_want_ranges_chunk
59#define __glibcxx_want_ranges_chunk_by
60#define __glibcxx_want_ranges_enumerate
61#define __glibcxx_want_ranges_iota
62#define __glibcxx_want_ranges_join_with
63#define __glibcxx_want_ranges_repeat
64#define __glibcxx_want_ranges_slide
65#define __glibcxx_want_ranges_stride
66#define __glibcxx_want_ranges_to_container
67#define __glibcxx_want_ranges_zip
70#ifdef __glibcxx_generator
71# include <bits/elements_of.h>
80namespace std _GLIBCXX_VISIBILITY(default)
82_GLIBCXX_BEGIN_NAMESPACE_VERSION
97 template<
typename _Tp>
requires is_object_v<_Tp>
99 :
public view_interface<empty_view<_Tp>>
102 static constexpr _Tp*
begin() noexcept {
return nullptr; }
103 static constexpr _Tp*
end() noexcept {
return nullptr; }
104 static constexpr _Tp*
data() noexcept {
return nullptr; }
105 static constexpr size_t size() noexcept {
return 0; }
106 static constexpr bool empty() noexcept {
return true; }
109 template<
typename _Tp>
110 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> =
true;
114#if __cpp_lib_ranges >= 202207L
116 template<
typename _Tp>
117 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
119 template<
typename _Tp>
120 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
123 template<__boxable _Tp>
124 struct __box : std::optional<_Tp>
126 using std::optional<_Tp>::optional;
130 noexcept(is_nothrow_default_constructible_v<_Tp>)
131 requires default_initializable<_Tp>
132 :
std::optional<_Tp>{std::in_place}
135 __box(
const __box&) =
default;
136 __box(__box&&) =
default;
138 using std::optional<_Tp>::operator=;
144 operator=(
const __box& __that)
145 noexcept(is_nothrow_copy_constructible_v<_Tp>)
146 requires (!copyable<_Tp>) && copy_constructible<_Tp>
151 this->emplace(*__that);
159 operator=(__box&& __that)
160 noexcept(is_nothrow_move_constructible_v<_Tp>)
161 requires (!movable<_Tp>)
174 template<
typename _Tp>
175 concept __boxable_copyable
176 = copy_constructible<_Tp>
177 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
178 && is_nothrow_copy_constructible_v<_Tp>));
179 template<
typename _Tp>
180 concept __boxable_movable
181 = (!copy_constructible<_Tp>)
182 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
188 template<__boxable _Tp>
189 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
193 [[no_unique_address]] _Tp _M_value = _Tp();
196 __box()
requires default_initializable<_Tp> = default;
199 __box(const _Tp& __t)
200 noexcept(is_nothrow_copy_constructible_v<_Tp>)
201 requires copy_constructible<_Tp>
207 noexcept(is_nothrow_move_constructible_v<_Tp>)
211 template<
typename... _Args>
212 requires constructible_from<_Tp, _Args...>
214 __box(in_place_t, _Args&&... __args)
215 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
219 __box(
const __box&) =
default;
220 __box(__box&&) =
default;
221 __box& operator=(
const __box&)
requires copyable<_Tp> =
default;
222 __box& operator=(__box&&)
requires movable<_Tp> = default;
227 operator=(const __box& __that) noexcept
228 requires (!copyable<_Tp>) && copy_constructible<_Tp>
230 static_assert(is_nothrow_copy_constructible_v<_Tp>);
241 operator=(__box&& __that)
noexcept
242 requires (!movable<_Tp>)
244 static_assert(is_nothrow_move_constructible_v<_Tp>);
254 has_value() const noexcept
269 constexpr const _Tp&&
274 operator->() noexcept
278 operator->() const noexcept
284#if __cpp_lib_ranges >= 202207L
285 template<move_constructible _Tp>
287 template<copy_constructible _Tp>
289 requires is_object_v<_Tp>
290 class single_view :
public view_interface<single_view<_Tp>>
293 single_view()
requires default_initializable<_Tp> = default;
296 single_view(const _Tp& __t)
297 noexcept(is_nothrow_copy_constructible_v<_Tp>)
298 requires copy_constructible<_Tp>
303 single_view(_Tp&& __t)
304 noexcept(is_nothrow_move_constructible_v<_Tp>)
310 template<
typename... _Args>
311 requires constructible_from<_Tp, _Args...>
313 single_view(in_place_t, _Args&&... __args)
314 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
315 : _M_value{in_place,
std::
forward<_Args>(__args)...}
323 begin() const noexcept
328 {
return data() + 1; }
332 {
return data() + 1; }
334 static constexpr size_t
340 {
return _M_value.operator->(); }
343 data() const noexcept
344 {
return _M_value.operator->(); }
347 [[no_unique_address]] __detail::__box<_Tp> _M_value;
350 template<
typename _Tp>
351 single_view(_Tp) -> single_view<_Tp>;
355 template<
typename _Wp>
356 constexpr auto __to_signed_like(_Wp __w)
noexcept
358 if constexpr (!integral<_Wp>)
359 return iter_difference_t<_Wp>();
360 else if constexpr (
sizeof(iter_difference_t<_Wp>) >
sizeof(_Wp))
361 return iter_difference_t<_Wp>(__w);
362 else if constexpr (
sizeof(ptrdiff_t) >
sizeof(_Wp))
363 return ptrdiff_t(__w);
364 else if constexpr (
sizeof(
long long) >
sizeof(_Wp))
365 return (
long long)(__w);
366#ifdef __SIZEOF_INT128__
367 else if constexpr (__SIZEOF_INT128__ >
sizeof(_Wp))
368 return __int128(__w);
371 return __max_diff_type(__w);
374 template<
typename _Wp>
375 using __iota_diff_t =
decltype(__to_signed_like(std::declval<_Wp>()));
377 template<
typename _It>
378 concept __decrementable = incrementable<_It>
381 { --__i } -> same_as<_It&>;
382 { __i-- } -> same_as<_It>;
385 template<
typename _It>
386 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
387 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
389 { __i += __n } -> same_as<_It&>;
390 { __i -= __n } -> same_as<_It&>;
394 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
397 template<
typename _Winc>
398 struct __iota_view_iter_cat
401 template<incrementable _Winc>
402 struct __iota_view_iter_cat<_Winc>
403 {
using iterator_category = input_iterator_tag; };
406 template<weakly_incrementable _Winc,
407 semiregular _Bound = unreachable_sentinel_t>
408 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
410 class iota_view :
public view_interface<iota_view<_Winc, _Bound>>
415 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
421 using namespace __detail;
422 if constexpr (__advanceable<_Winc>)
423 return random_access_iterator_tag{};
424 else if constexpr (__decrementable<_Winc>)
425 return bidirectional_iterator_tag{};
426 else if constexpr (incrementable<_Winc>)
427 return forward_iterator_tag{};
429 return input_iterator_tag{};
433 using iterator_concept =
decltype(_S_iter_concept());
435 using value_type = _Winc;
436 using difference_type = __detail::__iota_diff_t<_Winc>;
438 _Iterator()
requires default_initializable<_Winc> = default;
441 _Iterator(_Winc __value)
442 : _M_value(__value) { }
445 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
460 operator++(
int)
requires incrementable<_Winc>
468 operator--()
requires __detail::__decrementable<_Winc>
475 operator--(
int)
requires __detail::__decrementable<_Winc>
483 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
485 using __detail::__is_integer_like;
486 using __detail::__is_signed_integer_like;
487 if constexpr (__is_integer_like<_Winc>
488 && !__is_signed_integer_like<_Winc>)
490 if (__n >= difference_type(0))
491 _M_value +=
static_cast<_Winc
>(__n);
493 _M_value -=
static_cast<_Winc
>(-__n);
501 operator-=(difference_type __n)
requires __detail::__advanceable<_Winc>
503 using __detail::__is_integer_like;
504 using __detail::__is_signed_integer_like;
505 if constexpr (__is_integer_like<_Winc>
506 && !__is_signed_integer_like<_Winc>)
508 if (__n >= difference_type(0))
509 _M_value -=
static_cast<_Winc
>(__n);
511 _M_value +=
static_cast<_Winc
>(-__n);
519 operator[](difference_type __n)
const
520 requires __detail::__advanceable<_Winc>
521 {
return _Winc(_M_value + __n); }
523 friend constexpr bool
524 operator==(
const _Iterator& __x,
const _Iterator& __y)
525 requires equality_comparable<_Winc>
526 {
return __x._M_value == __y._M_value; }
528 friend constexpr bool
529 operator<(
const _Iterator& __x,
const _Iterator& __y)
530 requires totally_ordered<_Winc>
531 {
return __x._M_value < __y._M_value; }
533 friend constexpr bool
534 operator>(
const _Iterator& __x,
const _Iterator& __y)
535 requires totally_ordered<_Winc>
536 {
return __y < __x; }
538 friend constexpr bool
539 operator<=(
const _Iterator& __x,
const _Iterator& __y)
540 requires totally_ordered<_Winc>
541 {
return !(__y < __x); }
543 friend constexpr bool
544 operator>=(
const _Iterator& __x,
const _Iterator& __y)
545 requires totally_ordered<_Winc>
546 {
return !(__x < __y); }
548#ifdef __cpp_lib_three_way_comparison
549 friend constexpr auto
550 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
551 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
552 {
return __x._M_value <=> __y._M_value; }
555 friend constexpr _Iterator
556 operator+(_Iterator __i, difference_type __n)
557 requires __detail::__advanceable<_Winc>
563 friend constexpr _Iterator
564 operator+(difference_type __n, _Iterator __i)
565 requires __detail::__advanceable<_Winc>
566 {
return __i += __n; }
568 friend constexpr _Iterator
569 operator-(_Iterator __i, difference_type __n)
570 requires __detail::__advanceable<_Winc>
576 friend constexpr difference_type
577 operator-(
const _Iterator& __x,
const _Iterator& __y)
578 requires __detail::__advanceable<_Winc>
580 using __detail::__is_integer_like;
581 using __detail::__is_signed_integer_like;
582 using _Dt = difference_type;
583 if constexpr (__is_integer_like<_Winc>)
585 if constexpr (__is_signed_integer_like<_Winc>)
586 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
588 return (__y._M_value > __x._M_value)
589 ? _Dt(-_Dt(__y._M_value - __x._M_value))
590 : _Dt(__x._M_value - __y._M_value);
593 return __x._M_value - __y._M_value;
597 _Winc _M_value = _Winc();
607 _M_equal(
const _Iterator& __x)
const
608 {
return __x._M_value == _M_bound; }
611 _M_distance_from(
const _Iterator& __x)
const
612 {
return _M_bound - __x._M_value; }
614 _Bound _M_bound = _Bound();
617 _Sentinel() =
default;
620 _Sentinel(_Bound __bound)
621 : _M_bound(__bound) { }
623 friend constexpr bool
624 operator==(
const _Iterator& __x,
const _Sentinel& __y)
625 {
return __y._M_equal(__x); }
627 friend constexpr iter_difference_t<_Winc>
628 operator-(
const _Iterator& __x,
const _Sentinel& __y)
629 requires sized_sentinel_for<_Bound, _Winc>
630 {
return -__y._M_distance_from(__x); }
632 friend constexpr iter_difference_t<_Winc>
633 operator-(
const _Sentinel& __x,
const _Iterator& __y)
634 requires sized_sentinel_for<_Bound, _Winc>
635 {
return __x._M_distance_from(__y); }
640 _Winc _M_value = _Winc();
641 [[no_unique_address]] _Bound _M_bound = _Bound();
644 iota_view()
requires default_initializable<_Winc> = default;
647 iota_view(_Winc __value)
652 iota_view(type_identity_t<_Winc> __value,
653 type_identity_t<_Bound> __bound)
654 : _M_value(__value), _M_bound(__bound)
656 if constexpr (totally_ordered_with<_Winc, _Bound>)
657 __glibcxx_assert(
bool(__value <= __bound) );
661 iota_view(_Iterator __first, _Iterator __last)
662 requires same_as<_Winc, _Bound>
663 : iota_view(__first._M_value, __last._M_value)
667 iota_view(_Iterator __first, unreachable_sentinel_t __last)
668 requires same_as<_Bound, unreachable_sentinel_t>
669 : iota_view(__first._M_value, __last)
673 iota_view(_Iterator __first, _Sentinel __last)
674 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
675 : iota_view(__first._M_value, __last._M_bound)
679 begin()
const {
return _Iterator{_M_value}; }
684 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
685 return unreachable_sentinel;
687 return _Sentinel{_M_bound};
691 end() const requires same_as<_Winc, _Bound>
692 {
return _Iterator{_M_bound}; }
696 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
697 || (integral<_Winc> && integral<_Bound>)
698 || sized_sentinel_for<_Bound, _Winc>
700 using __detail::__is_integer_like;
701 using __detail::__to_unsigned_like;
702 if constexpr (integral<_Winc> && integral<_Bound>)
705 return _Up(_M_bound) - _Up(_M_value);
707 else if constexpr (__is_integer_like<_Winc>)
708 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
710 return __to_unsigned_like(_M_bound - _M_value);
714 template<
typename _Winc,
typename _Bound>
715 requires (!__detail::__is_integer_like<_Winc>
716 || !__detail::__is_integer_like<_Bound>
717 || (__detail::__is_signed_integer_like<_Winc>
718 == __detail::__is_signed_integer_like<_Bound>))
719 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
721 template<
typename _Winc,
typename _Bound>
722 inline constexpr bool
723 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
727 template<
typename _Tp>
728 inline constexpr empty_view<_Tp>
empty{};
732 template<
typename _Tp>
733 concept __can_single_view
734 =
requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
739 template<__detail::__can_single_view _Tp>
741 operator() [[nodiscard]] (_Tp&& __e)
const
742 noexcept(
noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
743 {
return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
746 inline constexpr _Single single{};
750 template<
typename... _Args>
751 concept __can_iota_view =
requires { iota_view(std::declval<_Args>()...); };
756 template<__detail::__can_iota_view _Tp>
758 operator() [[nodiscard]] (_Tp&& __e)
const
759 {
return iota_view(std::forward<_Tp>(__e)); }
761 template<
typename _Tp,
typename _Up>
762 requires __detail::__can_iota_view<_Tp, _Up>
764 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
765 {
return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
768 inline constexpr _Iota
iota{};
774 template<
typename _Val,
typename _CharT,
typename _Traits>
775 concept __stream_extractable
776 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
779 template<movable _Val,
typename _CharT,
780 typename _Traits = char_traits<_CharT>>
781 requires default_initializable<_Val>
782 && __detail::__stream_extractable<_Val, _CharT, _Traits>
783 class basic_istream_view
784 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
788 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
795 *_M_stream >> _M_object;
796 return _Iterator{
this};
799 constexpr default_sentinel_t
804 basic_istream<_CharT, _Traits>* _M_stream;
805 _Val _M_object = _Val();
810 using iterator_concept = input_iterator_tag;
811 using difference_type = ptrdiff_t;
812 using value_type = _Val;
815 _Iterator(basic_istream_view* __parent) noexcept
816 : _M_parent(__parent)
819 _Iterator(
const _Iterator&) =
delete;
820 _Iterator(_Iterator&&) =
default;
821 _Iterator& operator=(
const _Iterator&) =
delete;
822 _Iterator& operator=(_Iterator&&) =
default;
827 *_M_parent->_M_stream >> _M_parent->_M_object;
837 {
return _M_parent->_M_object; }
840 operator==(
const _Iterator& __x, default_sentinel_t)
841 {
return __x._M_at_end(); }
844 basic_istream_view* _M_parent;
848 {
return !*_M_parent->_M_stream; }
854 template<
typename _Val>
855 using istream_view = basic_istream_view<_Val, char>;
857 template<
typename _Val>
858 using wistream_view = basic_istream_view<_Val, wchar_t>;
864 template<
typename _Tp,
typename _Up>
865 concept __can_istream_view =
requires (_Up __e) {
866 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
870 template<
typename _Tp>
873 template<
typename _CharT,
typename _Traits>
875 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
876 requires __detail::__can_istream_view<_Tp, remove_reference_t<
decltype(__e)>>
877 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
880 template<
typename _Tp>
881 inline constexpr _Istream<_Tp>
istream;
895 template<
bool _Present,
typename _Tp>
896 using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;
899 template<
bool _Const,
typename _Tp>
900 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
905using __detail::__maybe_const_t;
907namespace views::__adaptor
910 template<
typename _Adaptor,
typename... _Args>
911 concept __adaptor_invocable
912 =
requires { std::declval<_Adaptor>()(declval<_Args>()...); };
916 template<
typename _Adaptor,
typename... _Args>
917 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
918 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
919 && (constructible_from<decay_t<_Args>, _Args> && ...);
921 template<
typename _Adaptor,
typename... _Args>
924 template<
typename _Lhs,
typename _Rhs>
932 template<
typename _Derived>
933 struct _RangeAdaptorClosure
936 template<
typename _Tp,
typename _Up>
937 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
938 void __is_range_adaptor_closure_fn
939 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
941 template<
typename _Tp>
942 concept __is_range_adaptor_closure
943 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
945#pragma GCC diagnostic push
946#pragma GCC diagnostic ignored "-Wdangling-reference"
948 template<
typename _Self,
typename _Range>
949 requires __is_range_adaptor_closure<_Self>
950 && __adaptor_invocable<_Self, _Range>
953 {
return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
957 template<
typename _Lhs,
typename _Rhs>
958 requires __is_range_adaptor_closure<_Lhs>
959 && __is_range_adaptor_closure<_Rhs>
963 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
964 std::forward<_Rhs>(__rhs)};
966#pragma GCC diagnostic pop
979 template<
typename _Derived>
984 template<
typename... _Args>
985 requires __adaptor_partial_app_viable<_Derived, _Args...>
987 operator()(_Args&&... __args)
const
989 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
996 template<
typename _Adaptor>
997 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1001 template<
typename _Adaptor,
typename... _Args>
1002 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1003 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1007 template<
typename _Adaptor,
typename... _Args>
1008 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1010 tuple<_Args...> _M_args;
1014 template<
typename... _Ts>
1016 _Partial(
int, _Ts&&... __args)
1022#if __cpp_explicit_this_parameter
1023 template<
typename _Self,
typename _Range>
1024 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1026 operator()(
this _Self&& __self, _Range&& __r)
1028 auto __forwarder = [&__r] (
auto&&... __args) {
1029 return _Adaptor{}(std::forward<_Range>(__r),
1030 std::forward<decltype(__args)>(__args)...);
1032 return std::apply(__forwarder, std::forward<_Self>(__self)._M_args);
1035 template<
typename _Range>
1036 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1038 operator()(_Range&& __r)
const &
1040 auto __forwarder = [&__r] (
const auto&... __args) {
1041 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1043 return std::apply(__forwarder, _M_args);
1046 template<
typename _Range>
1047 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1049 operator()(_Range&& __r) &&
1051 auto __forwarder = [&__r] (
auto&... __args) {
1052 return _Adaptor{}(std::forward<_Range>(__r),
std::move(__args)...);
1054 return std::apply(__forwarder, _M_args);
1057 template<
typename _Range>
1059 operator()(_Range&& __r)
const && =
delete;
1065 template<
typename _Adaptor,
typename _Arg>
1066 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1070 template<
typename _Tp>
1072 _Partial(
int, _Tp&& __arg)
1076#if __cpp_explicit_this_parameter
1077 template<
typename _Self,
typename _Range>
1078 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1080 operator()(
this _Self&& __self, _Range&& __r)
1081 {
return _Adaptor{}(std::forward<_Range>(__r), std::forward<_Self>(__self)._M_arg); }
1083 template<
typename _Range>
1084 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1086 operator()(_Range&& __r)
const &
1087 {
return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1089 template<
typename _Range>
1090 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1092 operator()(_Range&& __r) &&
1093 {
return _Adaptor{}(std::forward<_Range>(__r),
std::move(_M_arg)); }
1095 template<
typename _Range>
1097 operator()(_Range&& __r)
const && =
delete;
1105 template<
typename _Adaptor,
typename... _Args>
1106 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1107 && (is_trivially_copyable_v<_Args> && ...)
1108 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1110 tuple<_Args...> _M_args;
1112 template<
typename... _Ts>
1114 _Partial(
int, _Ts&&... __args)
1120 template<
typename _Range>
1121 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1123 operator()(_Range&& __r)
const
1125 auto __forwarder = [&__r] (
const auto&... __args) {
1126 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1128 return std::apply(__forwarder, _M_args);
1131 static constexpr bool _S_has_simple_call_op =
true;
1136 template<
typename _Adaptor,
typename _Arg>
1137 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1138 && is_trivially_copyable_v<_Arg>
1139 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1143 template<
typename _Tp>
1145 _Partial(
int, _Tp&& __arg)
1149 template<
typename _Range>
1150 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1152 operator()(_Range&& __r)
const
1153 {
return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1155 static constexpr bool _S_has_simple_call_op =
true;
1158 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1159 concept __pipe_invocable
1160 =
requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1164 template<
typename _Lhs,
typename _Rhs>
1165 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1167 [[no_unique_address]] _Lhs _M_lhs;
1168 [[no_unique_address]] _Rhs _M_rhs;
1170 template<
typename _Tp,
typename _Up>
1172 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1178#if __cpp_explicit_this_parameter
1179 template<
typename _Self,
typename _Range>
1180 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1182 operator()(
this _Self&& __self, _Range&& __r)
1184 return (std::forward<_Self>(__self)._M_rhs
1185 (std::forward<_Self>(__self)._M_lhs
1186 (std::forward<_Range>(__r))));
1189 template<
typename _Range>
1190 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1192 operator()(_Range&& __r)
const &
1193 {
return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1195 template<
typename _Range>
1196 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1198 operator()(_Range&& __r) &&
1201 template<
typename _Range>
1203 operator()(_Range&& __r)
const && =
delete;
1211 template<
typename _Lhs,
typename _Rhs>
1212 requires __closure_has_simple_call_op<_Lhs>
1213 && __closure_has_simple_call_op<_Rhs>
1214 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1216 [[no_unique_address]] _Lhs _M_lhs;
1217 [[no_unique_address]] _Rhs _M_rhs;
1219 template<
typename _Tp,
typename _Up>
1221 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1225 template<
typename _Range>
1226 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1228 operator()(_Range&& __r)
const
1229 {
return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1231 static constexpr bool _S_has_simple_call_op =
true;
1235#if __cpp_lib_ranges >= 202202L
1237 template<
typename _Derived>
1238 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1239 class range_adaptor_closure
1240 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1244 template<range _Range>
requires is_object_v<_Range>
1245 class ref_view :
public view_interface<ref_view<_Range>>
1250 static void _S_fun(_Range&);
1251 static void _S_fun(_Range&&) =
delete;
1254 template<__detail::__different_from<ref_view> _Tp>
1255 requires convertible_to<_Tp, _Range&>
1256 &&
requires { _S_fun(declval<_Tp>()); }
1259 noexcept(
noexcept(
static_cast<_Range&
>(std::declval<_Tp>())))
1267 constexpr iterator_t<_Range>
1269 {
return ranges::begin(*_M_r); }
1271 constexpr sentinel_t<_Range>
1273 {
return ranges::end(*_M_r); }
1276 empty() const requires requires { ranges::empty(*_M_r); }
1277 {
return ranges::empty(*_M_r); }
1280 size() const requires sized_range<_Range>
1281 {
return ranges::size(*_M_r); }
1284 data() const requires contiguous_range<_Range>
1285 {
return ranges::data(*_M_r); }
1288 template<
typename _Range>
1289 ref_view(_Range&) -> ref_view<_Range>;
1291 template<
typename _Tp>
1292 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1294 template<range _Range>
1295 requires movable<_Range>
1296 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1297 class owning_view : public view_interface<owning_view<_Range>>
1300 _Range _M_r = _Range();
1303 owning_view()
requires default_initializable<_Range> = default;
1306 owning_view(_Range&& __t)
1307 noexcept(is_nothrow_move_constructible_v<_Range>)
1311 owning_view(owning_view&&) =
default;
1312 owning_view& operator=(owning_view&&) =
default;
1318 constexpr const _Range&
1319 base() const& noexcept
1326 constexpr const _Range&&
1327 base() const&& noexcept
1330 constexpr iterator_t<_Range>
1332 {
return ranges::begin(_M_r); }
1334 constexpr sentinel_t<_Range>
1336 {
return ranges::end(_M_r); }
1339 begin() const requires range<const _Range>
1340 {
return ranges::begin(_M_r); }
1343 end() const requires range<const _Range>
1344 {
return ranges::end(_M_r); }
1347 empty()
requires requires { ranges::empty(_M_r); }
1348 {
return ranges::empty(_M_r); }
1351 empty() const requires requires { ranges::empty(_M_r); }
1352 {
return ranges::empty(_M_r); }
1355 size()
requires sized_range<_Range>
1356 {
return ranges::size(_M_r); }
1359 size() const requires sized_range<const _Range>
1360 {
return ranges::size(_M_r); }
1363 data()
requires contiguous_range<_Range>
1364 {
return ranges::data(_M_r); }
1367 data() const requires contiguous_range<const _Range>
1368 {
return ranges::data(_M_r); }
1371 template<
typename _Tp>
1372 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1373 = enable_borrowed_range<_Tp>;
1379 template<
typename _Range>
1380 concept __can_ref_view =
requires { ref_view{std::declval<_Range>()}; };
1382 template<
typename _Range>
1383 concept __can_owning_view =
requires { owning_view{std::declval<_Range>()}; };
1386 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1388 template<
typename _Range>
1389 static constexpr bool
1392 if constexpr (view<decay_t<_Range>>)
1393 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1394 else if constexpr (__detail::__can_ref_view<_Range>)
1397 return noexcept(owning_view{std::declval<_Range>()});
1400 template<viewable_range _Range>
1401 requires view<decay_t<_Range>>
1402 || __detail::__can_ref_view<_Range>
1403 || __detail::__can_owning_view<_Range>
1405 operator() [[nodiscard]] (_Range&& __r)
const
1406 noexcept(_S_noexcept<_Range>())
1408 if constexpr (view<decay_t<_Range>>)
1409 return std::forward<_Range>(__r);
1410 else if constexpr (__detail::__can_ref_view<_Range>)
1411 return ref_view{std::forward<_Range>(__r)};
1413 return owning_view{std::forward<_Range>(__r)};
1416 static constexpr bool _S_has_simple_call_op =
true;
1419 inline constexpr _All all;
1421 template<viewable_range _Range>
1422 using all_t =
decltype(all(std::declval<_Range>()));
1427 template<
typename _Tp>
1428 struct __non_propagating_cache
1436 template<
typename _Tp>
1437 requires is_object_v<_Tp>
1438 struct __non_propagating_cache<_Tp>
1439 :
protected _Optional_base<_Tp>
1441 __non_propagating_cache() =
default;
1444 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1448 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1449 { __other._M_reset(); }
1451 constexpr __non_propagating_cache&
1452 operator=(
const __non_propagating_cache& __other)
noexcept
1459 constexpr __non_propagating_cache&
1460 operator=(__non_propagating_cache&& __other)
noexcept
1467 constexpr __non_propagating_cache&
1468 operator=(_Tp __val)
1471 this->_M_payload._M_construct(
std::move(__val));
1476 operator bool() const noexcept
1477 {
return this->_M_is_engaged(); }
1481 {
return this->_M_get(); }
1483 constexpr const _Tp&
1485 {
return this->_M_get(); }
1487 template<
typename _Iter>
1489 _M_emplace_deref(
const _Iter& __i)
1492 auto __f = [] (
auto& __x) {
return *__x; };
1493 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1494 return this->_M_get();
1498 template<range _Range>
1499 struct _CachedPosition
1502 _M_has_value()
const
1505 constexpr iterator_t<_Range>
1506 _M_get(
const _Range&)
const
1508 __glibcxx_assert(
false);
1509 __builtin_unreachable();
1513 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1517 template<forward_range _Range>
1518 struct _CachedPosition<_Range>
1519 :
protected __non_propagating_cache<iterator_t<_Range>>
1522 _M_has_value()
const
1523 {
return this->_M_is_engaged(); }
1525 constexpr iterator_t<_Range>
1526 _M_get(
const _Range&)
const
1528 __glibcxx_assert(_M_has_value());
1533 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1535 __glibcxx_assert(!_M_has_value());
1538 this->_M_payload._M_engaged =
true;
1542 template<random_access_range _Range>
1543 requires (
sizeof(range_difference_t<_Range>)
1544 <=
sizeof(iterator_t<_Range>))
1545 struct _CachedPosition<_Range>
1548 range_difference_t<_Range> _M_offset = -1;
1551 _CachedPosition() =
default;
1554 _CachedPosition(
const _CachedPosition&) =
default;
1557 _CachedPosition(_CachedPosition&& __other)
noexcept
1560 constexpr _CachedPosition&
1561 operator=(
const _CachedPosition&) =
default;
1563 constexpr _CachedPosition&
1564 operator=(_CachedPosition&& __other)
noexcept
1567 _M_offset = __other._M_offset;
1568 __other._M_offset = -1;
1573 _M_has_value()
const
1574 {
return _M_offset >= 0; }
1576 constexpr iterator_t<_Range>
1577 _M_get(_Range& __r)
const
1579 __glibcxx_assert(_M_has_value());
1580 return ranges::begin(__r) + _M_offset;
1584 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1586 __glibcxx_assert(!_M_has_value());
1587 _M_offset = __it - ranges::begin(__r);
1594 template<
typename _Base>
1595 struct __filter_view_iter_cat
1598 template<forward_range _Base>
1599 struct __filter_view_iter_cat<_Base>
1605 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1606 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1607 return bidirectional_iterator_tag{};
1608 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1609 return forward_iterator_tag{};
1614 using iterator_category =
decltype(_S_iter_cat());
1618 template<input_range _Vp,
1619 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1620 requires view<_Vp> && is_object_v<_Pred>
1621 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1626 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1629 static constexpr auto
1632 if constexpr (bidirectional_range<_Vp>)
1633 return bidirectional_iterator_tag{};
1634 else if constexpr (forward_range<_Vp>)
1635 return forward_iterator_tag{};
1637 return input_iterator_tag{};
1642 using _Vp_iter = iterator_t<_Vp>;
1644 _Vp_iter _M_current = _Vp_iter();
1645 filter_view* _M_parent =
nullptr;
1648 using iterator_concept =
decltype(_S_iter_concept());
1650 using value_type = range_value_t<_Vp>;
1651 using difference_type = range_difference_t<_Vp>;
1653 _Iterator()
requires default_initializable<_Vp_iter> = default;
1656 _Iterator(filter_view* __parent, _Vp_iter __current)
1657 : _M_current(
std::move(__current)),
1661 constexpr const _Vp_iter&
1662 base() const & noexcept
1663 {
return _M_current; }
1669 constexpr range_reference_t<_Vp>
1671 {
return *_M_current; }
1675 requires __detail::__has_arrow<_Vp_iter>
1676 && copyable<_Vp_iter>
1677 {
return _M_current; }
1679 constexpr _Iterator&
1682 _M_current = ranges::find_if(
std::move(++_M_current),
1683 ranges::end(_M_parent->_M_base),
1684 std::ref(*_M_parent->_M_pred));
1693 operator++(
int)
requires forward_range<_Vp>
1700 constexpr _Iterator&
1701 operator--()
requires bidirectional_range<_Vp>
1710 operator--(
int)
requires bidirectional_range<_Vp>
1717 friend constexpr bool
1718 operator==(
const _Iterator& __x,
const _Iterator& __y)
1719 requires equality_comparable<_Vp_iter>
1720 {
return __x._M_current == __y._M_current; }
1722 friend constexpr range_rvalue_reference_t<_Vp>
1723 iter_move(
const _Iterator& __i)
1724 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1725 {
return ranges::iter_move(__i._M_current); }
1727 friend constexpr void
1728 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1729 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1730 requires indirectly_swappable<_Vp_iter>
1731 { ranges::iter_swap(__x._M_current, __y._M_current); }
1737 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1740 __equal(
const _Iterator& __i)
const
1741 {
return __i._M_current == _M_end; }
1744 _Sentinel() =
default;
1747 _Sentinel(filter_view* __parent)
1748 : _M_end(ranges::
end(__parent->_M_base))
1751 constexpr sentinel_t<_Vp>
1755 friend constexpr bool
1756 operator==(
const _Iterator& __x,
const _Sentinel& __y)
1757 {
return __y.__equal(__x); }
1760 _Vp _M_base = _Vp();
1761 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1762 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1765 filter_view()
requires (default_initializable<_Vp>
1766 && default_initializable<_Pred>)
1770 filter_view(_Vp __base, _Pred __pred)
1775 base() const& requires copy_constructible<_Vp>
1782 constexpr const _Pred&
1784 {
return *_M_pred; }
1789 if (_M_cached_begin._M_has_value())
1790 return {
this, _M_cached_begin._M_get(_M_base)};
1792 __glibcxx_assert(_M_pred.has_value());
1793 auto __it = ranges::find_if(ranges::begin(_M_base),
1794 ranges::end(_M_base),
1795 std::ref(*_M_pred));
1796 _M_cached_begin._M_set(_M_base, __it);
1803 if constexpr (common_range<_Vp>)
1804 return _Iterator{
this, ranges::end(_M_base)};
1806 return _Sentinel{
this};
1810 template<
typename _Range,
typename _Pred>
1811 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1817 template<
typename _Range,
typename _Pred>
1818 concept __can_filter_view
1819 =
requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1822 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1824 template<viewable_range _Range,
typename _Pred>
1825 requires __detail::__can_filter_view<_Range, _Pred>
1827 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1829 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1832 using _RangeAdaptor<_Filter>::operator();
1833 static constexpr int _S_arity = 2;
1834 static constexpr bool _S_has_simple_extra_args =
true;
1837 inline constexpr _Filter filter;
1840#if __cpp_lib_ranges >= 202207L
1841 template<input_range _Vp, move_constructible _Fp>
1843 template<input_range _Vp, copy_constructible _Fp>
1845 requires view<_Vp> && is_object_v<_Fp>
1846 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1847 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1848 range_reference_t<_Vp>>>
1849 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
1852 template<
bool _Const>
1853 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1855 template<
bool _Const>
1859 template<
bool _Const>
1860 requires forward_range<_Base<_Const>>
1861 struct __iter_cat<_Const>
1867 using _Base = transform_view::_Base<_Const>;
1868 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1869 if constexpr (is_lvalue_reference_v<_Res>)
1872 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1873 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1874 return random_access_iterator_tag{};
1879 return input_iterator_tag{};
1882 using iterator_category =
decltype(_S_iter_cat());
1885 template<
bool _Const>
1888 template<
bool _Const>
1889 struct _Iterator : __iter_cat<_Const>
1892 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1893 using _Base = transform_view::_Base<_Const>;
1898 if constexpr (random_access_range<_Base>)
1899 return random_access_iterator_tag{};
1900 else if constexpr (bidirectional_range<_Base>)
1901 return bidirectional_iterator_tag{};
1902 else if constexpr (forward_range<_Base>)
1903 return forward_iterator_tag{};
1905 return input_iterator_tag{};
1908 using _Base_iter = iterator_t<_Base>;
1910 _Base_iter _M_current = _Base_iter();
1911 _Parent* _M_parent =
nullptr;
1914 using iterator_concept =
decltype(_S_iter_concept());
1917 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1918 using difference_type = range_difference_t<_Base>;
1920 _Iterator()
requires default_initializable<_Base_iter> = default;
1923 _Iterator(_Parent* __parent, _Base_iter __current)
1924 : _M_current(
std::move(__current)),
1929 _Iterator(_Iterator<!_Const> __i)
1931 && convertible_to<iterator_t<_Vp>, _Base_iter>
1932 : _M_current(
std::move(__i._M_current)), _M_parent(__i._M_parent)
1935 constexpr const _Base_iter&
1936 base() const & noexcept
1937 {
return _M_current; }
1939 constexpr _Base_iter
1943 constexpr decltype(
auto)
1945 noexcept(
noexcept(
std::__invoke(*_M_parent->_M_fun, *_M_current)))
1948 constexpr _Iterator&
1960 operator++(
int)
requires forward_range<_Base>
1967 constexpr _Iterator&
1968 operator--()
requires bidirectional_range<_Base>
1975 operator--(
int)
requires bidirectional_range<_Base>
1982 constexpr _Iterator&
1983 operator+=(difference_type __n)
requires random_access_range<_Base>
1989 constexpr _Iterator&
1990 operator-=(difference_type __n)
requires random_access_range<_Base>
1996 constexpr decltype(
auto)
1997 operator[](difference_type __n)
const
1998 requires random_access_range<_Base>
1999 {
return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2001 friend constexpr bool
2002 operator==(
const _Iterator& __x,
const _Iterator& __y)
2003 requires equality_comparable<_Base_iter>
2004 {
return __x._M_current == __y._M_current; }
2006 friend constexpr bool
2007 operator<(
const _Iterator& __x,
const _Iterator& __y)
2008 requires random_access_range<_Base>
2009 {
return __x._M_current < __y._M_current; }
2011 friend constexpr bool
2012 operator>(
const _Iterator& __x,
const _Iterator& __y)
2013 requires random_access_range<_Base>
2014 {
return __y < __x; }
2016 friend constexpr bool
2017 operator<=(
const _Iterator& __x,
const _Iterator& __y)
2018 requires random_access_range<_Base>
2019 {
return !(__y < __x); }
2021 friend constexpr bool
2022 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2023 requires random_access_range<_Base>
2024 {
return !(__x < __y); }
2026#ifdef __cpp_lib_three_way_comparison
2027 friend constexpr auto
2028 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2029 requires random_access_range<_Base>
2030 && three_way_comparable<_Base_iter>
2031 {
return __x._M_current <=> __y._M_current; }
2034 friend constexpr _Iterator
2035 operator+(_Iterator __i, difference_type __n)
2036 requires random_access_range<_Base>
2037 {
return {__i._M_parent, __i._M_current + __n}; }
2039 friend constexpr _Iterator
2040 operator+(difference_type __n, _Iterator __i)
2041 requires random_access_range<_Base>
2042 {
return {__i._M_parent, __i._M_current + __n}; }
2044 friend constexpr _Iterator
2045 operator-(_Iterator __i, difference_type __n)
2046 requires random_access_range<_Base>
2047 {
return {__i._M_parent, __i._M_current - __n}; }
2051 friend constexpr difference_type
2052 operator-(
const _Iterator& __x,
const _Iterator& __y)
2053 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2054 {
return __x._M_current - __y._M_current; }
2056 friend constexpr decltype(
auto)
2057 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2059 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2065 friend _Iterator<!_Const>;
2066 template<
bool>
friend struct _Sentinel;
2069 template<
bool _Const>
2073 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2074 using _Base = transform_view::_Base<_Const>;
2076 template<
bool _Const2>
2078 __distance_from(
const _Iterator<_Const2>& __i)
const
2079 {
return _M_end - __i._M_current; }
2081 template<
bool _Const2>
2083 __equal(
const _Iterator<_Const2>& __i)
const
2084 {
return __i._M_current == _M_end; }
2086 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2089 _Sentinel() =
default;
2092 _Sentinel(sentinel_t<_Base> __end)
2097 _Sentinel(_Sentinel<!_Const> __i)
2099 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2103 constexpr sentinel_t<_Base>
2107 template<
bool _Const2>
2108 requires sentinel_for<sentinel_t<_Base>,
2109 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2110 friend constexpr bool
2111 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2112 {
return __y.__equal(__x); }
2114 template<
bool _Const2,
2115 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2116 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2117 friend constexpr range_difference_t<_Base2>
2118 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2119 {
return -__y.__distance_from(__x); }
2121 template<
bool _Const2,
2122 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2123 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2124 friend constexpr range_difference_t<_Base2>
2125 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2126 {
return __y.__distance_from(__x); }
2128 friend _Sentinel<!_Const>;
2131 _Vp _M_base = _Vp();
2132 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2135 transform_view()
requires (default_initializable<_Vp>
2136 && default_initializable<_Fp>)
2140 transform_view(_Vp __base, _Fp __fun)
2145 base() const& requires copy_constructible<_Vp>
2146 {
return _M_base ; }
2152 constexpr _Iterator<false>
2154 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2156 constexpr _Iterator<true>
2158 requires range<const _Vp>
2159 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2160 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2162 constexpr _Sentinel<false>
2164 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2166 constexpr _Iterator<false>
2167 end()
requires common_range<_Vp>
2168 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2170 constexpr _Sentinel<true>
2172 requires range<const _Vp>
2173 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2174 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2176 constexpr _Iterator<true>
2178 requires common_range<const _Vp>
2179 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2180 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2183 size()
requires sized_range<_Vp>
2184 {
return ranges::size(_M_base); }
2187 size() const requires sized_range<const _Vp>
2188 {
return ranges::size(_M_base); }
2191 template<
typename _Range,
typename _Fp>
2192 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2198 template<
typename _Range,
typename _Fp>
2199 concept __can_transform_view
2200 =
requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2203 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2205 template<viewable_range _Range,
typename _Fp>
2206 requires __detail::__can_transform_view<_Range, _Fp>
2208 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2210 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2213 using _RangeAdaptor<_Transform>::operator();
2214 static constexpr int _S_arity = 2;
2215 static constexpr bool _S_has_simple_extra_args =
true;
2218 inline constexpr _Transform transform;
2222 class take_view :
public view_interface<take_view<_Vp>>
2225 template<
bool _Const>
2226 using _CI = counted_iterator<
2227 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2229 template<
bool _Const>
2233 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2234 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2237 _Sentinel() =
default;
2240 _Sentinel(sentinel_t<_Base> __end)
2245 _Sentinel(_Sentinel<!_Const> __s)
2246 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2250 constexpr sentinel_t<_Base>
2254 friend constexpr bool
2255 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2256 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2258 template<
bool _OtherConst = !_Const,
2259 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2260 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2261 friend constexpr bool
2262 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2263 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2265 friend _Sentinel<!_Const>;
2268 _Vp _M_base = _Vp();
2269 range_difference_t<_Vp> _M_count = 0;
2272 take_view()
requires default_initializable<_Vp> = default;
2275 take_view(_Vp __base, range_difference_t<_Vp> __count)
2276 : _M_base(
std::move(__base)), _M_count(
std::move(__count))
2280 base() const& requires copy_constructible<_Vp>
2288 begin()
requires (!__detail::__simple_view<_Vp>)
2290 if constexpr (sized_range<_Vp>)
2292 if constexpr (random_access_range<_Vp>)
2293 return ranges::begin(_M_base);
2297 return counted_iterator(ranges::begin(_M_base), __sz);
2301 return counted_iterator(ranges::begin(_M_base), _M_count);
2305 begin() const requires range<const _Vp>
2307 if constexpr (sized_range<const _Vp>)
2309 if constexpr (random_access_range<const _Vp>)
2310 return ranges::begin(_M_base);
2314 return counted_iterator(ranges::begin(_M_base), __sz);
2318 return counted_iterator(ranges::begin(_M_base), _M_count);
2322 end()
requires (!__detail::__simple_view<_Vp>)
2324 if constexpr (sized_range<_Vp>)
2326 if constexpr (random_access_range<_Vp>)
2327 return ranges::begin(_M_base) +
size();
2332 return _Sentinel<false>{ranges::end(_M_base)};
2336 end() const requires range<const _Vp>
2338 if constexpr (sized_range<const _Vp>)
2340 if constexpr (random_access_range<const _Vp>)
2341 return ranges::begin(_M_base) +
size();
2346 return _Sentinel<true>{ranges::end(_M_base)};
2350 size()
requires sized_range<_Vp>
2352 auto __n = ranges::size(_M_base);
2353 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2357 size() const requires sized_range<const _Vp>
2359 auto __n = ranges::size(_M_base);
2360 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2367 template<
typename _Range>
2368 take_view(_Range&&, range_difference_t<_Range>)
2369 -> take_view<views::all_t<_Range>>;
2371 template<
typename _Tp>
2372 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2373 = enable_borrowed_range<_Tp>;
2379 template<
typename _Range>
2380 inline constexpr bool __is_empty_view =
false;
2382 template<
typename _Tp>
2383 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2385 template<
typename _Range>
2386 inline constexpr bool __is_basic_string_view =
false;
2388 template<
typename _CharT,
typename _Traits>
2389 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2392 template<
typename _Range>
2393 inline constexpr bool __is_subrange =
false;
2395 template<
typename _Iter,
typename _Sent, subrange_kind _Kind>
2396 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> =
true;
2398 template<
typename _Range>
2399 inline constexpr bool __is_iota_view =
false;
2401 template<
typename _Winc,
typename _Bound>
2402 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2404 template<
typename _Range>
2405 inline constexpr bool __is_repeat_view =
false;
2407 template<
typename _Range>
2409 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2411 template<
typename _Range,
typename _Dp>
2412 concept __can_take_view
2413 =
requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2416 struct _Take : __adaptor::_RangeAdaptor<_Take>
2418 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2419 requires __detail::__can_take_view<_Range, _Dp>
2421 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2423 using _Tp = remove_cvref_t<_Range>;
2424 if constexpr (__detail::__is_empty_view<_Tp>)
2426 else if constexpr (random_access_range<_Tp>
2428 && (std::__detail::__is_span<_Tp>
2429 || __detail::__is_basic_string_view<_Tp>
2430 || __detail::__is_subrange<_Tp>
2431 || __detail::__is_iota_view<_Tp>))
2433 __n = std::min<_Dp>(ranges::distance(__r), __n);
2434 auto __begin = ranges::begin(__r);
2435 auto __end = __begin + __n;
2436 if constexpr (std::__detail::__is_span<_Tp>)
2437 return span<typename _Tp::element_type>(__begin, __end);
2438 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2439 return _Tp(__begin, __end);
2440 else if constexpr (__detail::__is_subrange<_Tp>)
2441 return subrange<iterator_t<_Tp>>(__begin, __end);
2443 return iota_view(*__begin, *__end);
2445 else if constexpr (__detail::__is_repeat_view<_Tp>)
2446 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2448 return take_view(std::forward<_Range>(__r), __n);
2451 using _RangeAdaptor<_Take>::operator();
2452 static constexpr int _S_arity = 2;
2456 template<
typename _Tp>
2457 static constexpr bool _S_has_simple_extra_args
2458 = ranges::__detail::__is_integer_like<_Tp>;
2461 inline constexpr _Take take;
2464 template<view _Vp,
typename _Pred>
2465 requires input_range<_Vp> && is_object_v<_Pred>
2466 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2467 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2469 template<
bool _Const>
2473 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2475 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2476 const _Pred* _M_pred =
nullptr;
2479 _Sentinel() =
default;
2482 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2483 : _M_end(__end), _M_pred(__pred)
2487 _Sentinel(_Sentinel<!_Const> __s)
2488 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2489 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2492 constexpr sentinel_t<_Base>
2493 base()
const {
return _M_end; }
2495 friend constexpr bool
2496 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2497 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2499 template<
bool _OtherConst = !_Const,
2500 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2501 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2502 friend constexpr bool
2503 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2504 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2506 friend _Sentinel<!_Const>;
2509 _Vp _M_base = _Vp();
2510 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2513 take_while_view()
requires (default_initializable<_Vp>
2514 && default_initializable<_Pred>)
2518 take_while_view(_Vp __base, _Pred __pred)
2523 base() const& requires copy_constructible<_Vp>
2530 constexpr const _Pred&
2532 {
return *_M_pred; }
2535 begin()
requires (!__detail::__simple_view<_Vp>)
2536 {
return ranges::begin(_M_base); }
2539 begin() const requires range<const _Vp>
2540 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2541 {
return ranges::begin(_M_base); }
2544 end()
requires (!__detail::__simple_view<_Vp>)
2545 {
return _Sentinel<false>(ranges::end(_M_base),
2549 end() const requires range<const _Vp>
2550 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2551 {
return _Sentinel<true>(ranges::end(_M_base),
2555 template<
typename _Range,
typename _Pred>
2556 take_while_view(_Range&&, _Pred)
2557 -> take_while_view<views::all_t<_Range>, _Pred>;
2563 template<
typename _Range,
typename _Pred>
2564 concept __can_take_while_view
2565 =
requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2568 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2570 template<viewable_range _Range,
typename _Pred>
2571 requires __detail::__can_take_while_view<_Range, _Pred>
2573 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2575 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2578 using _RangeAdaptor<_TakeWhile>::operator();
2579 static constexpr int _S_arity = 2;
2580 static constexpr bool _S_has_simple_extra_args =
true;
2583 inline constexpr _TakeWhile take_while;
2587 class drop_view :
public view_interface<drop_view<_Vp>>
2590 _Vp _M_base = _Vp();
2591 range_difference_t<_Vp> _M_count = 0;
2595 static constexpr bool _S_needs_cached_begin
2596 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2597 [[no_unique_address]]
2598 __detail::__maybe_present_t<_S_needs_cached_begin,
2599 __detail::_CachedPosition<_Vp>>
2603 drop_view()
requires default_initializable<_Vp> = default;
2606 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2607 : _M_base(
std::move(__base)), _M_count(__count)
2608 { __glibcxx_assert(__count >= 0); }
2611 base() const& requires copy_constructible<_Vp>
2621 requires (!(__detail::__simple_view<_Vp>
2622 && random_access_range<const _Vp>
2623 && sized_range<const _Vp>))
2625 if constexpr (_S_needs_cached_begin)
2626 if (_M_cached_begin._M_has_value())
2627 return _M_cached_begin._M_get(_M_base);
2629 auto __it = ranges::next(ranges::begin(_M_base),
2630 _M_count, ranges::end(_M_base));
2631 if constexpr (_S_needs_cached_begin)
2632 _M_cached_begin._M_set(_M_base, __it);
2640 requires random_access_range<const _Vp> && sized_range<const _Vp>
2642 return ranges::next(ranges::begin(_M_base), _M_count,
2643 ranges::end(_M_base));
2647 end()
requires (!__detail::__simple_view<_Vp>)
2648 {
return ranges::end(_M_base); }
2651 end() const requires range<const _Vp>
2652 {
return ranges::end(_M_base); }
2655 size()
requires sized_range<_Vp>
2657 const auto __s = ranges::size(_M_base);
2658 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2659 return __s < __c ? 0 : __s - __c;
2663 size() const requires sized_range<const _Vp>
2665 const auto __s = ranges::size(_M_base);
2666 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2667 return __s < __c ? 0 : __s - __c;
2671 template<
typename _Range>
2672 drop_view(_Range&&, range_difference_t<_Range>)
2673 -> drop_view<views::all_t<_Range>>;
2675 template<
typename _Tp>
2676 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2677 = enable_borrowed_range<_Tp>;
2683 template<
typename _Range>
2685 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2687 template<
typename _Range,
typename _Dp>
2688 concept __can_drop_view
2689 =
requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2692 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2694 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2695 requires __detail::__can_drop_view<_Range, _Dp>
2697 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2699 using _Tp = remove_cvref_t<_Range>;
2700 if constexpr (__detail::__is_empty_view<_Tp>)
2702 else if constexpr (random_access_range<_Tp>
2704 && (std::__detail::__is_span<_Tp>
2705 || __detail::__is_basic_string_view<_Tp>
2706 || __detail::__is_iota_view<_Tp>
2707 || __detail::__is_subrange<_Tp>))
2709 __n = std::min<_Dp>(ranges::distance(__r), __n);
2710 auto __begin = ranges::begin(__r) + __n;
2711 auto __end = ranges::end(__r);
2712 if constexpr (std::__detail::__is_span<_Tp>)
2713 return span<typename _Tp::element_type>(__begin, __end);
2714 else if constexpr (__detail::__is_subrange<_Tp>)
2716 if constexpr (_Tp::_S_store_size)
2718 using ranges::__detail::__to_unsigned_like;
2719 auto __m = ranges::distance(__r) - __n;
2720 return _Tp(__begin, __end, __to_unsigned_like(__m));
2723 return _Tp(__begin, __end);
2726 return _Tp(__begin, __end);
2728 else if constexpr (__detail::__is_repeat_view<_Tp>)
2729 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2731 return drop_view(std::forward<_Range>(__r), __n);
2734 using _RangeAdaptor<_Drop>::operator();
2735 static constexpr int _S_arity = 2;
2736 template<
typename _Tp>
2737 static constexpr bool _S_has_simple_extra_args
2738 = _Take::_S_has_simple_extra_args<_Tp>;
2741 inline constexpr _Drop drop;
2744 template<view _Vp,
typename _Pred>
2745 requires input_range<_Vp> && is_object_v<_Pred>
2746 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2747 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2750 _Vp _M_base = _Vp();
2751 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2752 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2755 drop_while_view()
requires (default_initializable<_Vp>
2756 && default_initializable<_Pred>)
2760 drop_while_view(_Vp __base, _Pred __pred)
2765 base() const& requires copy_constructible<_Vp>
2772 constexpr const _Pred&
2774 {
return *_M_pred; }
2779 if (_M_cached_begin._M_has_value())
2780 return _M_cached_begin._M_get(_M_base);
2782 __glibcxx_assert(_M_pred.has_value());
2783 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2784 ranges::end(_M_base),
2785 std::cref(*_M_pred));
2786 _M_cached_begin._M_set(_M_base, __it);
2792 {
return ranges::end(_M_base); }
2795 template<
typename _Range,
typename _Pred>
2796 drop_while_view(_Range&&, _Pred)
2797 -> drop_while_view<views::all_t<_Range>, _Pred>;
2799 template<
typename _Tp,
typename _Pred>
2800 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2801 = enable_borrowed_range<_Tp>;
2807 template<
typename _Range,
typename _Pred>
2808 concept __can_drop_while_view
2809 =
requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2812 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2814 template<viewable_range _Range,
typename _Pred>
2815 requires __detail::__can_drop_while_view<_Range, _Pred>
2817 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2819 return drop_while_view(std::forward<_Range>(__r),
2820 std::forward<_Pred>(__p));
2823 using _RangeAdaptor<_DropWhile>::operator();
2824 static constexpr int _S_arity = 2;
2825 static constexpr bool _S_has_simple_extra_args =
true;
2828 inline constexpr _DropWhile drop_while;
2833 template<
typename _Tp>
2835 __as_lvalue(_Tp&& __t)
2836 {
return static_cast<_Tp&
>(__t); }
2839 template<input_range _Vp>
2840 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2841 class join_view :
public view_interface<join_view<_Vp>>
2844 using _InnerRange = range_reference_t<_Vp>;
2846 template<
bool _Const>
2847 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2849 template<
bool _Const>
2850 using _Outer_iter = iterator_t<_Base<_Const>>;
2852 template<
bool _Const>
2853 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2855 template<
bool _Const>
2856 static constexpr bool _S_ref_is_glvalue
2857 = is_reference_v<range_reference_t<_Base<_Const>>>;
2859 template<
bool _Const>
2863 template<
bool _Const>
2864 requires _S_ref_is_glvalue<_Const>
2865 && forward_range<_Base<_Const>>
2866 && forward_range<range_reference_t<_Base<_Const>>>
2867 struct __iter_cat<_Const>
2870 static constexpr auto
2873 using _Outer_iter = join_view::_Outer_iter<_Const>;
2874 using _Inner_iter = join_view::_Inner_iter<_Const>;
2875 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
2876 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
2877 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2878 && derived_from<_InnerCat, bidirectional_iterator_tag>
2879 && common_range<range_reference_t<_Base<_Const>>>)
2880 return bidirectional_iterator_tag{};
2881 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2882 && derived_from<_InnerCat, forward_iterator_tag>)
2883 return forward_iterator_tag{};
2885 return input_iterator_tag{};
2888 using iterator_category =
decltype(_S_iter_cat());
2891 template<
bool _Const>
2894 template<
bool _Const>
2895 struct _Iterator : __iter_cat<_Const>
2898 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2899 using _Base = join_view::_Base<_Const>;
2903 static constexpr bool _S_ref_is_glvalue
2904 = join_view::_S_ref_is_glvalue<_Const>;
2909 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
2910 if constexpr (_S_ref_is_glvalue)
2913 return _M_parent->_M_inner._M_emplace_deref(__x);
2916 _Outer_iter& __outer = _M_get_outer();
2917 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2919 auto&& __inner = __update_inner(__outer);
2920 _M_inner = ranges::begin(__inner);
2921 if (_M_inner != ranges::end(__inner))
2925 if constexpr (_S_ref_is_glvalue)
2929 static constexpr auto
2932 if constexpr (_S_ref_is_glvalue
2933 && bidirectional_range<_Base>
2934 && bidirectional_range<range_reference_t<_Base>>
2935 && common_range<range_reference_t<_Base>>)
2936 return bidirectional_iterator_tag{};
2937 else if constexpr (_S_ref_is_glvalue
2938 && forward_range<_Base>
2939 && forward_range<range_reference_t<_Base>>)
2940 return forward_iterator_tag{};
2942 return input_iterator_tag{};
2945 using _Outer_iter = join_view::_Outer_iter<_Const>;
2946 using _Inner_iter = join_view::_Inner_iter<_Const>;
2948 constexpr _Outer_iter&
2951 if constexpr (forward_range<_Base>)
2954 return *_M_parent->_M_outer;
2957 constexpr const _Outer_iter&
2958 _M_get_outer()
const
2960 if constexpr (forward_range<_Base>)
2963 return *_M_parent->_M_outer;
2967 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
2968 : _M_outer(
std::move(__outer)), _M_parent(__parent)
2972 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
2973 : _M_parent(__parent)
2976 [[no_unique_address]]
2977 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
2978 optional<_Inner_iter> _M_inner;
2979 _Parent* _M_parent =
nullptr;
2982 using iterator_concept =
decltype(_S_iter_concept());
2984 using value_type = range_value_t<range_reference_t<_Base>>;
2985 using difference_type
2986 = common_type_t<range_difference_t<_Base>,
2987 range_difference_t<range_reference_t<_Base>>>;
2989 _Iterator() =
default;
2992 _Iterator(_Iterator<!_Const> __i)
2994 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2995 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2997 _M_parent(__i._M_parent)
3000 constexpr decltype(
auto)
3002 {
return **_M_inner; }
3006 constexpr _Inner_iter
3008 requires __detail::__has_arrow<_Inner_iter>
3009 && copyable<_Inner_iter>
3010 {
return *_M_inner; }
3012 constexpr _Iterator&
3015 auto&& __inner_range = [
this] () ->
auto&& {
3016 if constexpr (_S_ref_is_glvalue)
3017 return *_M_get_outer();
3019 return *_M_parent->_M_inner;
3021 if (++*_M_inner == ranges::end(__inner_range))
3035 requires _S_ref_is_glvalue && forward_range<_Base>
3036 && forward_range<range_reference_t<_Base>>
3043 constexpr _Iterator&
3045 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3046 && bidirectional_range<range_reference_t<_Base>>
3047 && common_range<range_reference_t<_Base>>
3049 if (_M_outer == ranges::end(_M_parent->_M_base))
3050 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3051 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3052 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3059 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3060 && bidirectional_range<range_reference_t<_Base>>
3061 && common_range<range_reference_t<_Base>>
3068 friend constexpr bool
3069 operator==(
const _Iterator& __x,
const _Iterator& __y)
3070 requires _S_ref_is_glvalue
3071 && forward_range<_Base>
3072 && equality_comparable<_Inner_iter>
3074 return (__x._M_outer == __y._M_outer
3075 && __x._M_inner == __y._M_inner);
3078 friend constexpr decltype(
auto)
3079 iter_move(
const _Iterator& __i)
3080 noexcept(
noexcept(ranges::iter_move(*__i._M_inner)))
3081 {
return ranges::iter_move(*__i._M_inner); }
3083 friend constexpr void
3084 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3085 noexcept(
noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3086 requires indirectly_swappable<_Inner_iter>
3087 {
return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3089 friend _Iterator<!_Const>;
3090 template<
bool>
friend struct _Sentinel;
3093 template<
bool _Const>
3097 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3098 using _Base = join_view::_Base<_Const>;
3100 template<
bool _Const2>
3102 __equal(
const _Iterator<_Const2>& __i)
const
3103 {
return __i._M_get_outer() == _M_end; }
3105 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3108 _Sentinel() =
default;
3111 _Sentinel(_Parent* __parent)
3112 : _M_end(ranges::
end(__parent->_M_base))
3116 _Sentinel(_Sentinel<!_Const> __s)
3117 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3121 template<
bool _Const2>
3122 requires sentinel_for<sentinel_t<_Base>,
3123 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3124 friend constexpr bool
3125 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3126 {
return __y.__equal(__x); }
3128 friend _Sentinel<!_Const>;
3131 _Vp _M_base = _Vp();
3132 [[no_unique_address]]
3133 __detail::__maybe_present_t<!forward_range<_Vp>,
3134 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3135 [[no_unique_address]]
3136 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3139 join_view()
requires default_initializable<_Vp> = default;
3142 join_view(_Vp __base)
3143 : _M_base(
std::move(__base))
3147 base() const& requires copy_constructible<_Vp>
3157 if constexpr (forward_range<_Vp>)
3159 constexpr bool __use_const
3160 = (__detail::__simple_view<_Vp>
3161 && is_reference_v<range_reference_t<_Vp>>);
3162 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3166 _M_outer = ranges::begin(_M_base);
3167 return _Iterator<false>{
this};
3173 requires forward_range<const _Vp>
3174 && is_reference_v<range_reference_t<const _Vp>>
3175 && input_range<range_reference_t<const _Vp>>
3177 return _Iterator<true>{
this, ranges::begin(_M_base)};
3183 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3184 && forward_range<_InnerRange>
3185 && common_range<_Vp> && common_range<_InnerRange>)
3186 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3187 ranges::end(_M_base)};
3189 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3194 requires forward_range<const _Vp>
3195 && is_reference_v<range_reference_t<const _Vp>>
3196 && input_range<range_reference_t<const _Vp>>
3198 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3199 && forward_range<range_reference_t<const _Vp>>
3200 && common_range<const _Vp>
3201 && common_range<range_reference_t<const _Vp>>)
3202 return _Iterator<true>{
this, ranges::end(_M_base)};
3204 return _Sentinel<true>{
this};
3208 template<
typename _Range>
3209 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3215 template<
typename _Range>
3216 concept __can_join_view
3217 =
requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3220 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3222 template<viewable_range _Range>
3223 requires __detail::__can_join_view<_Range>
3225 operator() [[nodiscard]] (_Range&& __r)
const
3229 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3232 static constexpr bool _S_has_simple_call_op =
true;
3235 inline constexpr _Join join;
3241 struct __require_constant;
3243 template<
typename _Range>
3244 concept __tiny_range = sized_range<_Range>
3246 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3247 && (remove_reference_t<_Range>::size() <= 1);
3249 template<
typename _Base>
3250 struct __lazy_split_view_outer_iter_cat
3253 template<forward_range _Base>
3254 struct __lazy_split_view_outer_iter_cat<_Base>
3255 {
using iterator_category = input_iterator_tag; };
3257 template<
typename _Base>
3258 struct __lazy_split_view_inner_iter_cat
3261 template<forward_range _Base>
3262 struct __lazy_split_view_inner_iter_cat<_Base>
3265 static constexpr auto
3268 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3269 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3270 return forward_iterator_tag{};
3275 using iterator_category =
decltype(_S_iter_cat());
3279 template<input_range _Vp, forward_range _Pattern>
3280 requires view<_Vp> && view<_Pattern>
3281 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3283 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3284 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3287 template<
bool _Const>
3288 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3290 template<
bool _Const>
3293 template<
bool _Const>
3295 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3298 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3299 using _Base = lazy_split_view::_Base<_Const>;
3303 {
return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3310 __current() noexcept
3312 if constexpr (forward_range<_Vp>)
3315 return *_M_parent->_M_current;
3319 __current() const noexcept
3321 if constexpr (forward_range<_Vp>)
3324 return *_M_parent->_M_current;
3327 _Parent* _M_parent =
nullptr;
3329 [[no_unique_address]]
3330 __detail::__maybe_present_t<forward_range<_Vp>,
3331 iterator_t<_Base>> _M_current;
3332 bool _M_trailing_empty =
false;
3335 using iterator_concept = __conditional_t<forward_range<_Base>,
3336 forward_iterator_tag,
3337 input_iterator_tag>;
3339 using difference_type = range_difference_t<_Base>;
3341 struct value_type : view_interface<value_type>
3344 _OuterIter _M_i = _OuterIter();
3347 value_type() =
default;
3350 value_type(_OuterIter __i)
3354 constexpr _InnerIter<_Const>
3356 {
return _InnerIter<_Const>{_M_i}; }
3358 constexpr default_sentinel_t
3359 end() const noexcept
3363 _OuterIter() =
default;
3366 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3367 : _M_parent(__parent)
3371 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3372 requires forward_range<_Base>
3373 : _M_parent(__parent),
3378 _OuterIter(_OuterIter<!_Const> __i)
3380 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3381 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3382 _M_trailing_empty(__i._M_trailing_empty)
3385 constexpr value_type
3387 {
return value_type{*
this}; }
3389 constexpr _OuterIter&
3394 const auto __end = ranges::end(_M_parent->_M_base);
3395 if (__current() == __end)
3397 _M_trailing_empty =
false;
3400 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3401 if (__pbegin == __pend)
3403 else if constexpr (__detail::__tiny_range<_Pattern>)
3405 __current() = ranges::find(
std::move(__current()), __end,
3407 if (__current() != __end)
3410 if (__current() == __end)
3411 _M_trailing_empty =
true;
3418 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3422 if (__current() == __end)
3423 _M_trailing_empty =
true;
3426 }
while (++__current() != __end);
3430 constexpr decltype(
auto)
3433 if constexpr (forward_range<_Base>)
3443 friend constexpr bool
3444 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3445 requires forward_range<_Base>
3447 return __x._M_current == __y._M_current
3448 && __x._M_trailing_empty == __y._M_trailing_empty;
3451 friend constexpr bool
3452 operator==(
const _OuterIter& __x, default_sentinel_t)
3453 {
return __x.__at_end(); };
3455 friend _OuterIter<!_Const>;
3456 friend _InnerIter<_Const>;
3459 template<
bool _Const>
3461 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3464 using _Base = lazy_split_view::_Base<_Const>;
3469 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3470 auto __end = ranges::end(_M_i._M_parent->_M_base);
3471 if constexpr (__detail::__tiny_range<_Pattern>)
3473 const auto& __cur = _M_i_current();
3476 if (__pcur == __pend)
3477 return _M_incremented;
3478 return *__cur == *__pcur;
3482 auto __cur = _M_i_current();
3485 if (__pcur == __pend)
3486 return _M_incremented;
3489 if (*__cur != *__pcur)
3491 if (++__pcur == __pend)
3493 }
while (++__cur != __end);
3499 _M_i_current() noexcept
3500 {
return _M_i.__current(); }
3503 _M_i_current() const noexcept
3504 {
return _M_i.__current(); }
3506 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3507 bool _M_incremented =
false;
3510 using iterator_concept
3511 =
typename _OuterIter<_Const>::iterator_concept;
3513 using value_type = range_value_t<_Base>;
3514 using difference_type = range_difference_t<_Base>;
3516 _InnerIter() =
default;
3519 _InnerIter(_OuterIter<_Const> __i)
3523 constexpr const iterator_t<_Base>&
3524 base() const& noexcept
3525 {
return _M_i_current(); }
3527 constexpr iterator_t<_Base>
3528 base() &&
requires forward_range<_Vp>
3531 constexpr decltype(
auto)
3533 {
return *_M_i_current(); }
3535 constexpr _InnerIter&
3538 _M_incremented =
true;
3539 if constexpr (!forward_range<_Base>)
3540 if constexpr (_Pattern::size() == 0)
3546 constexpr decltype(
auto)
3549 if constexpr (forward_range<_Base>)
3559 friend constexpr bool
3560 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3561 requires forward_range<_Base>
3562 {
return __x._M_i == __y._M_i; }
3564 friend constexpr bool
3565 operator==(
const _InnerIter& __x, default_sentinel_t)
3566 {
return __x.__at_end(); }
3568 friend constexpr decltype(
auto)
3569 iter_move(
const _InnerIter& __i)
3570 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3571 {
return ranges::iter_move(__i._M_i_current()); }
3573 friend constexpr void
3574 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3575 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3576 __y._M_i_current())))
3577 requires indirectly_swappable<iterator_t<_Base>>
3578 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3581 _Vp _M_base = _Vp();
3582 _Pattern _M_pattern = _Pattern();
3583 [[no_unique_address]]
3584 __detail::__maybe_present_t<!forward_range<_Vp>,
3585 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3589 lazy_split_view()
requires (default_initializable<_Vp>
3590 && default_initializable<_Pattern>)
3594 lazy_split_view(_Vp __base, _Pattern __pattern)
3598 template<input_range _Range>
3599 requires constructible_from<_Vp, views::all_t<_Range>>
3600 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3602 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3603 : _M_base(views::all(
std::
forward<_Range>(__r))),
3604 _M_pattern(views::single(
std::
move(__e)))
3608 base() const& requires copy_constructible<_Vp>
3618 if constexpr (forward_range<_Vp>)
3620 constexpr bool __simple
3621 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3622 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3626 _M_current = ranges::begin(_M_base);
3627 return _OuterIter<false>{
this};
3632 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3634 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3638 end()
requires forward_range<_Vp> && common_range<_Vp>
3640 constexpr bool __simple
3641 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3642 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3648 if constexpr (forward_range<_Vp>
3649 && forward_range<const _Vp>
3650 && common_range<const _Vp>)
3651 return _OuterIter<true>{
this, ranges::end(_M_base)};
3657 template<
typename _Range,
typename _Pattern>
3658 lazy_split_view(_Range&&, _Pattern&&)
3659 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3661 template<input_range _Range>
3662 lazy_split_view(_Range&&, range_value_t<_Range>)
3663 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3669 template<
typename _Range,
typename _Pattern>
3670 concept __can_lazy_split_view
3671 =
requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3674 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3676 template<viewable_range _Range,
typename _Pattern>
3677 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3679 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3681 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3684 using _RangeAdaptor<_LazySplit>::operator();
3685 static constexpr int _S_arity = 2;
3690 template<
typename _Pattern>
3691 static constexpr bool _S_has_simple_extra_args
3692 = is_scalar_v<_Pattern> || (view<_Pattern>
3693 && copy_constructible<_Pattern>);
3696 inline constexpr _LazySplit lazy_split;
3699 template<forward_range _Vp, forward_range _Pattern>
3700 requires view<_Vp> && view<_Pattern>
3701 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3703 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3706 _Vp _M_base = _Vp();
3707 _Pattern _M_pattern = _Pattern();
3708 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3714 split_view()
requires (default_initializable<_Vp>
3715 && default_initializable<_Pattern>)
3719 split_view(_Vp __base, _Pattern __pattern)
3723 template<forward_range _Range>
3724 requires constructible_from<_Vp, views::all_t<_Range>>
3725 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3727 split_view(_Range&& __r, range_value_t<_Range> __e)
3728 : _M_base(views::all(
std::
forward<_Range>(__r))),
3729 _M_pattern(views::single(
std::
move(__e)))
3733 base() const& requires copy_constructible<_Vp>
3743 if (!_M_cached_begin)
3744 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3745 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3751 if constexpr (common_range<_Vp>)
3752 return _Iterator{
this, ranges::end(_M_base), {}};
3754 return _Sentinel{
this};
3757 constexpr subrange<iterator_t<_Vp>>
3758 _M_find_next(iterator_t<_Vp> __it)
3760 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3761 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3773 split_view* _M_parent =
nullptr;
3774 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3775 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3776 bool _M_trailing_empty =
false;
3778 friend struct _Sentinel;
3781 using iterator_concept = forward_iterator_tag;
3782 using iterator_category = input_iterator_tag;
3783 using value_type = subrange<iterator_t<_Vp>>;
3784 using difference_type = range_difference_t<_Vp>;
3786 _Iterator() =
default;
3789 _Iterator(split_view* __parent,
3790 iterator_t<_Vp> __current,
3791 subrange<iterator_t<_Vp>> __next)
3792 : _M_parent(__parent),
3797 constexpr iterator_t<_Vp>
3801 constexpr value_type
3803 {
return {_M_cur, _M_next.begin()}; }
3805 constexpr _Iterator&
3808 _M_cur = _M_next.begin();
3809 if (_M_cur != ranges::end(_M_parent->_M_base))
3811 _M_cur = _M_next.end();
3812 if (_M_cur == ranges::end(_M_parent->_M_base))
3814 _M_trailing_empty =
true;
3815 _M_next = {_M_cur, _M_cur};
3818 _M_next = _M_parent->_M_find_next(_M_cur);
3821 _M_trailing_empty =
false;
3833 friend constexpr bool
3834 operator==(
const _Iterator& __x,
const _Iterator& __y)
3836 return __x._M_cur == __y._M_cur
3837 && __x._M_trailing_empty == __y._M_trailing_empty;
3844 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3847 _M_equal(
const _Iterator& __x)
const
3848 {
return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3851 _Sentinel() =
default;
3854 _Sentinel(split_view* __parent)
3855 : _M_end(ranges::
end(__parent->_M_base))
3858 friend constexpr bool
3859 operator==(
const _Iterator& __x,
const _Sentinel& __y)
3860 {
return __y._M_equal(__x); }
3864 template<
typename _Range,
typename _Pattern>
3865 split_view(_Range&&, _Pattern&&)
3866 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3868 template<forward_range _Range>
3869 split_view(_Range&&, range_value_t<_Range>)
3870 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3876 template<
typename _Range,
typename _Pattern>
3877 concept __can_split_view
3878 =
requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3881 struct _Split : __adaptor::_RangeAdaptor<_Split>
3883 template<viewable_range _Range,
typename _Pattern>
3884 requires __detail::__can_split_view<_Range, _Pattern>
3886 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3888 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3891 using _RangeAdaptor<_Split>::operator();
3892 static constexpr int _S_arity = 2;
3893 template<
typename _Pattern>
3894 static constexpr bool _S_has_simple_extra_args
3895 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3898 inline constexpr _Split split;
3905 template<input_or_output_iterator _Iter>
3907 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
3909 if constexpr (contiguous_iterator<_Iter>)
3910 return span(std::__to_address(__i), __n);
3911 else if constexpr (random_access_iterator<_Iter>)
3912 return subrange(__i, __i + __n);
3914 return subrange(counted_iterator(
std::move(__i), __n),
3919 inline constexpr _Counted counted{};
3923 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3924 class common_view : public view_interface<common_view<_Vp>>
3927 _Vp _M_base = _Vp();
3930 common_view()
requires default_initializable<_Vp> = default;
3933 common_view(_Vp __r)
3934 : _M_base(
std::move(__r))
3938 base() const& requires copy_constructible<_Vp>
3948 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3949 return ranges::begin(_M_base);
3951 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3952 (ranges::begin(_M_base));
3956 begin() const requires range<const _Vp>
3958 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3959 return ranges::begin(_M_base);
3961 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3962 (ranges::begin(_M_base));
3968 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3969 return ranges::begin(_M_base) + ranges::size(_M_base);
3971 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3972 (ranges::end(_M_base));
3976 end() const requires range<const _Vp>
3978 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3979 return ranges::begin(_M_base) + ranges::size(_M_base);
3981 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3982 (ranges::end(_M_base));
3986 size()
requires sized_range<_Vp>
3987 {
return ranges::size(_M_base); }
3990 size() const requires sized_range<const _Vp>
3991 {
return ranges::size(_M_base); }
3994 template<
typename _Range>
3995 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3997 template<
typename _Tp>
3998 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3999 = enable_borrowed_range<_Tp>;
4005 template<
typename _Range>
4006 concept __already_common = common_range<_Range>
4007 &&
requires { views::all(std::declval<_Range>()); };
4009 template<
typename _Range>
4010 concept __can_common_view
4011 =
requires { common_view{std::declval<_Range>()}; };
4014 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4016 template<viewable_range _Range>
4017 requires __detail::__already_common<_Range>
4018 || __detail::__can_common_view<_Range>
4020 operator() [[nodiscard]] (_Range&& __r)
const
4022 if constexpr (__detail::__already_common<_Range>)
4023 return views::all(std::forward<_Range>(__r));
4025 return common_view{std::forward<_Range>(__r)};
4028 static constexpr bool _S_has_simple_call_op =
true;
4031 inline constexpr _Common common;
4035 requires bidirectional_range<_Vp>
4036 class reverse_view :
public view_interface<reverse_view<_Vp>>
4039 static constexpr bool _S_needs_cached_begin
4040 = !common_range<_Vp> && !(random_access_range<_Vp>
4041 && sized_sentinel_for<sentinel_t<_Vp>,
4044 _Vp _M_base = _Vp();
4045 [[no_unique_address]]
4046 __detail::__maybe_present_t<_S_needs_cached_begin,
4047 __detail::_CachedPosition<_Vp>>
4051 reverse_view()
requires default_initializable<_Vp> = default;
4054 reverse_view(_Vp __r)
4055 : _M_base(
std::move(__r))
4059 base() const& requires copy_constructible<_Vp>
4066 constexpr reverse_iterator<iterator_t<_Vp>>
4069 if constexpr (_S_needs_cached_begin)
4070 if (_M_cached_begin._M_has_value())
4073 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4074 if constexpr (_S_needs_cached_begin)
4075 _M_cached_begin._M_set(_M_base, __it);
4080 begin()
requires common_range<_Vp>
4084 begin() const requires common_range<const _Vp>
4087 constexpr reverse_iterator<iterator_t<_Vp>>
4092 end() const requires common_range<const _Vp>
4096 size()
requires sized_range<_Vp>
4097 {
return ranges::size(_M_base); }
4100 size() const requires sized_range<const _Vp>
4101 {
return ranges::size(_M_base); }
4104 template<
typename _Range>
4105 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4107 template<
typename _Tp>
4108 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4109 = enable_borrowed_range<_Tp>;
4116 inline constexpr bool __is_reversible_subrange =
false;
4118 template<
typename _Iter, subrange_kind _Kind>
4119 inline constexpr bool
4120 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4121 reverse_iterator<_Iter>,
4125 inline constexpr bool __is_reverse_view =
false;
4127 template<
typename _Vp>
4128 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4130 template<
typename _Range>
4131 concept __can_reverse_view
4132 =
requires { reverse_view{std::declval<_Range>()}; };
4135 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4137 template<viewable_range _Range>
4138 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4139 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4140 || __detail::__can_reverse_view<_Range>
4142 operator() [[nodiscard]] (_Range&& __r)
const
4144 using _Tp = remove_cvref_t<_Range>;
4145 if constexpr (__detail::__is_reverse_view<_Tp>)
4146 return std::forward<_Range>(__r).base();
4147 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4149 using _Iter =
decltype(ranges::begin(__r).base());
4150 if constexpr (sized_range<_Tp>)
4151 return subrange<_Iter, _Iter, subrange_kind::sized>
4152 {__r.end().base(), __r.begin().base(), __r.size()};
4154 return subrange<_Iter, _Iter, subrange_kind::unsized>
4155 {__r.end().base(), __r.begin().base()};
4158 return reverse_view{std::forward<_Range>(__r)};
4161 static constexpr bool _S_has_simple_call_op =
true;
4164 inline constexpr _Reverse reverse;
4169 template<
typename _Tp,
size_t _Nm>
4170 concept __has_tuple_element =
requires(_Tp __t)
4172 typename tuple_size<_Tp>::type;
4173 requires _Nm < tuple_size_v<_Tp>;
4174 typename tuple_element_t<_Nm, _Tp>;
4175 { std::get<_Nm>(__t) }
4176 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4179 template<
typename _Tp,
size_t _Nm>
4180 concept __returnable_element
4181 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4184 template<input_range _Vp,
size_t _Nm>
4186 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4187 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4189 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4190 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4193 elements_view()
requires default_initializable<_Vp> = default;
4196 elements_view(_Vp __base)
4197 : _M_base(
std::move(__base))
4201 base() const& requires copy_constructible<_Vp>
4209 begin()
requires (!__detail::__simple_view<_Vp>)
4210 {
return _Iterator<false>(ranges::begin(_M_base)); }
4213 begin() const requires range<const _Vp>
4214 {
return _Iterator<true>(ranges::begin(_M_base)); }
4217 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4218 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4221 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4222 {
return _Iterator<false>{ranges::end(_M_base)}; }
4225 end() const requires range<const _Vp>
4226 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4229 end() const requires common_range<const _Vp>
4230 {
return _Iterator<true>{ranges::end(_M_base)}; }
4233 size()
requires sized_range<_Vp>
4234 {
return ranges::size(_M_base); }
4237 size() const requires sized_range<const _Vp>
4238 {
return ranges::size(_M_base); }
4241 template<
bool _Const>
4242 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4244 template<
bool _Const>
4248 template<
bool _Const>
4249 requires forward_range<_Base<_Const>>
4250 struct __iter_cat<_Const>
4253 static auto _S_iter_cat()
4255 using _Base = elements_view::_Base<_Const>;
4256 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4257 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4258 if constexpr (!is_lvalue_reference_v<_Res>)
4259 return input_iterator_tag{};
4260 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4261 return random_access_iterator_tag{};
4266 using iterator_category =
decltype(_S_iter_cat());
4269 template<
bool _Const>
4272 template<
bool _Const>
4273 struct _Iterator : __iter_cat<_Const>
4276 using _Base = elements_view::_Base<_Const>;
4278 iterator_t<_Base> _M_current = iterator_t<_Base>();
4280 static constexpr decltype(
auto)
4281 _S_get_element(
const iterator_t<_Base>& __i)
4283 if constexpr (is_reference_v<range_reference_t<_Base>>)
4284 return std::get<_Nm>(*__i);
4287 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4288 return static_cast<_Et
>(std::get<_Nm>(*__i));
4295 if constexpr (random_access_range<_Base>)
4296 return random_access_iterator_tag{};
4297 else if constexpr (bidirectional_range<_Base>)
4298 return bidirectional_iterator_tag{};
4299 else if constexpr (forward_range<_Base>)
4300 return forward_iterator_tag{};
4302 return input_iterator_tag{};
4305 friend _Iterator<!_Const>;
4308 using iterator_concept =
decltype(_S_iter_concept());
4311 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4312 using difference_type = range_difference_t<_Base>;
4314 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4317 _Iterator(iterator_t<_Base> __current)
4318 : _M_current(
std::move(__current))
4322 _Iterator(_Iterator<!_Const> __i)
4323 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4327 constexpr const iterator_t<_Base>&
4328 base() const& noexcept
4329 {
return _M_current; }
4331 constexpr iterator_t<_Base>
4335 constexpr decltype(
auto)
4337 {
return _S_get_element(_M_current); }
4339 constexpr _Iterator&
4351 operator++(
int)
requires forward_range<_Base>
4358 constexpr _Iterator&
4359 operator--()
requires bidirectional_range<_Base>
4366 operator--(
int)
requires bidirectional_range<_Base>
4373 constexpr _Iterator&
4374 operator+=(difference_type __n)
4375 requires random_access_range<_Base>
4381 constexpr _Iterator&
4382 operator-=(difference_type __n)
4383 requires random_access_range<_Base>
4389 constexpr decltype(
auto)
4390 operator[](difference_type __n)
const
4391 requires random_access_range<_Base>
4392 {
return _S_get_element(_M_current + __n); }
4394 friend constexpr bool
4395 operator==(
const _Iterator& __x,
const _Iterator& __y)
4396 requires equality_comparable<iterator_t<_Base>>
4397 {
return __x._M_current == __y._M_current; }
4399 friend constexpr bool
4400 operator<(
const _Iterator& __x,
const _Iterator& __y)
4401 requires random_access_range<_Base>
4402 {
return __x._M_current < __y._M_current; }
4404 friend constexpr bool
4405 operator>(
const _Iterator& __x,
const _Iterator& __y)
4406 requires random_access_range<_Base>
4407 {
return __y._M_current < __x._M_current; }
4409 friend constexpr bool
4410 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4411 requires random_access_range<_Base>
4412 {
return !(__y._M_current > __x._M_current); }
4414 friend constexpr bool
4415 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4416 requires random_access_range<_Base>
4417 {
return !(__x._M_current > __y._M_current); }
4419#ifdef __cpp_lib_three_way_comparison
4420 friend constexpr auto
4421 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4422 requires random_access_range<_Base>
4423 && three_way_comparable<iterator_t<_Base>>
4424 {
return __x._M_current <=> __y._M_current; }
4427 friend constexpr _Iterator
4428 operator+(
const _Iterator& __x, difference_type __y)
4429 requires random_access_range<_Base>
4430 {
return _Iterator{__x} += __y; }
4432 friend constexpr _Iterator
4433 operator+(difference_type __x,
const _Iterator& __y)
4434 requires random_access_range<_Base>
4435 {
return __y + __x; }
4437 friend constexpr _Iterator
4438 operator-(
const _Iterator& __x, difference_type __y)
4439 requires random_access_range<_Base>
4440 {
return _Iterator{__x} -= __y; }
4444 friend constexpr difference_type
4445 operator-(
const _Iterator& __x,
const _Iterator& __y)
4446 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4447 {
return __x._M_current - __y._M_current; }
4449 template <
bool>
friend struct _Sentinel;
4452 template<
bool _Const>
4456 template<
bool _Const2>
4458 _M_equal(
const _Iterator<_Const2>& __x)
const
4459 {
return __x._M_current == _M_end; }
4461 template<
bool _Const2>
4463 _M_distance_from(
const _Iterator<_Const2>& __i)
const
4464 {
return _M_end - __i._M_current; }
4466 using _Base = elements_view::_Base<_Const>;
4467 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4470 _Sentinel() =
default;
4473 _Sentinel(sentinel_t<_Base> __end)
4478 _Sentinel(_Sentinel<!_Const> __other)
4480 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4484 constexpr sentinel_t<_Base>
4488 template<
bool _Const2>
4489 requires sentinel_for<sentinel_t<_Base>,
4490 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4491 friend constexpr bool
4492 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4493 {
return __y._M_equal(__x); }
4495 template<
bool _Const2,
4496 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4497 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4498 friend constexpr range_difference_t<_Base2>
4499 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4500 {
return -__y._M_distance_from(__x); }
4502 template<
bool _Const2,
4503 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4504 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4505 friend constexpr range_difference_t<_Base2>
4506 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4507 {
return __x._M_distance_from(__y); }
4509 friend _Sentinel<!_Const>;
4512 _Vp _M_base = _Vp();
4515 template<
typename _Tp,
size_t _Nm>
4516 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4517 = enable_borrowed_range<_Tp>;
4519 template<
typename _Range>
4520 using keys_view = elements_view<views::all_t<_Range>, 0>;
4522 template<
typename _Range>
4523 using values_view = elements_view<views::all_t<_Range>, 1>;
4529 template<
size_t _Nm,
typename _Range>
4530 concept __can_elements_view
4531 =
requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4534 template<
size_t _Nm>
4535 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4537 template<viewable_range _Range>
4538 requires __detail::__can_elements_view<_Nm, _Range>
4540 operator() [[nodiscard]] (_Range&& __r)
const
4542 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4545 static constexpr bool _S_has_simple_call_op =
true;
4548 template<
size_t _Nm>
4549 inline constexpr _Elements<_Nm> elements;
4550 inline constexpr auto keys = elements<0>;
4551 inline constexpr auto values = elements<1>;
4554#ifdef __cpp_lib_ranges_zip
4557 template<
typename... _Rs>
4558 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4559 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4560 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4562 template<
typename... _Ts>
4563 struct __tuple_or_pair
4566 template<
typename _Tp,
typename _Up>
4567 struct __tuple_or_pair<_Tp, _Up>
4568 {
using type = pair<_Tp, _Up>; };
4570 template<
typename... _Ts>
4571 using __tuple_or_pair_t =
typename __tuple_or_pair<_Ts...>::type;
4573 template<
typename _Fp,
typename _Tuple>
4575 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4577 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4578 return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
4580 }, std::forward<_Tuple>(__tuple));
4583 template<
typename _Fp,
typename _Tuple>
4585 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4587 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4589 }, std::forward<_Tuple>(__tuple));
4593 template<input_range... _Vs>
4594 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4595 class zip_view :
public view_interface<zip_view<_Vs...>>
4597 tuple<_Vs...> _M_views;
4599 template<
bool>
class _Iterator;
4600 template<
bool>
class _Sentinel;
4603 zip_view() =
default;
4606 zip_view(_Vs... __views)
4607 : _M_views(
std::
move(__views)...)
4611 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4612 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4615 begin() const requires (range<const _Vs> && ...)
4616 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4619 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4621 if constexpr (!__detail::__zip_is_common<_Vs...>)
4622 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4623 else if constexpr ((random_access_range<_Vs> && ...))
4624 return begin() + iter_difference_t<_Iterator<false>>(
size());
4626 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4630 end() const requires (range<const _Vs> && ...)
4632 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4633 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4634 else if constexpr ((random_access_range<const _Vs> && ...))
4635 return begin() + iter_difference_t<_Iterator<true>>(
size());
4637 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4641 size()
requires (sized_range<_Vs> && ...)
4643 return std::apply([](
auto... sizes) {
4644 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4645 return ranges::min({_CT(sizes)...});
4646 }, __detail::__tuple_transform(ranges::size, _M_views));
4650 size() const requires (sized_range<const _Vs> && ...)
4652 return std::apply([](
auto... sizes) {
4653 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4654 return ranges::min({_CT(sizes)...});
4655 }, __detail::__tuple_transform(ranges::size, _M_views));
4659 template<
typename... _Rs>
4660 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4662 template<
typename... _Views>
4663 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4664 = (enable_borrowed_range<_Views> && ...);
4668 template<
bool _Const,
typename... _Vs>
4669 concept __all_random_access
4670 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4672 template<
bool _Const,
typename... _Vs>
4673 concept __all_bidirectional
4674 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4676 template<
bool _Const,
typename... _Vs>
4677 concept __all_forward
4678 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4680 template<
bool _Const,
typename... _Views>
4681 struct __zip_view_iter_cat
4684 template<
bool _Const,
typename... _Views>
4685 requires __all_forward<_Const, _Views...>
4686 struct __zip_view_iter_cat<_Const, _Views...>
4687 {
using iterator_category = input_iterator_tag; };
4690 template<input_range... _Vs>
4691 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4692 template<
bool _Const>
4693 class zip_view<_Vs...>::_Iterator
4694 :
public __detail::__zip_view_iter_cat<_Const, _Vs...>
4699 __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4702 _Iterator(
decltype(_M_current) __current)
4703 : _M_current(
std::
move(__current))
4709 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4710 return random_access_iterator_tag{};
4711 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4712 return bidirectional_iterator_tag{};
4713 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4714 return forward_iterator_tag{};
4716 return input_iterator_tag{};
4720 template<move_constructible _Fp, input_range... _Ws>
4721 requires (view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4722 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4723 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4724 friend class zip_transform_view;
4729 using iterator_concept =
decltype(_S_iter_concept());
4731 = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4732 using difference_type
4733 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4735 _Iterator() =
default;
4738 _Iterator(_Iterator<!_Const> __i)
4740 && (convertible_to<iterator_t<_Vs>,
4741 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4742 : _M_current(
std::
move(__i._M_current))
4748 auto __f = [](
auto& __i) ->
decltype(
auto) {
4751 return __detail::__tuple_transform(__f, _M_current);
4754 constexpr _Iterator&
4757 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4767 requires __detail::__all_forward<_Const, _Vs...>
4774 constexpr _Iterator&
4776 requires __detail::__all_bidirectional<_Const, _Vs...>
4778 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4784 requires __detail::__all_bidirectional<_Const, _Vs...>
4791 constexpr _Iterator&
4792 operator+=(difference_type __x)
4793 requires __detail::__all_random_access<_Const, _Vs...>
4795 auto __f = [&]<
typename _It>(_It& __i) {
4796 __i += iter_difference_t<_It>(__x);
4798 __detail::__tuple_for_each(__f, _M_current);
4802 constexpr _Iterator&
4803 operator-=(difference_type __x)
4804 requires __detail::__all_random_access<_Const, _Vs...>
4806 auto __f = [&]<
typename _It>(_It& __i) {
4807 __i -= iter_difference_t<_It>(__x);
4809 __detail::__tuple_for_each(__f, _M_current);
4814 operator[](difference_type __n)
const
4815 requires __detail::__all_random_access<_Const, _Vs...>
4817 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
4818 return __i[iter_difference_t<_It>(__n)];
4820 return __detail::__tuple_transform(__f, _M_current);
4823 friend constexpr bool
4824 operator==(
const _Iterator& __x,
const _Iterator& __y)
4825 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4827 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4828 return __x._M_current == __y._M_current;
4831 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4835 friend constexpr auto
4836 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4837 requires __detail::__all_random_access<_Const, _Vs...>
4838 {
return __x._M_current <=> __y._M_current; }
4840 friend constexpr _Iterator
4841 operator+(
const _Iterator& __i, difference_type __n)
4842 requires __detail::__all_random_access<_Const, _Vs...>
4849 friend constexpr _Iterator
4850 operator+(difference_type __n,
const _Iterator& __i)
4851 requires __detail::__all_random_access<_Const, _Vs...>
4858 friend constexpr _Iterator
4859 operator-(
const _Iterator& __i, difference_type __n)
4860 requires __detail::__all_random_access<_Const, _Vs...>
4867 friend constexpr difference_type
4868 operator-(
const _Iterator& __x,
const _Iterator& __y)
4869 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4870 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4873 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4874 - std::get<_Is>(__y._M_current))...},
4876 [](difference_type __i) {
4877 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4882 friend constexpr auto
4883 iter_move(
const _Iterator& __i)
4884 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4886 friend constexpr void
4887 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
4888 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4891 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4895 friend class zip_view;
4898 template<input_range... _Vs>
4899 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4900 template<
bool _Const>
4901 class zip_view<_Vs...>::_Sentinel
4903 __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4906 _Sentinel(
decltype(_M_end) __end)
4910 friend class zip_view;
4913 _Sentinel() =
default;
4916 _Sentinel(_Sentinel<!_Const> __i)
4918 && (convertible_to<sentinel_t<_Vs>,
4919 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4920 : _M_end(
std::
move(__i._M_end))
4923 template<
bool _OtherConst>
4924 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4925 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4926 friend constexpr bool
4927 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
4930 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4934 template<
bool _OtherConst>
4935 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4936 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4937 friend constexpr auto
4938 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
4941 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4943 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4946 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4951 template<
bool _OtherConst>
4952 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4953 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4954 friend constexpr auto
4955 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
4956 {
return -(__x - __y); }
4963 template<
typename... _Ts>
4964 concept __can_zip_view
4965 =
requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4970 template<
typename... _Ts>
4971 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4973 operator() [[nodiscard]] (_Ts&&... __ts)
const
4975 if constexpr (
sizeof...(_Ts) == 0)
4976 return views::empty<tuple<>>;
4978 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4982 inline constexpr _Zip zip;
4987 template<
typename _Range,
bool _Const>
4988 using __range_iter_cat
4989 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4992 template<move_constructible _Fp, input_range... _Vs>
4993 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
4994 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4995 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4996 class zip_transform_view :
public view_interface<zip_transform_view<_Fp, _Vs...>>
4998 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4999 zip_view<_Vs...> _M_zip;
5001 using _InnerView = zip_view<_Vs...>;
5003 template<
bool _Const>
5004 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5006 template<
bool _Const>
5007 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5009 template<
bool _Const>
5010 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5012 template<
bool _Const>
5016 template<
bool _Const>
5017 requires forward_range<_Base<_Const>>
5018 struct __iter_cat<_Const>
5024 using __detail::__maybe_const_t;
5025 using __detail::__range_iter_cat;
5026 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5027 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5028 if constexpr (!is_lvalue_reference_v<_Res>)
5029 return input_iterator_tag{};
5030 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5031 random_access_iterator_tag> && ...))
5032 return random_access_iterator_tag{};
5033 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5034 bidirectional_iterator_tag> && ...))
5035 return bidirectional_iterator_tag{};
5036 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5037 forward_iterator_tag> && ...))
5038 return forward_iterator_tag{};
5040 return input_iterator_tag{};
5043 using iterator_category =
decltype(_S_iter_cat());
5046 template<
bool>
class _Iterator;
5047 template<
bool>
class _Sentinel;
5050 zip_transform_view() =
default;
5053 zip_transform_view(_Fp __fun, _Vs... __views)
5059 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5063 requires range<const _InnerView>
5064 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5065 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5070 if constexpr (common_range<_InnerView>)
5071 return _Iterator<false>(*
this, _M_zip.end());
5073 return _Sentinel<false>(_M_zip.end());
5078 requires range<const _InnerView>
5079 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5081 if constexpr (common_range<const _InnerView>)
5082 return _Iterator<true>(*
this, _M_zip.end());
5084 return _Sentinel<true>(_M_zip.end());
5088 size()
requires sized_range<_InnerView>
5089 {
return _M_zip.size(); }
5092 size() const requires sized_range<const _InnerView>
5093 {
return _M_zip.size(); }
5096 template<
class _Fp,
class... Rs>
5097 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5099 template<move_constructible _Fp, input_range... _Vs>
5100 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5101 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5102 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5103 template<
bool _Const>
5104 class zip_transform_view<_Fp, _Vs...>::_Iterator :
public __iter_cat<_Const>
5106 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5108 _Parent* _M_parent =
nullptr;
5109 __ziperator<_Const> _M_inner;
5112 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5116 friend class zip_transform_view;
5120 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5122 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5123 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5124 using difference_type = range_difference_t<_Base<_Const>>;
5126 _Iterator() =
default;
5129 _Iterator(_Iterator<!_Const> __i)
5130 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5131 : _M_parent(__i._M_parent), _M_inner(
std::move(__i._M_inner))
5134 constexpr decltype(
auto)
5137 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5139 }, _M_inner._M_current);
5142 constexpr _Iterator&
5154 operator++(
int)
requires forward_range<_Base<_Const>>
5161 constexpr _Iterator&
5162 operator--()
requires bidirectional_range<_Base<_Const>>
5169 operator--(
int)
requires bidirectional_range<_Base<_Const>>
5176 constexpr _Iterator&
5177 operator+=(difference_type __x)
requires random_access_range<_Base<_Const>>
5183 constexpr _Iterator&
5184 operator-=(difference_type __x)
requires random_access_range<_Base<_Const>>
5190 constexpr decltype(
auto)
5191 operator[](difference_type __n)
const requires random_access_range<_Base<_Const>>
5193 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5194 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5195 }, _M_inner._M_current);
5198 friend constexpr bool
5199 operator==(
const _Iterator& __x,
const _Iterator& __y)
5200 requires equality_comparable<__ziperator<_Const>>
5201 {
return __x._M_inner == __y._M_inner; }
5203 friend constexpr auto
5204 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5205 requires random_access_range<_Base<_Const>>
5206 {
return __x._M_inner <=> __y._M_inner; }
5208 friend constexpr _Iterator
5209 operator+(
const _Iterator& __i, difference_type __n)
5210 requires random_access_range<_Base<_Const>>
5211 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5213 friend constexpr _Iterator
5214 operator+(difference_type __n,
const _Iterator& __i)
5215 requires random_access_range<_Base<_Const>>
5216 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5218 friend constexpr _Iterator
5219 operator-(
const _Iterator& __i, difference_type __n)
5220 requires random_access_range<_Base<_Const>>
5221 {
return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5223 friend constexpr difference_type
5224 operator-(
const _Iterator& __x,
const _Iterator& __y)
5225 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5226 {
return __x._M_inner - __y._M_inner; }
5229 template<move_constructible _Fp, input_range... _Vs>
5230 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5231 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5232 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5233 template<
bool _Const>
5234 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5236 __zentinel<_Const> _M_inner;
5239 _Sentinel(__zentinel<_Const> __inner)
5243 friend class zip_transform_view;
5246 _Sentinel() =
default;
5249 _Sentinel(_Sentinel<!_Const> __i)
5250 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5254 template<
bool _OtherConst>
5255 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5256 friend constexpr bool
5257 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5258 {
return __x._M_inner == __y._M_inner; }
5260 template<
bool _OtherConst>
5261 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5262 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5263 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5264 {
return __x._M_inner - __y._M_inner; }
5266 template<
bool _OtherConst>
5267 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5268 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5269 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5270 {
return __x._M_inner - __y._M_inner; }
5277 template<
typename _Fp,
typename... _Ts>
5278 concept __can_zip_transform_view
5279 =
requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5282 struct _ZipTransform
5284 template<
typename _Fp,
typename... _Ts>
5285 requires (
sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5287 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5289 if constexpr (
sizeof...(_Ts) == 0)
5290 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5292 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5296 inline constexpr _ZipTransform zip_transform;
5299 template<forward_range _Vp,
size_t _Nm>
5300 requires view<_Vp> && (_Nm > 0)
5301 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5303 _Vp _M_base = _Vp();
5305 template<
bool>
class _Iterator;
5306 template<
bool>
class _Sentinel;
5308 struct __as_sentinel
5312 adjacent_view()
requires default_initializable<_Vp> = default;
5315 adjacent_view(_Vp __base)
5316 : _M_base(
std::move(__base))
5320 begin()
requires (!__detail::__simple_view<_Vp>)
5321 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5324 begin() const requires range<const _Vp>
5325 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5328 end()
requires (!__detail::__simple_view<_Vp>)
5330 if constexpr (common_range<_Vp>)
5331 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5333 return _Sentinel<false>(ranges::end(_M_base));
5337 end() const requires range<const _Vp>
5339 if constexpr (common_range<const _Vp>)
5340 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5342 return _Sentinel<true>(ranges::end(_M_base));
5346 size()
requires sized_range<_Vp>
5348 using _ST =
decltype(ranges::size(_M_base));
5349 using _CT = common_type_t<_ST, size_t>;
5350 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5351 __sz -= std::min<_CT>(__sz, _Nm - 1);
5352 return static_cast<_ST
>(__sz);
5356 size() const requires sized_range<const _Vp>
5358 using _ST =
decltype(ranges::size(_M_base));
5359 using _CT = common_type_t<_ST, size_t>;
5360 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5361 __sz -= std::min<_CT>(__sz, _Nm - 1);
5362 return static_cast<_ST
>(__sz);
5366 template<
typename _Vp,
size_t _Nm>
5367 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5368 = enable_borrowed_range<_Vp>;
5373 template<
typename _Tp,
size_t _Nm>
5378 template<
typename _Fp,
size_t _Nm>
5381 template<
typename... _Ts>
5382 static invoke_result_t<_Fp, _Ts...>
5383 __tuple_apply(
const tuple<_Ts...>&);
5385 template<
typename _Tp>
5386 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5391 template<forward_range _Vp,
size_t _Nm>
5392 requires view<_Vp> && (_Nm > 0)
5393 template<bool _Const>
5394 class adjacent_view<_Vp, _Nm>::_Iterator
5399 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5400 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5403 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5405 for (
auto& __i : _M_current)
5408 ranges::advance(__first, 1, __last);
5413 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5415 if constexpr (!bidirectional_range<_Base>)
5416 for (
auto& __it : _M_current)
5419 for (
size_t __i = 0; __i < _Nm; ++__i)
5421 _M_current[_Nm - 1 - __i] = __last;
5422 ranges::advance(__last, -1, __first);
5429 if constexpr (random_access_range<_Base>)
5430 return random_access_iterator_tag{};
5431 else if constexpr (bidirectional_range<_Base>)
5432 return bidirectional_iterator_tag{};
5434 return forward_iterator_tag{};
5437 friend class adjacent_view;
5440 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5441 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5442 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5443 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5444 range_reference_t<_Wp>>>
5445 friend class adjacent_transform_view;
5449 using iterator_category = input_iterator_tag;
5450 using iterator_concept =
decltype(_S_iter_concept());
5452 pair<range_value_t<_Base>, range_value_t<_Base>>,
5453 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5454 using difference_type = range_difference_t<_Base>;
5456 _Iterator() =
default;
5459 _Iterator(_Iterator<!_Const> __i)
5460 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5462 for (
size_t __j = 0; __j < _Nm; ++__j)
5463 _M_current[__j] =
std::move(__i._M_current[__j]);
5469 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5470 return __detail::__tuple_transform(__f, _M_current);
5473 constexpr _Iterator&
5476 for (
auto& __i : _M_current)
5489 constexpr _Iterator&
5490 operator--()
requires bidirectional_range<_Base>
5492 for (
auto& __i : _M_current)
5498 operator--(
int)
requires bidirectional_range<_Base>
5505 constexpr _Iterator&
5506 operator+=(difference_type __x)
5507 requires random_access_range<_Base>
5509 for (
auto& __i : _M_current)
5514 constexpr _Iterator&
5515 operator-=(difference_type __x)
5516 requires random_access_range<_Base>
5518 for (
auto& __i : _M_current)
5524 operator[](difference_type __n)
const
5525 requires random_access_range<_Base>
5527 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5528 return __detail::__tuple_transform(__f, _M_current);
5531 friend constexpr bool
5532 operator==(
const _Iterator& __x,
const _Iterator& __y)
5533 {
return __x._M_current.back() == __y._M_current.back(); }
5535 friend constexpr bool
5536 operator<(
const _Iterator& __x,
const _Iterator& __y)
5537 requires random_access_range<_Base>
5538 {
return __x._M_current.back() < __y._M_current.back(); }
5540 friend constexpr bool
5541 operator>(
const _Iterator& __x,
const _Iterator& __y)
5542 requires random_access_range<_Base>
5543 {
return __y < __x; }
5545 friend constexpr bool
5546 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5547 requires random_access_range<_Base>
5548 {
return !(__y < __x); }
5550 friend constexpr bool
5551 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5552 requires random_access_range<_Base>
5553 {
return !(__x < __y); }
5555 friend constexpr auto
5556 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5557 requires random_access_range<_Base>
5558 && three_way_comparable<iterator_t<_Base>>
5559 {
return __x._M_current.back() <=> __y._M_current.back(); }
5561 friend constexpr _Iterator
5562 operator+(
const _Iterator& __i, difference_type __n)
5563 requires random_access_range<_Base>
5570 friend constexpr _Iterator
5571 operator+(difference_type __n,
const _Iterator& __i)
5572 requires random_access_range<_Base>
5579 friend constexpr _Iterator
5580 operator-(
const _Iterator& __i, difference_type __n)
5581 requires random_access_range<_Base>
5588 friend constexpr difference_type
5589 operator-(
const _Iterator& __x,
const _Iterator& __y)
5590 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5591 {
return __x._M_current.back() - __y._M_current.back(); }
5593 friend constexpr auto
5594 iter_move(
const _Iterator& __i)
5595 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5597 friend constexpr void
5598 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5599 requires indirectly_swappable<iterator_t<_Base>>
5601 for (
size_t __i = 0; __i < _Nm; __i++)
5602 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5606 template<forward_range _Vp,
size_t _Nm>
5607 requires view<_Vp> && (_Nm > 0)
5608 template<bool _Const>
5609 class adjacent_view<_Vp, _Nm>::_Sentinel
5611 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5613 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5616 _Sentinel(sentinel_t<_Base> __end)
5620 friend class adjacent_view;
5623 _Sentinel() =
default;
5626 _Sentinel(_Sentinel<!_Const> __i)
5627 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5631 template<
bool _OtherConst>
5632 requires sentinel_for<sentinel_t<_Base>,
5633 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5634 friend constexpr bool
5635 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5636 {
return __x._M_current.back() == __y._M_end; }
5638 template<
bool _OtherConst>
5639 requires sized_sentinel_for<sentinel_t<_Base>,
5640 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5641 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5642 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5643 {
return __x._M_current.back() - __y._M_end; }
5645 template<
bool _OtherConst>
5646 requires sized_sentinel_for<sentinel_t<_Base>,
5647 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5648 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5649 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5650 {
return __y._M_end - __x._M_current.back(); }
5657 template<
size_t _Nm,
typename _Range>
5658 concept __can_adjacent_view
5659 =
requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5662 template<
size_t _Nm>
5663 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5665 template<viewable_range _Range>
5666 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5668 operator() [[nodiscard]] (_Range&& __r)
const
5670 if constexpr (_Nm == 0)
5671 return views::empty<tuple<>>;
5673 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5677 template<
size_t _Nm>
5678 inline constexpr _Adjacent<_Nm> adjacent;
5680 inline constexpr auto pairwise = adjacent<2>;
5683 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5684 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5685 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5686 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5687 range_reference_t<_Vp>>>
5688 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5690 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5691 adjacent_view<_Vp, _Nm> _M_inner;
5693 using _InnerView = adjacent_view<_Vp, _Nm>;
5695 template<
bool _Const>
5696 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5698 template<
bool _Const>
5699 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5701 template<
bool>
class _Iterator;
5702 template<
bool>
class _Sentinel;
5705 adjacent_transform_view() =
default;
5708 adjacent_transform_view(_Vp __base, _Fp __fun)
5714 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5718 requires range<const _InnerView>
5719 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5720 range_reference_t<const _Vp>>
5721 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5726 if constexpr (common_range<_InnerView>)
5727 return _Iterator<false>(*
this, _M_inner.end());
5729 return _Sentinel<false>(_M_inner.end());
5734 requires range<const _InnerView>
5735 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5736 range_reference_t<const _Vp>>
5738 if constexpr (common_range<const _InnerView>)
5739 return _Iterator<true>(*
this, _M_inner.end());
5741 return _Sentinel<true>(_M_inner.end());
5745 size()
requires sized_range<_InnerView>
5746 {
return _M_inner.size(); }
5749 size() const requires sized_range<const _InnerView>
5750 {
return _M_inner.size(); }
5753 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5754 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5755 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5756 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5757 range_reference_t<_Vp>>>
5758 template<bool _Const>
5759 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5761 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5762 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5764 _Parent* _M_parent =
nullptr;
5765 _InnerIter<_Const> _M_inner;
5768 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5775 using __detail::__maybe_const_t;
5776 using __detail::__unarize;
5777 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5778 range_reference_t<_Base>>;
5779 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
5780 if constexpr (!is_lvalue_reference_v<_Res>)
5781 return input_iterator_tag{};
5782 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5783 return random_access_iterator_tag{};
5784 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5785 return bidirectional_iterator_tag{};
5786 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5787 return forward_iterator_tag{};
5789 return input_iterator_tag{};
5792 friend class adjacent_transform_view;
5795 using iterator_category =
decltype(_S_iter_cat());
5796 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
5798 = remove_cvref_t<invoke_result_t
5799 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5800 range_reference_t<_Base>>>;
5801 using difference_type = range_difference_t<_Base>;
5803 _Iterator() =
default;
5806 _Iterator(_Iterator<!_Const> __i)
5807 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5808 : _M_parent(__i._M_parent), _M_inner(
std::move(__i._M_inner))
5811 constexpr decltype(
auto)
5814 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5816 }, _M_inner._M_current);
5819 constexpr _Iterator&
5834 constexpr _Iterator&
5835 operator--()
requires bidirectional_range<_Base>
5842 operator--(
int)
requires bidirectional_range<_Base>
5849 constexpr _Iterator&
5850 operator+=(difference_type __x)
requires random_access_range<_Base>
5856 constexpr _Iterator&
5857 operator-=(difference_type __x)
requires random_access_range<_Base>
5863 constexpr decltype(
auto)
5864 operator[](difference_type __n)
const requires random_access_range<_Base>
5866 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5868 }, _M_inner._M_current);
5871 friend constexpr bool
5872 operator==(
const _Iterator& __x,
const _Iterator& __y)
5873 {
return __x._M_inner == __y._M_inner; }
5875 friend constexpr bool
5876 operator<(
const _Iterator& __x,
const _Iterator& __y)
5877 requires random_access_range<_Base>
5878 {
return __x._M_inner < __y._M_inner; }
5880 friend constexpr bool
5881 operator>(
const _Iterator& __x,
const _Iterator& __y)
5882 requires random_access_range<_Base>
5883 {
return __x._M_inner > __y._M_inner; }
5885 friend constexpr bool
5886 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5887 requires random_access_range<_Base>
5888 {
return __x._M_inner <= __y._M_inner; }
5890 friend constexpr bool
5891 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5892 requires random_access_range<_Base>
5893 {
return __x._M_inner >= __y._M_inner; }
5895 friend constexpr auto
5896 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5897 requires random_access_range<_Base> &&
5898 three_way_comparable<_InnerIter<_Const>>
5899 {
return __x._M_inner <=> __y._M_inner; }
5901 friend constexpr _Iterator
5902 operator+(
const _Iterator& __i, difference_type __n)
5903 requires random_access_range<_Base>
5904 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5906 friend constexpr _Iterator
5907 operator+(difference_type __n,
const _Iterator& __i)
5908 requires random_access_range<_Base>
5909 {
return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5911 friend constexpr _Iterator
5912 operator-(
const _Iterator& __i, difference_type __n)
5913 requires random_access_range<_Base>
5914 {
return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5916 friend constexpr difference_type
5917 operator-(
const _Iterator& __x,
const _Iterator& __y)
5918 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5919 {
return __x._M_inner - __y._M_inner; }
5922 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5923 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5924 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5925 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5926 range_reference_t<_Vp>>>
5927 template<bool _Const>
5928 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5930 _InnerSent<_Const> _M_inner;
5933 _Sentinel(_InnerSent<_Const> __inner)
5937 friend class adjacent_transform_view;
5940 _Sentinel() =
default;
5943 _Sentinel(_Sentinel<!_Const> __i)
5944 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5948 template<
bool _OtherConst>
5949 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5950 friend constexpr bool
5951 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5952 {
return __x._M_inner == __y._M_inner; }
5954 template<
bool _OtherConst>
5955 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5956 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5957 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5958 {
return __x._M_inner - __y._M_inner; }
5960 template<
bool _OtherConst>
5961 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5962 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5963 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5964 {
return __x._M_inner - __y._M_inner; }
5971 template<
size_t _Nm,
typename _Range,
typename _Fp>
5972 concept __can_adjacent_transform_view
5973 =
requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5974 (std::declval<_Range>(), std::declval<_Fp>()); };
5977 template<
size_t _Nm>
5978 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5980 template<viewable_range _Range,
typename _Fp>
5981 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5983 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
5985 if constexpr (_Nm == 0)
5986 return zip_transform(std::forward<_Fp>(__f));
5988 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5989 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5992 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5993 static constexpr int _S_arity = 2;
5994 static constexpr bool _S_has_simple_extra_args =
true;
5997 template<
size_t _Nm>
5998 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6000 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6004#ifdef __cpp_lib_ranges_chunk
6007 template<
typename _Tp>
6008 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6010 _Tp __r = __num / __denom;
6011 if (__num % __denom)
6018 requires input_range<_Vp>
6019 class chunk_view :
public view_interface<chunk_view<_Vp>>
6022 range_difference_t<_Vp> _M_n;
6023 range_difference_t<_Vp> _M_remainder = 0;
6024 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6031 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6033 { __glibcxx_assert(__n >= 0); }
6036 base() const & requires copy_constructible<_Vp>
6043 constexpr _OuterIter
6046 _M_current = ranges::begin(_M_base);
6047 _M_remainder = _M_n;
6048 return _OuterIter(*
this);
6051 constexpr default_sentinel_t
6052 end() const noexcept
6056 size()
requires sized_range<_Vp>
6058 return __detail::__to_unsigned_like(__detail::__div_ceil
6059 (ranges::distance(_M_base), _M_n));
6063 size() const requires sized_range<const _Vp>
6065 return __detail::__to_unsigned_like(__detail::__div_ceil
6066 (ranges::distance(_M_base), _M_n));
6070 template<
typename _Range>
6071 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6074 requires input_range<_Vp>
6075 class chunk_view<_Vp>::_OuterIter
6077 chunk_view* _M_parent;
6080 _OuterIter(chunk_view& __parent) noexcept
6087 using iterator_concept = input_iterator_tag;
6088 using difference_type = range_difference_t<_Vp>;
6092 _OuterIter(_OuterIter&&) =
default;
6093 _OuterIter& operator=(_OuterIter&&) =
default;
6095 constexpr value_type
6098 __glibcxx_assert(*
this != default_sentinel);
6099 return value_type(*_M_parent);
6102 constexpr _OuterIter&
6105 __glibcxx_assert(*
this != default_sentinel);
6106 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6107 ranges::end(_M_parent->_M_base));
6108 _M_parent->_M_remainder = _M_parent->_M_n;
6116 friend constexpr bool
6117 operator==(
const _OuterIter& __x, default_sentinel_t)
6119 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6120 && __x._M_parent->_M_remainder != 0;
6123 friend constexpr difference_type
6124 operator-(default_sentinel_t,
const _OuterIter& __x)
6125 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6127 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6129 if (__dist < __x._M_parent->_M_remainder)
6130 return __dist == 0 ? 0 : 1;
6132 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6133 __x._M_parent->_M_n);
6136 friend constexpr difference_type
6137 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6138 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6139 {
return -(__y - __x); }
6143 requires input_range<_Vp>
6144 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6147 chunk_view* _M_parent;
6150 value_type(chunk_view& __parent) noexcept
6157 constexpr _InnerIter
6158 begin() const noexcept
6159 {
return _InnerIter(*_M_parent); }
6161 constexpr default_sentinel_t
6162 end() const noexcept
6167 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6169 return __detail::__to_unsigned_like
6170 (ranges::min(_M_parent->_M_remainder,
6171 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6176 requires input_range<_Vp>
6177 class chunk_view<_Vp>::_InnerIter
6179 chunk_view* _M_parent;
6182 _InnerIter(chunk_view& __parent) noexcept
6186 friend _OuterIter::value_type;
6189 using iterator_concept = input_iterator_tag;
6190 using difference_type = range_difference_t<_Vp>;
6191 using value_type = range_value_t<_Vp>;
6193 _InnerIter(_InnerIter&&) =
default;
6194 _InnerIter& operator=(_InnerIter&&) =
default;
6196 constexpr const iterator_t<_Vp>&
6198 {
return *_M_parent->_M_current; }
6200 constexpr range_reference_t<_Vp>
6203 __glibcxx_assert(*
this != default_sentinel);
6204 return **_M_parent->_M_current;
6207 constexpr _InnerIter&
6210 __glibcxx_assert(*
this != default_sentinel);
6211 ++*_M_parent->_M_current;
6212 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6213 _M_parent->_M_remainder = 0;
6215 --_M_parent->_M_remainder;
6223 friend constexpr bool
6224 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6225 {
return __x._M_parent->_M_remainder == 0; }
6227 friend constexpr difference_type
6228 operator-(default_sentinel_t,
const _InnerIter& __x)
6229 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6231 return ranges::min(__x._M_parent->_M_remainder,
6232 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6235 friend constexpr difference_type
6236 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6237 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6238 {
return -(__y - __x); }
6242 requires forward_range<_Vp>
6243 class chunk_view<_Vp> :
public view_interface<chunk_view<_Vp>>
6246 range_difference_t<_Vp> _M_n;
6247 template<
bool>
class _Iterator;
6251 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6253 { __glibcxx_assert(__n > 0); }
6256 base() const & requires copy_constructible<_Vp>
6264 begin()
requires (!__detail::__simple_view<_Vp>)
6265 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6268 begin() const requires forward_range<const _Vp>
6269 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6272 end()
requires (!__detail::__simple_view<_Vp>)
6274 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6276 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6277 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6279 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6280 return _Iterator<false>(
this, ranges::end(_M_base));
6286 end() const requires forward_range<const _Vp>
6288 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6290 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6291 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6293 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6294 return _Iterator<true>(
this, ranges::end(_M_base));
6300 size()
requires sized_range<_Vp>
6302 return __detail::__to_unsigned_like(__detail::__div_ceil
6303 (ranges::distance(_M_base), _M_n));
6307 size() const requires sized_range<const _Vp>
6309 return __detail::__to_unsigned_like(__detail::__div_ceil
6310 (ranges::distance(_M_base), _M_n));
6314 template<
typename _Vp>
6315 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6316 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6319 requires forward_range<_Vp>
6320 template<
bool _Const>
6321 class chunk_view<_Vp>::_Iterator
6323 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6324 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6326 iterator_t<_Base> _M_current = iterator_t<_Base>();
6327 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6328 range_difference_t<_Base> _M_n = 0;
6329 range_difference_t<_Base> _M_missing = 0;
6332 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6333 range_difference_t<_Base> __missing = 0)
6334 : _M_current(__current), _M_end(ranges::
end(__parent->_M_base)),
6335 _M_n(__parent->_M_n), _M_missing(__missing)
6341 if constexpr (random_access_range<_Base>)
6342 return random_access_iterator_tag{};
6343 else if constexpr (bidirectional_range<_Base>)
6344 return bidirectional_iterator_tag{};
6346 return forward_iterator_tag{};
6352 using iterator_category = input_iterator_tag;
6353 using iterator_concept =
decltype(_S_iter_cat());
6354 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6355 using difference_type = range_difference_t<_Base>;
6357 _Iterator() =
default;
6359 constexpr _Iterator(_Iterator<!_Const> __i)
6361 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6362 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6364 _M_n(__i._M_n), _M_missing(__i._M_missing)
6367 constexpr iterator_t<_Base>
6369 {
return _M_current; }
6371 constexpr value_type
6374 __glibcxx_assert(_M_current != _M_end);
6375 return views::take(subrange(_M_current, _M_end), _M_n);
6378 constexpr _Iterator&
6381 __glibcxx_assert(_M_current != _M_end);
6382 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6394 constexpr _Iterator&
6395 operator--()
requires bidirectional_range<_Base>
6397 ranges::advance(_M_current, _M_missing - _M_n);
6403 operator--(
int)
requires bidirectional_range<_Base>
6410 constexpr _Iterator&
6411 operator+=(difference_type __x)
6412 requires random_access_range<_Base>
6416 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6417 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6421 ranges::advance(_M_current, _M_n * __x + _M_missing);
6427 constexpr _Iterator&
6428 operator-=(difference_type __x)
6429 requires random_access_range<_Base>
6430 {
return *
this += -__x; }
6432 constexpr value_type
6433 operator[](difference_type __n)
const
6434 requires random_access_range<_Base>
6435 {
return *(*
this + __n); }
6437 friend constexpr bool
6438 operator==(
const _Iterator& __x,
const _Iterator& __y)
6439 {
return __x._M_current == __y._M_current; }
6441 friend constexpr bool
6442 operator==(
const _Iterator& __x, default_sentinel_t)
6443 {
return __x._M_current == __x._M_end; }
6445 friend constexpr bool
6446 operator<(
const _Iterator& __x,
const _Iterator& __y)
6447 requires random_access_range<_Base>
6448 {
return __x._M_current > __y._M_current; }
6450 friend constexpr bool
6451 operator>(
const _Iterator& __x,
const _Iterator& __y)
6452 requires random_access_range<_Base>
6453 {
return __y < __x; }
6455 friend constexpr bool
6456 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6457 requires random_access_range<_Base>
6458 {
return !(__y < __x); }
6460 friend constexpr bool
6461 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6462 requires random_access_range<_Base>
6463 {
return !(__x < __y); }
6465 friend constexpr auto
6466 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6467 requires random_access_range<_Base>
6468 && three_way_comparable<iterator_t<_Base>>
6469 {
return __x._M_current <=> __y._M_current; }
6471 friend constexpr _Iterator
6472 operator+(
const _Iterator& __i, difference_type __n)
6473 requires random_access_range<_Base>
6480 friend constexpr _Iterator
6481 operator+(difference_type __n,
const _Iterator& __i)
6482 requires random_access_range<_Base>
6489 friend constexpr _Iterator
6490 operator-(
const _Iterator& __i, difference_type __n)
6491 requires random_access_range<_Base>
6498 friend constexpr difference_type
6499 operator-(
const _Iterator& __x,
const _Iterator& __y)
6500 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6502 return (__x._M_current - __y._M_current
6503 + __x._M_missing - __y._M_missing) / __x._M_n;
6506 friend constexpr difference_type
6507 operator-(default_sentinel_t __y,
const _Iterator& __x)
6508 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6509 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6511 friend constexpr difference_type
6512 operator-(
const _Iterator& __x, default_sentinel_t __y)
6513 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6514 {
return -(__y - __x); }
6521 template<
typename _Range,
typename _Dp>
6522 concept __can_chunk_view
6523 =
requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6526 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6528 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6529 requires __detail::__can_chunk_view<_Range, _Dp>
6531 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6532 {
return chunk_view(std::forward<_Range>(__r), __n); }
6534 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6535 static constexpr int _S_arity = 2;
6536 static constexpr bool _S_has_simple_extra_args =
true;
6539 inline constexpr _Chunk chunk;
6543#ifdef __cpp_lib_ranges_slide
6546 template<
typename _Vp>
6547 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6549 template<
typename _Vp>
6550 concept __slide_caches_last
6551 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6553 template<
typename _Vp>
6554 concept __slide_caches_first
6555 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6558 template<forward_range _Vp>
6560 class slide_view :
public view_interface<slide_view<_Vp>>
6563 range_difference_t<_Vp> _M_n;
6564 [[no_unique_address]]
6565 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6566 __detail::_CachedPosition<_Vp>> _M_cached_begin;
6567 [[no_unique_address]]
6568 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6569 __detail::_CachedPosition<_Vp>> _M_cached_end;
6571 template<
bool>
class _Iterator;
6576 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6578 { __glibcxx_assert(__n > 0); }
6581 begin()
requires (!(__detail::__simple_view<_Vp>
6582 && __detail::__slide_caches_nothing<const _Vp>))
6584 if constexpr (__detail::__slide_caches_first<_Vp>)
6586 iterator_t<_Vp> __it;
6587 if (_M_cached_begin._M_has_value())
6588 __it = _M_cached_begin._M_get(_M_base);
6591 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6592 _M_cached_begin._M_set(_M_base, __it);
6594 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6597 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6601 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6602 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6605 end()
requires (!(__detail::__simple_view<_Vp>
6606 && __detail::__slide_caches_nothing<const _Vp>))
6608 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6609 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(
size()),
6611 else if constexpr (__detail::__slide_caches_last<_Vp>)
6613 iterator_t<_Vp> __it;
6614 if (_M_cached_end._M_has_value())
6615 __it = _M_cached_end._M_get(_M_base);
6618 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6619 _M_cached_end._M_set(_M_base, __it);
6621 return _Iterator<false>(
std::move(__it), _M_n);
6623 else if constexpr (common_range<_Vp>)
6624 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6626 return _Sentinel(ranges::end(_M_base));
6630 end() const requires __detail::__slide_caches_nothing<const _Vp>
6631 {
return begin() + range_difference_t<const _Vp>(
size()); }
6634 size()
requires sized_range<_Vp>
6636 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6639 return __detail::__to_unsigned_like(__sz);
6643 size() const requires sized_range<const _Vp>
6645 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6648 return __detail::__to_unsigned_like(__sz);
6652 template<
typename _Range>
6653 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6655 template<
typename _Vp>
6656 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6657 = enable_borrowed_range<_Vp>;
6659 template<forward_range _Vp>
6661 template<
bool _Const>
6662 class slide_view<_Vp>::_Iterator
6664 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6665 static constexpr bool _S_last_elt_present
6666 = __detail::__slide_caches_first<_Base>;
6668 iterator_t<_Base> _M_current = iterator_t<_Base>();
6669 [[no_unique_address]]
6670 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6671 _M_last_elt =
decltype(_M_last_elt)();
6672 range_difference_t<_Base> _M_n = 0;
6675 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6676 requires (!_S_last_elt_present)
6677 : _M_current(__current), _M_n(__n)
6681 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6682 range_difference_t<_Base> __n)
6683 requires _S_last_elt_present
6684 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6690 if constexpr (random_access_range<_Base>)
6691 return random_access_iterator_tag{};
6692 else if constexpr (bidirectional_range<_Base>)
6693 return bidirectional_iterator_tag{};
6695 return forward_iterator_tag{};
6699 friend slide_view::_Sentinel;
6702 using iterator_category = input_iterator_tag;
6703 using iterator_concept =
decltype(_S_iter_concept());
6704 using value_type =
decltype(views::counted(_M_current, _M_n));
6705 using difference_type = range_difference_t<_Base>;
6707 _Iterator() =
default;
6710 _Iterator(_Iterator<!_Const> __i)
6711 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6712 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
6717 {
return views::counted(_M_current, _M_n); }
6719 constexpr _Iterator&
6723 if constexpr (_S_last_elt_present)
6736 constexpr _Iterator&
6737 operator--()
requires bidirectional_range<_Base>
6740 if constexpr (_S_last_elt_present)
6746 operator--(
int)
requires bidirectional_range<_Base>
6753 constexpr _Iterator&
6754 operator+=(difference_type __x)
6755 requires random_access_range<_Base>
6758 if constexpr (_S_last_elt_present)
6763 constexpr _Iterator&
6764 operator-=(difference_type __x)
6765 requires random_access_range<_Base>
6768 if constexpr (_S_last_elt_present)
6774 operator[](difference_type __n)
const
6775 requires random_access_range<_Base>
6776 {
return views::counted(_M_current + __n, _M_n); }
6778 friend constexpr bool
6779 operator==(
const _Iterator& __x,
const _Iterator& __y)
6781 if constexpr (_S_last_elt_present)
6782 return __x._M_last_elt == __y._M_last_elt;
6784 return __x._M_current == __y._M_current;
6787 friend constexpr bool
6788 operator<(
const _Iterator& __x,
const _Iterator& __y)
6789 requires random_access_range<_Base>
6790 {
return __x._M_current < __y._M_current; }
6792 friend constexpr bool
6793 operator>(
const _Iterator& __x,
const _Iterator& __y)
6794 requires random_access_range<_Base>
6795 {
return __y < __x; }
6797 friend constexpr bool
6798 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6799 requires random_access_range<_Base>
6800 {
return !(__y < __x); }
6802 friend constexpr bool
6803 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6804 requires random_access_range<_Base>
6805 {
return !(__x < __y); }
6807 friend constexpr auto
6808 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6809 requires random_access_range<_Base>
6810 && three_way_comparable<iterator_t<_Base>>
6811 {
return __x._M_current <=> __y._M_current; }
6813 friend constexpr _Iterator
6814 operator+(
const _Iterator& __i, difference_type __n)
6815 requires random_access_range<_Base>
6822 friend constexpr _Iterator
6823 operator+(difference_type __n,
const _Iterator& __i)
6824 requires random_access_range<_Base>
6831 friend constexpr _Iterator
6832 operator-(
const _Iterator& __i, difference_type __n)
6833 requires random_access_range<_Base>
6840 friend constexpr difference_type
6841 operator-(
const _Iterator& __x,
const _Iterator& __y)
6842 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6844 if constexpr (_S_last_elt_present)
6845 return __x._M_last_elt - __y._M_last_elt;
6847 return __x._M_current - __y._M_current;
6851 template<forward_range _Vp>
6853 class slide_view<_Vp>::_Sentinel
6855 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6858 _Sentinel(sentinel_t<_Vp> __end)
6865 _Sentinel() =
default;
6867 friend constexpr bool
6868 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
6869 {
return __x._M_last_elt == __y._M_end; }
6871 friend constexpr range_difference_t<_Vp>
6872 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
6873 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6874 {
return __x._M_last_elt - __y._M_end; }
6876 friend constexpr range_difference_t<_Vp>
6877 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
6878 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6879 {
return __y._M_end -__x._M_last_elt; }
6886 template<
typename _Range,
typename _Dp>
6887 concept __can_slide_view
6888 =
requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6891 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6893 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6894 requires __detail::__can_slide_view<_Range, _Dp>
6896 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6897 {
return slide_view(std::forward<_Range>(__r), __n); }
6899 using __adaptor::_RangeAdaptor<_Slide>::operator();
6900 static constexpr int _S_arity = 2;
6901 static constexpr bool _S_has_simple_extra_args =
true;
6904 inline constexpr _Slide slide;
6908#ifdef __cpp_lib_ranges_chunk_by
6909 template<forward_range _Vp,
6910 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6911 requires view<_Vp> && is_object_v<_Pred>
6912 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
6914 _Vp _M_base = _Vp();
6915 __detail::__box<_Pred> _M_pred;
6916 __detail::_CachedPosition<_Vp> _M_cached_begin;
6918 constexpr iterator_t<_Vp>
6919 _M_find_next(iterator_t<_Vp> __current)
6921 __glibcxx_assert(_M_pred.has_value());
6922 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
6923 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6925 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6926 return ranges::next(__it, 1, ranges::end(_M_base));
6929 constexpr iterator_t<_Vp>
6930 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
6932 __glibcxx_assert(_M_pred.has_value());
6933 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
6934 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6938 __glibcxx_assert(__rbegin != __rend);
6939 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6940 return ranges::prev(__it, 1, ranges::begin(_M_base));
6946 chunk_by_view()
requires (default_initializable<_Vp>
6947 && default_initializable<_Pred>)
6951 chunk_by_view(_Vp __base, _Pred __pred)
6956 base() const & requires copy_constructible<_Vp>
6963 constexpr const _Pred&
6965 {
return *_M_pred; }
6970 __glibcxx_assert(_M_pred.has_value());
6971 iterator_t<_Vp> __it;
6972 if (_M_cached_begin._M_has_value())
6973 __it = _M_cached_begin._M_get(_M_base);
6976 __it = _M_find_next(ranges::begin(_M_base));
6977 _M_cached_begin._M_set(_M_base, __it);
6979 return _Iterator(*
this, ranges::begin(_M_base), __it);
6985 if constexpr (common_range<_Vp>)
6986 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
6992 template<
typename _Range,
typename _Pred>
6993 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6995 template<forward_range _Vp,
6996 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6997 requires view<_Vp> && is_object_v<_Pred>
6998 class chunk_by_view<_Vp, _Pred>::_Iterator
7000 chunk_by_view* _M_parent =
nullptr;
7001 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7002 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7005 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7006 : _M_parent(
std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7012 if constexpr (bidirectional_range<_Vp>)
7013 return bidirectional_iterator_tag{};
7015 return forward_iterator_tag{};
7018 friend chunk_by_view;
7021 using value_type = subrange<iterator_t<_Vp>>;
7022 using difference_type = range_difference_t<_Vp>;
7023 using iterator_category = input_iterator_tag;
7024 using iterator_concept =
decltype(_S_iter_concept());
7026 _Iterator() =
default;
7028 constexpr value_type
7031 __glibcxx_assert(_M_current != _M_next);
7032 return ranges::subrange(_M_current, _M_next);
7035 constexpr _Iterator&
7038 __glibcxx_assert(_M_current != _M_next);
7039 _M_current = _M_next;
7040 _M_next = _M_parent->_M_find_next(_M_current);
7052 constexpr _Iterator&
7053 operator--()
requires bidirectional_range<_Vp>
7055 _M_next = _M_current;
7056 _M_current = _M_parent->_M_find_prev(_M_next);
7061 operator--(
int)
requires bidirectional_range<_Vp>
7068 friend constexpr bool
7069 operator==(
const _Iterator& __x,
const _Iterator& __y)
7070 {
return __x._M_current == __y._M_current; }
7072 friend constexpr bool
7073 operator==(
const _Iterator& __x, default_sentinel_t)
7074 {
return __x._M_current == __x._M_next; }
7081 template<
typename _Range,
typename _Pred>
7082 concept __can_chunk_by_view
7083 =
requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7086 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7088 template<viewable_range _Range,
typename _Pred>
7089 requires __detail::__can_chunk_by_view<_Range, _Pred>
7091 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7092 {
return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7094 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7095 static constexpr int _S_arity = 2;
7096 static constexpr bool _S_has_simple_extra_args =
true;
7099 inline constexpr _ChunkBy chunk_by;
7103#ifdef __cpp_lib_ranges_join_with
7106 template<
typename _Range,
typename _Pattern>
7107 concept __compatible_joinable_ranges
7108 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7109 && common_reference_with<range_reference_t<_Range>,
7110 range_reference_t<_Pattern>>
7111 && common_reference_with<range_rvalue_reference_t<_Range>,
7112 range_rvalue_reference_t<_Pattern>>;
7114 template<
typename _Range>
7115 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7118 template<input_range _Vp, forward_range _Pattern>
7119 requires view<_Vp> && view<_Pattern>
7120 && input_range<range_reference_t<_Vp>>
7121 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7122 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7124 using _InnerRange = range_reference_t<_Vp>;
7126 _Vp _M_base = _Vp();
7127 [[no_unique_address]]
7128 __detail::__maybe_present_t<!forward_range<_Vp>,
7129 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7130 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7131 _Pattern _M_pattern = _Pattern();
7133 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7134 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7135 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7137 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7138 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7139 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7141 template<
bool _Const>
7142 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7144 template<
bool _Const>
7148 template<
bool _Const>
7149 requires _S_ref_is_glvalue<_Const>
7150 && forward_range<_Base<_Const>>
7151 && forward_range<_InnerBase<_Const>>
7152 struct __iter_cat<_Const>
7158 using _OuterIter = join_with_view::_OuterIter<_Const>;
7159 using _InnerIter = join_with_view::_InnerIter<_Const>;
7160 using _PatternIter = join_with_view::_PatternIter<_Const>;
7161 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7162 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7163 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7164 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7165 iter_reference_t<_PatternIter>>>)
7166 return input_iterator_tag{};
7167 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7168 && derived_from<_InnerCat, bidirectional_iterator_tag>
7169 && derived_from<_PatternCat, bidirectional_iterator_tag>
7170 && common_range<_InnerBase<_Const>>
7171 && common_range<_PatternBase<_Const>>)
7172 return bidirectional_iterator_tag{};
7173 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7174 && derived_from<_InnerCat, forward_iterator_tag>
7175 && derived_from<_PatternCat, forward_iterator_tag>)
7176 return forward_iterator_tag{};
7178 return input_iterator_tag{};
7181 using iterator_category =
decltype(_S_iter_cat());
7184 template<
bool>
struct _Iterator;
7185 template<
bool>
struct _Sentinel;
7188 join_with_view()
requires (default_initializable<_Vp>
7189 && default_initializable<_Pattern>)
7193 join_with_view(_Vp __base, _Pattern __pattern)
7197 template<input_range _Range>
7198 requires constructible_from<_Vp, views::all_t<_Range>>
7199 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7201 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7202 : _M_base(views::all(
std::
forward<_Range>(__r))),
7203 _M_pattern(views::single(
std::
move(__e)))
7207 base() const& requires copy_constructible<_Vp>
7217 if constexpr (forward_range<_Vp>)
7219 constexpr bool __use_const = is_reference_v<_InnerRange>
7220 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7221 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7225 _M_outer_it = ranges::begin(_M_base);
7226 return _Iterator<false>{*
this};
7232 requires forward_range<const _Vp>
7233 && forward_range<const _Pattern>
7234 && is_reference_v<range_reference_t<const _Vp>>
7235 && input_range<range_reference_t<const _Vp>>
7236 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7241 constexpr bool __use_const
7242 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7243 if constexpr (is_reference_v<_InnerRange>
7244 && forward_range<_Vp> && common_range<_Vp>
7245 && forward_range<_InnerRange> && common_range<_InnerRange>)
7246 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7248 return _Sentinel<__use_const>{*
this};
7253 requires forward_range<const _Vp>
7254 && forward_range<const _Pattern>
7255 && is_reference_v<range_reference_t<const _Vp>>
7256 && input_range<range_reference_t<const _Vp>>
7258 using _InnerConstRange = range_reference_t<const _Vp>;
7259 if constexpr (forward_range<_InnerConstRange>
7260 && common_range<const _Vp>
7261 && common_range<_InnerConstRange>)
7262 return _Iterator<true>{*
this, ranges::end(_M_base)};
7264 return _Sentinel<true>{*
this};
7268 template<
typename _Range,
typename _Pattern>
7269 join_with_view(_Range&&, _Pattern&&)
7270 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7272 template<input_range _Range>
7273 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7274 -> join_with_view<views::all_t<_Range>,
7275 single_view<range_value_t<range_reference_t<_Range>>>>;
7277 template<input_range _Vp, forward_range _Pattern>
7278 requires view<_Vp> && view<_Pattern>
7279 && input_range<range_reference_t<_Vp>>
7280 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7281 template<
bool _Const>
7282 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7284 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7285 using _Base = join_with_view::_Base<_Const>;
7286 using _InnerBase = join_with_view::_InnerBase<_Const>;
7287 using _PatternBase = join_with_view::_PatternBase<_Const>;
7289 using _OuterIter = join_with_view::_OuterIter<_Const>;
7290 using _InnerIter = join_with_view::_InnerIter<_Const>;
7291 using _PatternIter = join_with_view::_PatternIter<_Const>;
7293 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7295 _Parent* _M_parent =
nullptr;
7296 [[no_unique_address]]
7297 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7298 variant<_PatternIter, _InnerIter> _M_inner_it;
7300 constexpr _OuterIter&
7303 if constexpr (forward_range<_Base>)
7306 return *_M_parent->_M_outer_it;
7309 constexpr const _OuterIter&
7310 _M_get_outer()
const
7312 if constexpr (forward_range<_Base>)
7315 return *_M_parent->_M_outer_it;
7319 _Iterator(_Parent& __parent, _OuterIter __outer)
7320 requires forward_range<_Base>
7323 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7325 auto&& __inner = _M_update_inner();
7326 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7332 _Iterator(_Parent& __parent)
7333 requires (!forward_range<_Base>)
7336 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7338 auto&& __inner = _M_update_inner();
7339 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7347 _OuterIter& __outer = _M_get_outer();
7348 if constexpr (_S_ref_is_glvalue)
7349 return __detail::__as_lvalue(*__outer);
7351 return _M_parent->_M_inner._M_emplace_deref(__outer);
7357 if constexpr (_S_ref_is_glvalue)
7358 return __detail::__as_lvalue(*_M_get_outer());
7360 return *_M_parent->_M_inner;
7368 if (_M_inner_it.index() == 0)
7370 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7373 auto&& __inner = _M_update_inner();
7374 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7378 auto&& __inner = _M_get_inner();
7379 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7382 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7384 if constexpr (_S_ref_is_glvalue)
7385 _M_inner_it.template emplace<0>();
7389 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7397 if constexpr (_S_ref_is_glvalue
7398 && bidirectional_range<_Base>
7399 && __detail::__bidirectional_common<_InnerBase>
7400 && __detail::__bidirectional_common<_PatternBase>)
7401 return bidirectional_iterator_tag{};
7402 else if constexpr (_S_ref_is_glvalue
7403 && forward_range<_Base>
7404 && forward_range<_InnerBase>)
7405 return forward_iterator_tag{};
7407 return input_iterator_tag{};
7410 friend join_with_view;
7413 using iterator_concept =
decltype(_S_iter_concept());
7415 using value_type = common_type_t<iter_value_t<_InnerIter>,
7416 iter_value_t<_PatternIter>>;
7417 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7418 iter_difference_t<_InnerIter>,
7419 iter_difference_t<_PatternIter>>;
7421 _Iterator() =
default;
7424 _Iterator(_Iterator<!_Const> __i)
7426 && convertible_to<iterator_t<_Vp>, _OuterIter>
7427 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7428 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7429 : _M_parent(__i._M_parent),
7432 if (__i._M_inner_it.index() == 0)
7433 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7435 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7438 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7439 iter_reference_t<_PatternIter>>
7442 if (_M_inner_it.index() == 0)
7443 return *std::get<0>(_M_inner_it);
7445 return *std::get<1>(_M_inner_it);
7448 constexpr _Iterator&
7451 if (_M_inner_it.index() == 0)
7452 ++std::get<0>(_M_inner_it);
7454 ++std::get<1>(_M_inner_it);
7465 requires _S_ref_is_glvalue
7466 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7468 _Iterator __tmp = *
this;
7473 constexpr _Iterator&
7475 requires _S_ref_is_glvalue
7476 && bidirectional_range<_Base>
7477 && __detail::__bidirectional_common<_InnerBase>
7478 && __detail::__bidirectional_common<_PatternBase>
7480 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7482 auto&& __inner = *--_M_outer_it;
7483 _M_inner_it.template emplace<1>(ranges::end(__inner));
7488 if (_M_inner_it.index() == 0)
7490 auto& __it = std::get<0>(_M_inner_it);
7491 if (__it == ranges::begin(_M_parent->_M_pattern))
7493 auto&& __inner = *--_M_outer_it;
7494 _M_inner_it.template emplace<1>(ranges::end(__inner));
7501 auto& __it = std::get<1>(_M_inner_it);
7502 auto&& __inner = *_M_outer_it;
7503 if (__it == ranges::begin(__inner))
7504 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7510 if (_M_inner_it.index() == 0)
7511 --std::get<0>(_M_inner_it);
7513 --std::get<1>(_M_inner_it);
7519 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7520 && __detail::__bidirectional_common<_InnerBase>
7521 && __detail::__bidirectional_common<_PatternBase>
7523 _Iterator __tmp = *
this;
7528 friend constexpr bool
7529 operator==(
const _Iterator& __x,
const _Iterator& __y)
7530 requires _S_ref_is_glvalue
7531 && forward_range<_Base> && equality_comparable<_InnerIter>
7532 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7534 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7535 iter_rvalue_reference_t<_PatternIter>>
7536 iter_move(
const _Iterator& __x)
7538 if (__x._M_inner_it.index() == 0)
7539 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7541 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7544 friend constexpr void
7545 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7546 requires indirectly_swappable<_InnerIter, _PatternIter>
7548 if (__x._M_inner_it.index() == 0)
7550 if (__y._M_inner_it.index() == 0)
7551 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7553 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7557 if (__y._M_inner_it.index() == 0)
7558 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7560 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7565 template<input_range _Vp, forward_range _Pattern>
7566 requires view<_Vp> && view<_Pattern>
7567 && input_range<range_reference_t<_Vp>>
7568 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7569 template<
bool _Const>
7570 class join_with_view<_Vp, _Pattern>::_Sentinel
7572 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7573 using _Base = join_with_view::_Base<_Const>;
7575 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7578 _Sentinel(_Parent& __parent)
7579 : _M_end(ranges::
end(__parent._M_base))
7582 friend join_with_view;
7585 _Sentinel() =
default;
7588 _Sentinel(_Sentinel<!_Const> __s)
7589 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7593 template<
bool _OtherConst>
7594 requires sentinel_for<sentinel_t<_Base>,
7595 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7596 friend constexpr bool
7597 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7598 {
return __x._M_get_outer() == __y._M_end; }
7605 template<
typename _Range,
typename _Pattern>
7606 concept __can_join_with_view
7607 =
requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7610 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7612 template<viewable_range _Range,
typename _Pattern>
7613 requires __detail::__can_join_with_view<_Range, _Pattern>
7615 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7617 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7620 using _RangeAdaptor<_JoinWith>::operator();
7621 static constexpr int _S_arity = 2;
7622 template<
typename _Pattern>
7623 static constexpr bool _S_has_simple_extra_args
7624 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7627 inline constexpr _JoinWith join_with;
7631#ifdef __cpp_lib_ranges_repeat
7632 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7633 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7634 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7635 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7637 __detail::__box<_Tp> _M_value;
7638 [[no_unique_address]] _Bound _M_bound = _Bound();
7642 template<
typename _Range>
7643 friend constexpr auto
7644 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7646 template<
typename _Range>
7647 friend constexpr auto
7648 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7651 repeat_view()
requires default_initializable<_Tp> = default;
7654 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7655 requires copy_constructible<_Tp>
7656 : _M_value(__value), _M_bound(__bound)
7658 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7659 __glibcxx_assert(__bound >= 0);
7663 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7664 : _M_value(
std::
move(__value)), _M_bound(__bound)
7667 template<
typename... _Args,
typename... _BoundArgs>
7668 requires constructible_from<_Tp, _Args...>
7669 && constructible_from<_Bound, _BoundArgs...>
7671 repeat_view(piecewise_construct_t,
7672 tuple<_Args...> __args,
7673 tuple<_BoundArgs...> __bound_args = tuple<>{})
7674 : _M_value(
std::make_from_tuple<_Tp>(
std::
move(__args))),
7675 _M_bound(
std::make_from_tuple<_Bound>(
std::
move(__bound_args)))
7683 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7686 constexpr unreachable_sentinel_t
7687 end() const noexcept
7688 {
return unreachable_sentinel; }
7691 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7692 {
return __detail::__to_unsigned_like(_M_bound); }
7695 template<
typename _Tp,
typename _Bound>
7696 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7698 template<move_constructible _Tp, semiregular _Bound>
7699 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7700 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7701 class repeat_view<_Tp, _Bound>::_Iterator
7704 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7706 const _Tp* _M_value =
nullptr;
7707 __index_type _M_current = __index_type();
7710 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
7711 : _M_value(__value), _M_current(__bound)
7713 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7714 __glibcxx_assert(__bound >= 0);
7720 using iterator_concept = random_access_iterator_tag;
7721 using iterator_category = random_access_iterator_tag;
7722 using value_type = _Tp;
7723 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7725 __detail::__iota_diff_t<__index_type>>;
7727 _Iterator() =
default;
7729 constexpr const _Tp&
7731 {
return *_M_value; }
7733 constexpr _Iterator&
7748 constexpr _Iterator&
7751 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7752 __glibcxx_assert(_M_current > 0);
7765 constexpr _Iterator&
7766 operator+=(difference_type __n)
7768 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7769 __glibcxx_assert(_M_current + __n >= 0);
7774 constexpr _Iterator&
7775 operator-=(difference_type __n)
7777 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7778 __glibcxx_assert(_M_current - __n >= 0);
7783 constexpr const _Tp&
7784 operator[](difference_type __n)
const noexcept
7785 {
return *(*
this + __n); }
7787 friend constexpr bool
7788 operator==(
const _Iterator& __x,
const _Iterator& __y)
7789 {
return __x._M_current == __y._M_current; }
7791 friend constexpr auto
7792 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7793 {
return __x._M_current <=> __y._M_current; }
7795 friend constexpr _Iterator
7796 operator+(_Iterator __i, difference_type __n)
7802 friend constexpr _Iterator
7803 operator+(difference_type __n, _Iterator __i)
7804 {
return __i + __n; }
7806 friend constexpr _Iterator
7807 operator-(_Iterator __i, difference_type __n)
7813 friend constexpr difference_type
7814 operator-(
const _Iterator& __x,
const _Iterator& __y)
7816 return (
static_cast<difference_type
>(__x._M_current)
7817 -
static_cast<difference_type
>(__y._M_current));
7825 template<
typename _Tp,
typename _Bound>
7826 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
7828 template<
typename _Tp>
7829 concept __can_repeat_view
7830 =
requires { repeat_view(std::declval<_Tp>()); };
7832 template<
typename _Tp,
typename _Bound>
7833 concept __can_bounded_repeat_view
7834 =
requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7839 template<
typename _Tp>
7840 requires __detail::__can_repeat_view<_Tp>
7842 operator() [[nodiscard]] (_Tp&& __value)
const
7843 {
return repeat_view(std::forward<_Tp>(__value)); }
7845 template<
typename _Tp,
typename _Bound>
7846 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7848 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
7849 {
return repeat_view(std::forward<_Tp>(__value), __bound); }
7852 inline constexpr _Repeat repeat;
7856 template<
typename _Range>
7858 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7860 using _Tp = remove_cvref_t<_Range>;
7861 static_assert(__is_repeat_view<_Tp>);
7862 if constexpr (sized_range<_Tp>)
7863 return views::repeat(*std::forward<_Range>(__r)._M_value,
7864 std::min(ranges::distance(__r), __n));
7866 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7869 template<
typename _Range>
7871 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7873 using _Tp = remove_cvref_t<_Range>;
7874 static_assert(__is_repeat_view<_Tp>);
7875 if constexpr (sized_range<_Tp>)
7877 auto __sz = ranges::distance(__r);
7878 return views::repeat(*std::forward<_Range>(__r)._M_value,
7888#ifdef __cpp_lib_ranges_stride
7889 template<input_range _Vp>
7891 class stride_view :
public view_interface<stride_view<_Vp>>
7894 range_difference_t<_Vp> _M_stride;
7896 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7898 template<
bool _Const>
7902 template<
bool _Const>
7903 requires forward_range<_Base<_Const>>
7904 struct __iter_cat<_Const>
7910 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7911 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7912 return random_access_iterator_tag{};
7917 using iterator_category =
decltype(_S_iter_cat());
7920 template<
bool>
class _Iterator;
7924 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7926 { __glibcxx_assert(__stride > 0); }
7929 base() const& requires copy_constructible<_Vp>
7936 constexpr range_difference_t<_Vp>
7937 stride() const noexcept
7938 {
return _M_stride; }
7941 begin()
requires (!__detail::__simple_view<_Vp>)
7942 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
7945 begin() const requires range<const _Vp>
7946 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
7949 end()
requires (!__detail::__simple_view<_Vp>)
7951 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7953 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7954 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
7956 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7957 return _Iterator<false>(
this, ranges::end(_M_base));
7963 end() const requires range<const _Vp>
7965 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7966 && forward_range<const _Vp>)
7968 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7969 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
7971 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7972 return _Iterator<true>(
this, ranges::end(_M_base));
7978 size()
requires sized_range<_Vp>
7980 return __detail::__to_unsigned_like
7981 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7985 size() const requires sized_range<const _Vp>
7987 return __detail::__to_unsigned_like
7988 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7992 template<
typename _Range>
7993 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7995 template<
typename _Vp>
7996 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7997 = enable_borrowed_range<_Vp>;
7999 template<input_range _Vp>
8001 template<
bool _Const>
8002 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8004 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8005 using _Base = stride_view::_Base<_Const>;
8007 iterator_t<_Base> _M_current = iterator_t<_Base>();
8008 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8009 range_difference_t<_Base> _M_stride = 0;
8010 range_difference_t<_Base> _M_missing = 0;
8013 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8014 range_difference_t<_Base> __missing = 0)
8015 : _M_current(
std::
move(__current)), _M_end(ranges::
end(__parent->_M_base)),
8016 _M_stride(__parent->_M_stride), _M_missing(__missing)
8022 if constexpr (random_access_range<_Base>)
8023 return random_access_iterator_tag{};
8024 else if constexpr (bidirectional_range<_Base>)
8025 return bidirectional_iterator_tag{};
8026 else if constexpr (forward_range<_Base>)
8027 return forward_iterator_tag{};
8029 return input_iterator_tag{};
8035 using difference_type = range_difference_t<_Base>;
8036 using value_type = range_value_t<_Base>;
8037 using iterator_concept =
decltype(_S_iter_concept());
8040 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8043 _Iterator(_Iterator<!_Const> __other)
8045 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8046 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8047 : _M_current(
std::move(__other._M_current)), _M_end(
std::move(__other._M_end)),
8048 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8051 constexpr iterator_t<_Base>
8055 constexpr const iterator_t<_Base>&
8056 base() const & noexcept
8057 {
return _M_current; }
8059 constexpr decltype(
auto)
8061 {
return *_M_current; }
8063 constexpr _Iterator&
8066 __glibcxx_assert(_M_current != _M_end);
8067 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8076 operator++(
int)
requires forward_range<_Base>
8083 constexpr _Iterator&
8084 operator--()
requires bidirectional_range<_Base>
8086 ranges::advance(_M_current, _M_missing - _M_stride);
8092 operator--(
int)
requires bidirectional_range<_Base>
8099 constexpr _Iterator&
8100 operator+=(difference_type __n)
requires random_access_range<_Base>
8104 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8105 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8109 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8115 constexpr _Iterator&
8116 operator-=(difference_type __n)
requires random_access_range<_Base>
8117 {
return *
this += -__n; }
8119 constexpr decltype(
auto)
operator[](difference_type __n)
const
8120 requires random_access_range<_Base>
8121 {
return *(*
this + __n); }
8123 friend constexpr bool
8124 operator==(
const _Iterator& __x, default_sentinel_t)
8125 {
return __x._M_current == __x._M_end; }
8127 friend constexpr bool
8128 operator==(
const _Iterator& __x,
const _Iterator& __y)
8129 requires equality_comparable<iterator_t<_Base>>
8130 {
return __x._M_current == __y._M_current; }
8132 friend constexpr bool
8133 operator<(
const _Iterator& __x,
const _Iterator& __y)
8134 requires random_access_range<_Base>
8135 {
return __x._M_current < __y._M_current; }
8137 friend constexpr bool
8138 operator>(
const _Iterator& __x,
const _Iterator& __y)
8139 requires random_access_range<_Base>
8140 {
return __y._M_current < __x._M_current; }
8142 friend constexpr bool
8143 operator<=(
const _Iterator& __x,
const _Iterator& __y)
8144 requires random_access_range<_Base>
8145 {
return !(__y._M_current < __x._M_current); }
8147 friend constexpr bool
8148 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8149 requires random_access_range<_Base>
8150 {
return !(__x._M_current < __y._M_current); }
8152 friend constexpr auto
8153 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8154 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8155 {
return __x._M_current <=> __y._M_current; }
8157 friend constexpr _Iterator
8158 operator+(
const _Iterator& __i, difference_type __n)
8159 requires random_access_range<_Base>
8166 friend constexpr _Iterator
8167 operator+(difference_type __n,
const _Iterator& __i)
8168 requires random_access_range<_Base>
8169 {
return __i + __n; }
8171 friend constexpr _Iterator
8172 operator-(
const _Iterator& __i, difference_type __n)
8173 requires random_access_range<_Base>
8180 friend constexpr difference_type
8181 operator-(
const _Iterator& __x,
const _Iterator& __y)
8182 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8184 auto __n = __x._M_current - __y._M_current;
8185 if constexpr (forward_range<_Base>)
8186 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8188 return -__detail::__div_ceil(-__n, __x._M_stride);
8190 return __detail::__div_ceil(__n, __x._M_stride);
8193 friend constexpr difference_type
8194 operator-(default_sentinel_t __y,
const _Iterator& __x)
8195 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8196 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8198 friend constexpr difference_type
8199 operator-(
const _Iterator& __x, default_sentinel_t __y)
8200 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8201 {
return -(__y - __x); }
8203 friend constexpr range_rvalue_reference_t<_Base>
8204 iter_move(
const _Iterator& __i)
8205 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8206 {
return ranges::iter_move(__i._M_current); }
8208 friend constexpr void
8209 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8210 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8211 requires indirectly_swappable<iterator_t<_Base>>
8212 { ranges::iter_swap(__x._M_current, __y._M_current); }
8219 template<
typename _Range,
typename _Dp>
8220 concept __can_stride_view
8221 =
requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8224 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8226 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8227 requires __detail::__can_stride_view<_Range, _Dp>
8229 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8230 {
return stride_view(std::forward<_Range>(__r), __n); }
8232 using __adaptor::_RangeAdaptor<_Stride>::operator();
8233 static constexpr int _S_arity = 2;
8234 static constexpr bool _S_has_simple_extra_args =
true;
8237 inline constexpr _Stride stride;
8241#ifdef __cpp_lib_ranges_cartesian_product
8244 template<
bool _Const,
typename _First,
typename... _Vs>
8245 concept __cartesian_product_is_random_access
8246 = (random_access_range<__maybe_const_t<_Const, _First>>
8248 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8249 && sized_range<__maybe_const_t<_Const, _Vs>>));
8251 template<
typename _Range>
8252 concept __cartesian_product_common_arg
8253 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8255 template<
bool _Const,
typename _First,
typename... _Vs>
8256 concept __cartesian_product_is_bidirectional
8257 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8259 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8260 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8262 template<
typename _First,
typename... _Vs>
8263 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8265 template<
typename... _Vs>
8266 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8268 template<
bool _Const,
template<
typename>
class FirstSent,
typename _First,
typename... _Vs>
8269 concept __cartesian_is_sized_sentinel
8270 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8271 iterator_t<__maybe_const_t<_Const, _First>>>
8273 && (sized_range<__maybe_const_t<_Const, _Vs>>
8274 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8275 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8277 template<__cartesian_product_common_arg _Range>
8279 __cartesian_common_arg_end(_Range& __r)
8281 if constexpr (common_range<_Range>)
8282 return ranges::end(__r);
8284 return ranges::begin(__r) + ranges::distance(__r);
8288 template<input_range _First, forward_range... _Vs>
8289 requires (view<_First> && ... && view<_Vs>)
8290 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8292 tuple<_First, _Vs...> _M_bases;
8294 template<
bool>
class _Iterator;
8297 _S_difference_type()
8303 range_difference_t<_First>,
8304 range_difference_t<_Vs>...>{};
8308 cartesian_product_view() =
default;
8311 cartesian_product_view(_First __first, _Vs... __rest)
8315 constexpr _Iterator<false>
8316 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8317 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8319 constexpr _Iterator<true>
8320 begin() const requires (range<const _First> && ... && range<const _Vs>)
8321 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8323 constexpr _Iterator<false>
8324 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8325 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8328 using _Ret = __detail::__tuple_or_pair_t<iterator_t<_First>,
8329 iterator_t<_Vs>...>;
8330 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8331 auto& __first = std::get<0>(_M_bases);
8332 return _Ret{(__empty_tail
8333 ? ranges::begin(__first)
8334 : __detail::__cartesian_common_arg_end(__first)),
8335 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8338 return _Iterator<false>{*
this,
std::move(__its)};
8341 constexpr _Iterator<true>
8342 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8345 using _Ret = __detail::__tuple_or_pair_t<iterator_t<const _First>,
8346 iterator_t<const _Vs>...>;
8347 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8348 auto& __first = std::get<0>(_M_bases);
8349 return _Ret{(__empty_tail
8350 ? ranges::begin(__first)
8351 : __detail::__cartesian_common_arg_end(__first)),
8352 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8355 return _Iterator<true>{*
this,
std::move(__its)};
8358 constexpr default_sentinel_t
8359 end() const noexcept
8363 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8365 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8367 auto __size =
static_cast<_ST
>(1);
8368#ifdef _GLIBCXX_ASSERTIONS
8369 if constexpr (integral<_ST>)
8372 = (__builtin_mul_overflow(__size,
8373 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8376 __glibcxx_assert(!__overflow);
8380 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8386 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8388 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8390 auto __size =
static_cast<_ST
>(1);
8391#ifdef _GLIBCXX_ASSERTIONS
8392 if constexpr (integral<_ST>)
8395 = (__builtin_mul_overflow(__size,
8396 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8399 __glibcxx_assert(!__overflow);
8403 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8409 template<
typename... _Vs>
8410 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8412 template<input_range _First, forward_range... _Vs>
8413 requires (view<_First> && ... && view<_Vs>)
8414 template<bool _Const>
8415 class cartesian_product_view<_First, _Vs...>::_Iterator
8417 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8418 _Parent* _M_parent =
nullptr;
8419 __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
8420 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8423 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8425 _M_current(
std::
move(__current))
8431 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8432 return random_access_iterator_tag{};
8433 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8434 return bidirectional_iterator_tag{};
8435 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8436 return forward_iterator_tag{};
8438 return input_iterator_tag{};
8441 friend cartesian_product_view;
8444 using iterator_category = input_iterator_tag;
8445 using iterator_concept =
decltype(_S_iter_concept());
8447 = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
8448 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8450 = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
8451 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8452 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8454 _Iterator() =
default;
8457 _Iterator(_Iterator<!_Const> __i)
8459 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8460 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8462 _M_current(
std::
move(__i._M_current))
8468 auto __f = [](
auto& __i) ->
decltype(
auto) {
8471 return __detail::__tuple_transform(__f, _M_current);
8474 constexpr _Iterator&
8486 operator++(
int)
requires forward_range<__maybe_const_t<_Const, _First>>
8493 constexpr _Iterator&
8495 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8503 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8510 constexpr _Iterator&
8511 operator+=(difference_type __x)
8512 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8518 constexpr _Iterator&
8519 operator-=(difference_type __x)
8520 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8521 {
return *
this += -__x; }
8524 operator[](difference_type __n)
const
8525 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8526 {
return *((*this) + __n); }
8528 friend constexpr bool
8529 operator==(
const _Iterator& __x,
const _Iterator& __y)
8530 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8531 {
return __x._M_current == __y._M_current; }
8533 friend constexpr bool
8534 operator==(
const _Iterator& __x, default_sentinel_t)
8537 return ((std::get<_Is>(__x._M_current)
8538 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8543 friend constexpr auto
8544 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8545 requires __detail::__all_random_access<_Const, _First, _Vs...>
8546 {
return __x._M_current <=> __y._M_current; }
8548 friend constexpr _Iterator
8549 operator+(_Iterator __x, difference_type __y)
8550 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8551 {
return __x += __y; }
8553 friend constexpr _Iterator
8554 operator+(difference_type __x, _Iterator __y)
8555 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8556 {
return __y += __x; }
8558 friend constexpr _Iterator
8559 operator-(_Iterator __x, difference_type __y)
8560 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8561 {
return __x -= __y; }
8563 friend constexpr difference_type
8564 operator-(
const _Iterator& __x,
const _Iterator& __y)
8565 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8566 {
return __x._M_distance_from(__y._M_current); }
8568 friend constexpr difference_type
8569 operator-(
const _Iterator& __i, default_sentinel_t)
8570 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8573 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8574 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8576 return __i._M_distance_from(__end_tuple);
8579 friend constexpr difference_type
8580 operator-(default_sentinel_t,
const _Iterator& __i)
8581 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8584 friend constexpr auto
8585 iter_move(
const _Iterator& __i)
8586 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8588 friend constexpr void
8589 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8590 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8592 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8595 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8600 template<
size_t _Nm =
sizeof...(_Vs)>
8604 auto& __it = std::get<_Nm>(_M_current);
8606 if constexpr (_Nm > 0)
8607 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8609 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8614 template<
size_t _Nm =
sizeof...(_Vs)>
8618 auto& __it = std::get<_Nm>(_M_current);
8619 if constexpr (_Nm > 0)
8620 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8622 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8628 template<
size_t _Nm =
sizeof...(_Vs)>
8630 _M_advance(difference_type __x)
8631 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8640 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8641 auto& __it = std::get<_Nm>(_M_current);
8642 if constexpr (_Nm == 0)
8644#ifdef _GLIBCXX_ASSERTIONS
8645 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8647 auto __size = ranges::ssize(__r);
8648 auto __begin = ranges::begin(__r);
8649 auto __offset = __it - __begin;
8650 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8657 auto __size = ranges::ssize(__r);
8658 auto __begin = ranges::begin(__r);
8659 auto __offset = __it - __begin;
8661 __x = __offset / __size;
8665 __offset = __size + __offset;
8668 __it = __begin + __offset;
8669 _M_advance<_Nm - 1>(__x);
8674 template<
typename _Tuple>
8675 constexpr difference_type
8676 _M_distance_from(
const _Tuple& __t)
const
8679 auto __sum =
static_cast<difference_type
>(0);
8680#ifdef _GLIBCXX_ASSERTIONS
8681 if constexpr (integral<difference_type>)
8684 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8686 __glibcxx_assert(!__overflow);
8690 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8695 template<
size_t _Nm,
typename _Tuple>
8696 constexpr difference_type
8697 _M_scaled_distance(
const _Tuple& __t)
const
8699 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8700 - std::get<_Nm>(__t));
8701#ifdef _GLIBCXX_ASSERTIONS
8702 if constexpr (integral<difference_type>)
8704 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8705 __glibcxx_assert(!__overflow);
8709 __dist *= _M_scaled_size<_Nm+1>();
8713 template<
size_t _Nm>
8714 constexpr difference_type
8715 _M_scaled_size()
const
8717 if constexpr (_Nm <=
sizeof...(_Vs))
8719 auto __size =
static_cast<difference_type
>(ranges::size
8720 (std::get<_Nm>(_M_parent->_M_bases)));
8721#ifdef _GLIBCXX_ASSERTIONS
8722 if constexpr (integral<difference_type>)
8724 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8725 __glibcxx_assert(!__overflow);
8729 __size *= _M_scaled_size<_Nm+1>();
8733 return static_cast<difference_type
>(1);
8741 template<
typename... _Ts>
8742 concept __can_cartesian_product_view
8743 =
requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8746 struct _CartesianProduct
8748 template<
typename... _Ts>
8749 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8751 operator() [[nodiscard]] (_Ts&&... __ts)
const
8753 if constexpr (
sizeof...(_Ts) == 0)
8754 return views::single(tuple{});
8756 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8760 inline constexpr _CartesianProduct cartesian_product;
8764#ifdef __cpp_lib_ranges_as_rvalue
8765 template<input_range _Vp>
8767 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
8769 _Vp _M_base = _Vp();
8772 as_rvalue_view()
requires default_initializable<_Vp> = default;
8775 as_rvalue_view(_Vp __base)
8776 : _M_base(
std::move(__base))
8780 base() const& requires copy_constructible<_Vp>
8788 begin()
requires (!__detail::__simple_view<_Vp>)
8789 {
return move_iterator(ranges::begin(_M_base)); }
8792 begin() const requires range<const _Vp>
8793 {
return move_iterator(ranges::begin(_M_base)); }
8796 end()
requires (!__detail::__simple_view<_Vp>)
8798 if constexpr (common_range<_Vp>)
8799 return move_iterator(ranges::end(_M_base));
8801 return move_sentinel(ranges::end(_M_base));
8805 end() const requires range<const _Vp>
8807 if constexpr (common_range<const _Vp>)
8808 return move_iterator(ranges::end(_M_base));
8810 return move_sentinel(ranges::end(_M_base));
8814 size()
requires sized_range<_Vp>
8815 {
return ranges::size(_M_base); }
8818 size() const requires sized_range<const _Vp>
8819 {
return ranges::size(_M_base); }
8822 template<
typename _Range>
8823 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8825 template<
typename _Tp>
8826 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8827 = enable_borrowed_range<_Tp>;
8833 template<
typename _Tp>
8834 concept __can_as_rvalue_view =
requires { as_rvalue_view(std::declval<_Tp>()); };
8837 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8839 template<viewable_range _Range>
8840 requires __detail::__can_as_rvalue_view<_Range>
8842 operator() [[nodiscard]] (_Range&& __r)
const
8844 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8845 range_reference_t<_Range>>)
8846 return views::all(std::forward<_Range>(__r));
8848 return as_rvalue_view(std::forward<_Range>(__r));
8852 inline constexpr _AsRvalue as_rvalue;
8856#ifdef __cpp_lib_ranges_enumerate
8859 template<
typename _Range>
8860 concept __range_with_movable_reference = input_range<_Range>
8861 && move_constructible<range_reference_t<_Range>>
8862 && move_constructible<range_rvalue_reference_t<_Range>>;
8866 requires __detail::__range_with_movable_reference<_Vp>
8867 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
8869 _Vp _M_base = _Vp();
8871 template<
bool _Const>
class _Iterator;
8872 template<
bool _Const>
class _Sentinel;
8875 enumerate_view()
requires default_initializable<_Vp> = default;
8878 enumerate_view(_Vp __base)
8879 : _M_base(
std::move(__base))
8883 begin()
requires (!__detail::__simple_view<_Vp>)
8884 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
8887 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8888 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
8891 end()
requires (!__detail::__simple_view<_Vp>)
8893 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8894 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8896 return _Sentinel<false>(ranges::end(_M_base));
8900 end() const requires __detail::__range_with_movable_reference<const _Vp>
8902 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8903 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8905 return _Sentinel<true>(ranges::end(_M_base));
8909 size()
requires sized_range<_Vp>
8910 {
return ranges::size(_M_base); }
8913 size() const requires sized_range<const _Vp>
8914 {
return ranges::size(_M_base); }
8917 base() const & requires copy_constructible<_Vp>
8925 template<
typename _Range>
8926 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8928 template<
typename _Tp>
8929 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8930 = enable_borrowed_range<_Tp>;
8933 requires __detail::__range_with_movable_reference<_Vp>
8934 template<
bool _Const>
8935 class enumerate_view<_Vp>::_Iterator
8937 using _Base = __maybe_const_t<_Const, _Vp>;
8942 if constexpr (random_access_range<_Base>)
8943 return random_access_iterator_tag{};
8944 else if constexpr (bidirectional_range<_Base>)
8945 return bidirectional_iterator_tag{};
8946 else if constexpr (forward_range<_Base>)
8947 return forward_iterator_tag{};
8949 return input_iterator_tag{};
8952 friend enumerate_view;
8955 using iterator_category = input_iterator_tag;
8956 using iterator_concept =
decltype(_S_iter_concept());
8957 using difference_type = range_difference_t<_Base>;
8958 using value_type = tuple<difference_type, range_value_t<_Base>>;
8961 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
8963 iterator_t<_Base> _M_current = iterator_t<_Base>();
8964 difference_type _M_pos = 0;
8967 _Iterator(iterator_t<_Base> __current, difference_type __pos)
8968 : _M_current(
std::
move(__current)), _M_pos(__pos)
8972 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8975 _Iterator(_Iterator<!_Const> __i)
8976 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8977 : _M_current(
std::move(__i._M_current)), _M_pos(__i._M_pos)
8980 constexpr const iterator_t<_Base> &
8981 base() const & noexcept
8982 {
return _M_current; }
8984 constexpr iterator_t<_Base>
8988 constexpr difference_type
8989 index() const noexcept
8994 {
return __reference_type(_M_pos, *_M_current); }
8996 constexpr _Iterator&
9009 operator++(
int)
requires forward_range<_Base>
9016 constexpr _Iterator&
9017 operator--()
requires bidirectional_range<_Base>
9025 operator--(
int)
requires bidirectional_range<_Base>
9032 constexpr _Iterator&
9033 operator+=(difference_type __n)
requires random_access_range<_Base>
9040 constexpr _Iterator&
9041 operator-=(difference_type __n)
requires random_access_range<_Base>
9049 operator[](difference_type __n)
const requires random_access_range<_Base>
9050 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9052 friend constexpr bool
9053 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9054 {
return __x._M_pos == __y._M_pos; }
9056 friend constexpr strong_ordering
9057 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9058 {
return __x._M_pos <=> __y._M_pos; }
9060 friend constexpr _Iterator
9061 operator+(
const _Iterator& __x, difference_type __y)
9062 requires random_access_range<_Base>
9063 {
return (
auto(__x) += __y); }
9065 friend constexpr _Iterator
9066 operator+(difference_type __x,
const _Iterator& __y)
9067 requires random_access_range<_Base>
9068 {
return auto(__y) += __x; }
9070 friend constexpr _Iterator
9071 operator-(
const _Iterator& __x, difference_type __y)
9072 requires random_access_range<_Base>
9073 {
return auto(__x) -= __y; }
9075 friend constexpr difference_type
9076 operator-(
const _Iterator& __x,
const _Iterator& __y)
9077 {
return __x._M_pos - __y._M_pos; }
9079 friend constexpr auto
9080 iter_move(
const _Iterator& __i)
9081 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9082 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9084 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9085 (__i._M_pos, ranges::iter_move(__i._M_current));
9090 requires __detail::__range_with_movable_reference<_Vp>
9091 template<
bool _Const>
9092 class enumerate_view<_Vp>::_Sentinel
9094 using _Base = __maybe_const_t<_Const, _Vp>;
9096 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9099 _Sentinel(sentinel_t<_Base> __end)
9103 friend enumerate_view;
9106 _Sentinel() =
default;
9109 _Sentinel(_Sentinel<!_Const> __other)
9110 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9114 constexpr sentinel_t<_Base>
9118 template<
bool _OtherConst>
9119 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9120 friend constexpr bool
9121 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9122 {
return __x._M_current == __y._M_end; }
9124 template<
bool _OtherConst>
9125 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9126 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9127 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9128 {
return __x._M_current - __y._M_end; }
9130 template<
bool _OtherConst>
9131 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9132 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9133 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9134 {
return __x._M_end - __y._M_current; }
9141 template<
typename _Tp>
9142 concept __can_enumerate_view
9143 =
requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9146 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9148 template<viewable_range _Range>
9149 requires __detail::__can_enumerate_view<_Range>
9151 operator() [[nodiscard]] (_Range&& __r)
const
9152 {
return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9155 inline constexpr _Enumerate enumerate;
9159#ifdef __cpp_lib_ranges_as_const
9161 requires input_range<_Vp>
9162 class as_const_view :
public view_interface<as_const_view<_Vp>>
9164 _Vp _M_base = _Vp();
9167 as_const_view()
requires default_initializable<_Vp> = default;
9170 as_const_view(_Vp __base)
9171 noexcept(is_nothrow_move_constructible_v<_Vp>)
9172 : _M_base(
std::move(__base))
9177 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9178 requires copy_constructible<_Vp>
9183 noexcept(is_nothrow_move_constructible_v<_Vp>)
9187 begin()
requires (!__detail::__simple_view<_Vp>)
9188 {
return ranges::cbegin(_M_base); }
9191 begin() const requires range<const _Vp>
9192 {
return ranges::cbegin(_M_base); }
9195 end()
requires (!__detail::__simple_view<_Vp>)
9196 {
return ranges::cend(_M_base); }
9199 end() const requires range<const _Vp>
9200 {
return ranges::cend(_M_base); }
9203 size()
requires sized_range<_Vp>
9204 {
return ranges::size(_M_base); }
9207 size() const requires sized_range<const _Vp>
9208 {
return ranges::size(_M_base); }
9211 template<
typename _Range>
9212 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9214 template<
typename _Tp>
9215 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9216 = enable_borrowed_range<_Tp>;
9222 template<
typename _Tp>
9223 inline constexpr bool __is_ref_view =
false;
9225 template<
typename _Range>
9226 inline constexpr bool __is_ref_view<ref_view<_Range>> =
true;
9228 template<
typename _Range>
9229 concept __can_as_const_view =
requires { as_const_view(std::declval<_Range>()); };
9232 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9234 template<viewable_range _Range>
9236 operator()(_Range&& __r)
const
9237 noexcept(
noexcept(as_const_view(std::declval<_Range>())))
9238 requires __detail::__can_as_const_view<_Range>
9240 using _Tp = remove_cvref_t<_Range>;
9241 using element_type = remove_reference_t<range_reference_t<_Range>>;
9242 if constexpr (constant_range<views::all_t<_Range>>)
9243 return views::all(std::forward<_Range>(__r));
9244 else if constexpr (__detail::__is_empty_view<_Tp>)
9245 return views::empty<const element_type>;
9246 else if constexpr (std::__detail::__is_span<_Tp>)
9247 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9248 else if constexpr (__detail::__is_ref_view<_Tp>
9249 && constant_range<const element_type>)
9250 return ref_view(
static_cast<const element_type&
>
9251 (std::forward<_Range>(__r).base()));
9252 else if constexpr (is_lvalue_reference_v<_Range>
9253 && constant_range<const _Tp>
9255 return ref_view(
static_cast<const _Tp&
>(__r));
9257 return as_const_view(std::forward<_Range>(__r));
9261 inline constexpr _AsConst as_const;
9266 namespace views = ranges::views;
9268#if __cpp_lib_ranges_to_container
9274 template<
typename _Container>
9275 constexpr bool __reservable_container
9276 = sized_range<_Container>
9277 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9279 { __c.capacity() } -> same_as<
decltype(__n)>;
9280 { __c.max_size() } -> same_as<
decltype(__n)>;
9283 template<
typename _Cont,
typename _Range>
9284 constexpr bool __toable =
requires {
9285 requires (!input_range<_Cont>
9286 || convertible_to<range_reference_t<_Range>,
9287 range_value_t<_Cont>>);
9308 template<
typename _Cont, input_range _Rg,
typename... _Args>
9309 requires (!view<_Cont>)
9311 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9313 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9314 static_assert(is_class_v<_Cont>);
9316 if constexpr (__detail::__toable<_Cont, _Rg>)
9318 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9319 return _Cont(std::forward<_Rg>(__r),
9320 std::forward<_Args>(__args)...);
9321 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9322 return _Cont(from_range, std::forward<_Rg>(__r),
9323 std::forward<_Args>(__args)...);
9324 else if constexpr (
requires {
requires common_range<_Rg>;
9325 typename __iter_category_t<iterator_t<_Rg>>;
9326 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9327 input_iterator_tag>;
9328 requires constructible_from<_Cont, iterator_t<_Rg>,
9329 sentinel_t<_Rg>, _Args...>;
9331 return _Cont(ranges::begin(__r), ranges::end(__r),
9332 std::forward<_Args>(__args)...);
9335 using _RefT = range_reference_t<_Rg>;
9336 static_assert(constructible_from<_Cont, _Args...>);
9337 _Cont __c(std::forward<_Args>(__args)...);
9338 if constexpr (sized_range<_Rg>
9339 && __detail::__reservable_container<_Cont>)
9340 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9344 auto __it = ranges::begin(__r);
9345 const auto __sent = ranges::end(__r);
9346 while (__it != __sent)
9348 if constexpr (
requires { __c.emplace_back(*__it); })
9349 __c.emplace_back(*__it);
9350 else if constexpr (
requires { __c.push_back(*__it); })
9351 __c.push_back(*__it);
9352 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9353 __c.emplace(__c.end(), *__it);
9355 __c.insert(__c.end(), *__it);
9363 static_assert(input_range<range_reference_t<_Rg>>);
9366 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9367 []<
typename _Elt>(_Elt&& __elem) {
9368 using _ValT = range_value_t<_Cont>;
9369 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9370 }), std::forward<_Args>(__args)...);
9377 template<
typename _Rg>
9380 using iterator_category = input_iterator_tag;
9381 using value_type = range_value_t<_Rg>;
9382 using difference_type = ptrdiff_t;
9383 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9384 using reference = range_reference_t<_Rg>;
9386 pointer operator->()
const;
9387 _InputIter& operator++();
9388 _InputIter operator++(
int);
9389 bool operator==(
const _InputIter&)
const;
9392 template<
template<
typename...>
typename _Cont, input_range _Rg,
9395 =
decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9397 template<
template<
typename...>
typename _Cont, input_range _Rg,
9400 =
decltype(_Cont(from_range, std::declval<_Rg>(),
9401 std::declval<_Args>()...));
9403 template<
template<
typename...>
typename _Cont, input_range _Rg,
9408 std::declval<_Args>()...));
9413 template<
template<
typename...>
typename _Cont, input_range _Rg,
9416 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9418 using __detail::_DeduceExpr1;
9419 using __detail::_DeduceExpr2;
9420 using __detail::_DeduceExpr3;
9421 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9422 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9423 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9424 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9425 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9426 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9427 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9428 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9429 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9431 static_assert(
false);
9437 template<
typename _Cont>
9440 template<
typename _Range,
typename... _Args>
9441 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9442 std::declval<_Args>()...); }
9444 operator()(_Range&& __r, _Args&&... __args)
const
9446 return ranges::to<_Cont>(std::forward<_Range>(__r),
9447 std::forward<_Args>(__args)...);
9468 template<
typename _Cont,
typename... _Args>
9469 requires (!view<_Cont>)
9471 to [[nodiscard]] (_Args&&... __args)
9473 using __detail::_To;
9474 using views::__adaptor::_Partial;
9475 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9481 template<
template<
typename...>
typename _Cont>
9484 template<
typename _Range,
typename... _Args>
9485 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9486 std::declval<_Args>()...); }
9488 operator()(_Range&& __r, _Args&&... __args)
const
9490 return ranges::to<_Cont>(std::forward<_Range>(__r),
9491 std::forward<_Args>(__args)...);
9514 template<
template<
typename...>
typename _Cont,
typename... _Args>
9516 to [[nodiscard]] (_Args&&... __args)
9518 using __detail::_To2;
9519 using views::__adaptor::_Partial;
9520 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9526_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.
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)
Primary class template, tuple.