30#ifndef _GLIBCXX_RANGES
31#define _GLIBCXX_RANGES 1
33#if __cplusplus > 201703L
36#pragma GCC system_header
50#if __cplusplus > 202002L
58#define __glibcxx_want_algorithm_default_value_type
59#define __glibcxx_want_ranges
60#define __glibcxx_want_ranges_as_const
61#define __glibcxx_want_ranges_as_rvalue
62#define __glibcxx_want_ranges_cache_latest
63#define __glibcxx_want_ranges_cartesian_product
64#define __glibcxx_want_ranges_concat
65#define __glibcxx_want_ranges_chunk
66#define __glibcxx_want_ranges_chunk_by
67#define __glibcxx_want_ranges_enumerate
68#define __glibcxx_want_ranges_filter
69#define __glibcxx_want_ranges_indices
70#define __glibcxx_want_ranges_join_with
71#define __glibcxx_want_ranges_repeat
72#define __glibcxx_want_ranges_slide
73#define __glibcxx_want_ranges_stride
74#define __glibcxx_want_ranges_to_container
75#define __glibcxx_want_ranges_as_input
76#define __glibcxx_want_ranges_zip
79#ifdef __glibcxx_generator
80# include <bits/elements_of.h>
89namespace std _GLIBCXX_VISIBILITY(default)
91_GLIBCXX_BEGIN_NAMESPACE_VERSION
106 template<
typename _Tp>
requires is_object_v<_Tp>
111 static constexpr _Tp* begin()
noexcept {
return nullptr; }
112 static constexpr _Tp* end()
noexcept {
return nullptr; }
113 static constexpr _Tp* data()
noexcept {
return nullptr; }
114 static constexpr size_t size()
noexcept {
return 0; }
115 static constexpr bool empty()
noexcept {
return true; }
118 template<
typename _Tp>
119 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> =
true;
123#if __cpp_lib_ranges >= 202207L
125 template<
typename _Tp>
128 template<
typename _Tp>
132 template<__boxable _Tp>
133 struct __box : std::optional<_Tp>
135 using std::optional<_Tp>::optional;
139 noexcept(is_nothrow_default_constructible_v<_Tp>)
141 :
std::optional<_Tp>{std::in_place}
144 __box(
const __box&) =
default;
145 __box(__box&&) =
default;
147 using std::optional<_Tp>::operator=;
153 operator=(
const __box& __that)
154 noexcept(is_nothrow_copy_constructible_v<_Tp>)
155 requires (!copyable<_Tp>) && copy_constructible<_Tp>
160 this->emplace(*__that);
168 operator=(__box&& __that)
169 noexcept(is_nothrow_move_constructible_v<_Tp>)
170 requires (!movable<_Tp>)
183 template<
typename _Tp>
184 concept __boxable_copyable
185 = copy_constructible<_Tp>
186 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
187 && is_nothrow_copy_constructible_v<_Tp>));
188 template<
typename _Tp>
189 concept __boxable_movable
190 = (!copy_constructible<_Tp>)
191 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
197 template<__boxable _Tp>
198 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
202 [[no_unique_address]] _Tp _M_value = _Tp();
205 __box()
requires default_initializable<_Tp> = default;
208 __box(const _Tp& __t)
209 noexcept(is_nothrow_copy_constructible_v<_Tp>)
210 requires copy_constructible<_Tp>
216 noexcept(is_nothrow_move_constructible_v<_Tp>)
217 : _M_value(std::move(__t))
220 template<
typename... _Args>
221 requires constructible_from<_Tp, _Args...>
223 __box(in_place_t, _Args&&... __args)
224 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
225 : _M_value(std::
forward<_Args>(__args)...)
228 __box(
const __box&) =
default;
229 __box(__box&&) =
default;
230 __box& operator=(
const __box&)
requires copyable<_Tp> =
default;
231 __box& operator=(__box&&)
requires movable<_Tp> = default;
236 operator=(const __box& __that) noexcept
237 requires (!copyable<_Tp>) && copy_constructible<_Tp>
239 static_assert(is_nothrow_copy_constructible_v<_Tp>);
250 operator=(__box&& __that)
noexcept
251 requires (!movable<_Tp>)
253 static_assert(is_nothrow_move_constructible_v<_Tp>);
263 has_value() const noexcept
278 constexpr const _Tp&&
283 operator->() noexcept
287 operator->() const noexcept
291 namespace __func_handle
293 template<
typename _Fn>
296 _Inplace() =
default;
299 _Inplace(_Fn __func) noexcept
303 template<
typename... _Iters>
304 constexpr decltype(
auto)
305 _M_call_deref(
const _Iters&... __iters)
const
306 noexcept(
noexcept(_M_fn(*__iters...)))
307 {
return _M_fn(*__iters...); }
309 template<
typename _DistType,
typename... _Iters>
310 constexpr decltype(
auto)
311 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
312 noexcept(
noexcept(_M_fn(__iters[iter_difference_t<_Iters>(__n)]...)))
313 {
return _M_fn(__iters[iter_difference_t<_Iters>(__n)]...); }
316 [[no_unique_address]] _Fn _M_fn = _Fn();
319 template<
typename _Fn>
320 struct _InplaceMemPtr
322 _InplaceMemPtr() =
default;
325 _InplaceMemPtr(_Fn __func) noexcept
329 template<
typename... _Iters>
330 constexpr decltype(
auto)
331 _M_call_deref(
const _Iters&... __iters)
const
335 template<
typename _DistType,
typename... _Iters>
336 constexpr decltype(
auto)
337 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
338 noexcept(
noexcept(
std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...)))
339 {
return std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...); }
342 _Fn _M_ptr =
nullptr;
345 template<
typename _Fn>
348 _ViaPointer() =
default;
351 _ViaPointer(_Fn& __func) noexcept
355 template<
typename _Un>
356 requires (!is_const_v<_Un>) && is_same_v<const _Un, _Fn>
358 _ViaPointer(_ViaPointer<_Un> __other) noexcept
359 : _M_ptr(__other._M_ptr)
362 template<
typename... _Iters>
363 constexpr decltype(
auto)
364 _M_call_deref(
const _Iters&... __iters)
const
365 noexcept(
noexcept((*_M_ptr)(*__iters...)))
366 {
return (*_M_ptr)(*__iters...); }
368 template<
typename _DistType,
typename... _Iters>
369 constexpr decltype(
auto)
370 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
371 noexcept(
noexcept((*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...)))
372 {
return (*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...); }
375 _Fn* _M_ptr =
nullptr;
378 friend struct _ViaPointer;
381 template<
typename _Fn>
384 _StaticCall() =
default;
387 _StaticCall(
const _Fn&)
noexcept
390 template<
typename... _Iters>
391 static constexpr decltype(
auto)
392 _M_call_deref(
const _Iters&... __iters)
393 noexcept(
noexcept(_Fn::operator()(*__iters...)))
394 {
return _Fn::operator()(*__iters...); }
396 template<
typename _DistType,
typename... _Iters>
397 static constexpr decltype(
auto)
398 _M_call_subscript(_DistType __n,
const _Iters&... __iters)
399 noexcept(
noexcept(_Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...)))
400 {
return _Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...); }
403 template<
typename _Fn,
typename... _Iters>
407 using _Fd = remove_cv_t<_Fn>;
408 if constexpr (is_member_pointer_v<_Fd>)
409 return __func_handle::_InplaceMemPtr<_Fd>();
410 else if constexpr (is_function_v<remove_pointer_t<_Fd>>)
411 return __func_handle::_Inplace<_Fd>();
412 else if constexpr (__is_std_op_wrapper<_Fd>)
413 return __func_handle::_Inplace<_Fd>();
414 else if constexpr (
requires (
const _Iters&... __iters)
415 { _Fd::operator()(*__iters...); })
416 return __func_handle::_StaticCall<_Fd>();
418 return __func_handle::_ViaPointer<_Fn>();
422 template<
typename _Fn,
typename... _Iters>
423 using __func_handle_t =
decltype(__func_handle::__select<_Fn, _Iters...>());
427#if __cpp_lib_ranges >= 202207L
428 template<move_constructible _Tp>
430 template<copy_constructible _Tp>
432 requires is_object_v<_Tp>
439 single_view(
const _Tp& __t)
440 noexcept(is_nothrow_copy_constructible_v<_Tp>)
446 single_view(_Tp&& __t)
447 noexcept(is_nothrow_move_constructible_v<_Tp>)
453 template<
typename... _Args>
456 single_view(in_place_t, _Args&&... __args)
457 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
466 begin()
const noexcept
471 {
return data() + 1; }
475 {
return data() + 1; }
479 static constexpr bool
483 static constexpr size_t
489 {
return _M_value.operator->(); }
492 data()
const noexcept
493 {
return _M_value.operator->(); }
496 [[no_unique_address]] __detail::__box<_Tp> _M_value;
499 template<
typename _Tp>
504 template<
typename _Wp>
505 constexpr auto __to_signed_like(_Wp __w)
noexcept
507 if constexpr (!integral<_Wp>)
508 return iter_difference_t<_Wp>();
509 else if constexpr (
sizeof(iter_difference_t<_Wp>) >
sizeof(_Wp))
510 return iter_difference_t<_Wp>(__w);
511 else if constexpr (
sizeof(ptrdiff_t) >
sizeof(_Wp))
512 return ptrdiff_t(__w);
513 else if constexpr (
sizeof(
long long) >
sizeof(_Wp))
514 return (
long long)(__w);
515#ifdef __SIZEOF_INT128__
516 else if constexpr (__SIZEOF_INT128__ >
sizeof(_Wp))
517 return __int128(__w);
520 return __max_diff_type(__w);
523 template<
typename _Wp>
526 template<
typename _It>
527 concept __decrementable = incrementable<_It>
530 { --__i } -> same_as<_It&>;
531 { __i-- } -> same_as<_It>;
534 template<
typename _It>
535 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
536 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
538 { __i += __n } -> same_as<_It&>;
539 { __i -= __n } -> same_as<_It&>;
543 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
546 template<
typename _Winc>
547 struct __iota_view_iter_cat
550 template<incrementable _Winc>
551 struct __iota_view_iter_cat<_Winc>
552 {
using iterator_category = input_iterator_tag; };
555 template<weakly_incrementable _Winc,
556 semiregular _Bound = unreachable_sentinel_t>
557 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
564 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
570 using namespace __detail;
571 if constexpr (__advanceable<_Winc>)
572 return random_access_iterator_tag{};
573 else if constexpr (__decrementable<_Winc>)
574 return bidirectional_iterator_tag{};
575 else if constexpr (incrementable<_Winc>)
576 return forward_iterator_tag{};
578 return input_iterator_tag{};
582 using iterator_concept =
decltype(_S_iter_concept());
584 using value_type = _Winc;
585 using difference_type = __detail::__iota_diff_t<_Winc>;
587 _Iterator()
requires default_initializable<_Winc> = default;
590 _Iterator(_Winc __value)
591 : _M_value(__value) { }
594 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
609 operator++(
int)
requires incrementable<_Winc>
617 operator--()
requires __detail::__decrementable<_Winc>
624 operator--(
int)
requires __detail::__decrementable<_Winc>
632 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
634 using __detail::__is_integer_like;
635 using __detail::__is_signed_integer_like;
636 if constexpr (__is_integer_like<_Winc>
637 && !__is_signed_integer_like<_Winc>)
639 if (__n >= difference_type(0))
640 _M_value +=
static_cast<_Winc
>(__n);
642 _M_value -=
static_cast<_Winc
>(-__n);
650 operator-=(difference_type __n)
requires __detail::__advanceable<_Winc>
652 using __detail::__is_integer_like;
653 using __detail::__is_signed_integer_like;
654 if constexpr (__is_integer_like<_Winc>
655 && !__is_signed_integer_like<_Winc>)
657 if (__n >= difference_type(0))
658 _M_value -=
static_cast<_Winc
>(__n);
660 _M_value +=
static_cast<_Winc
>(-__n);
668 operator[](difference_type __n)
const
669 requires __detail::__advanceable<_Winc>
670 {
return _Winc(_M_value + __n); }
672 friend constexpr bool
673 operator==(
const _Iterator& __x,
const _Iterator& __y)
674 requires equality_comparable<_Winc>
675 {
return __x._M_value == __y._M_value; }
677 friend constexpr bool
678 operator<(
const _Iterator& __x,
const _Iterator& __y)
679 requires totally_ordered<_Winc>
680 {
return __x._M_value < __y._M_value; }
682 friend constexpr bool
683 operator>(
const _Iterator& __x,
const _Iterator& __y)
684 requires totally_ordered<_Winc>
685 {
return __y < __x; }
687 friend constexpr bool
688 operator<=(
const _Iterator& __x,
const _Iterator& __y)
689 requires totally_ordered<_Winc>
690 {
return !(__y < __x); }
692 friend constexpr bool
693 operator>=(
const _Iterator& __x,
const _Iterator& __y)
694 requires totally_ordered<_Winc>
695 {
return !(__x < __y); }
697#ifdef __cpp_lib_three_way_comparison
698 friend constexpr auto
699 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
700 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
701 {
return __x._M_value <=> __y._M_value; }
704 friend constexpr _Iterator
705 operator+(_Iterator __i, difference_type __n)
706 requires __detail::__advanceable<_Winc>
712 friend constexpr _Iterator
713 operator+(difference_type __n, _Iterator __i)
714 requires __detail::__advanceable<_Winc>
715 {
return __i += __n; }
717 friend constexpr _Iterator
718 operator-(_Iterator __i, difference_type __n)
719 requires __detail::__advanceable<_Winc>
725 friend constexpr difference_type
726 operator-(
const _Iterator& __x,
const _Iterator& __y)
727 requires __detail::__advanceable<_Winc>
729 using __detail::__is_integer_like;
730 using __detail::__is_signed_integer_like;
731 using _Dt = difference_type;
732 if constexpr (__is_integer_like<_Winc>)
734 if constexpr (__is_signed_integer_like<_Winc>)
735 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
737 return (__y._M_value > __x._M_value)
738 ? _Dt(-_Dt(__y._M_value - __x._M_value))
739 : _Dt(__x._M_value - __y._M_value);
742 return __x._M_value - __y._M_value;
746 _Winc _M_value = _Winc();
755 _Bound _M_bound = _Bound();
758 _Sentinel() =
default;
761 _Sentinel(_Bound __bound)
762 : _M_bound(__bound) { }
764 friend constexpr bool
765 operator==(
const _Iterator& __x,
const _Sentinel& __y)
766 {
return __x._M_value == __y._M_bound; }
768 friend constexpr iter_difference_t<_Winc>
769 operator-(
const _Iterator& __x,
const _Sentinel& __y)
770 requires sized_sentinel_for<_Bound, _Winc>
771 {
return -(__y._M_bound - __x._M_value); }
773 friend constexpr iter_difference_t<_Winc>
774 operator-(
const _Sentinel& __x,
const _Iterator& __y)
775 requires sized_sentinel_for<_Bound, _Winc>
776 {
return __x._M_bound - __y._M_value; }
781 _Winc _M_value = _Winc();
782 [[no_unique_address]] _Bound _M_bound = _Bound();
785 iota_view()
requires default_initializable<_Winc> = default;
788 iota_view(_Winc __value)
793 iota_view(type_identity_t<_Winc> __value,
794 type_identity_t<_Bound> __bound)
795 : _M_value(__value), _M_bound(__bound)
797 if constexpr (totally_ordered_with<_Winc, _Bound>)
798 __glibcxx_assert(
bool(__value <= __bound) );
802 iota_view(_Iterator __first, _Iterator __last)
803 requires same_as<_Winc, _Bound>
804 : iota_view(__first._M_value, __last._M_value)
808 iota_view(_Iterator __first, unreachable_sentinel_t __last)
809 requires same_as<_Bound, unreachable_sentinel_t>
810 : iota_view(__first._M_value, __last)
814 iota_view(_Iterator __first, _Sentinel __last)
815 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
816 : iota_view(__first._M_value, __last._M_bound)
820 begin()
const {
return _Iterator{_M_value}; }
825 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
826 return unreachable_sentinel;
828 return _Sentinel{_M_bound};
832 end() const requires same_as<_Winc, _Bound>
833 {
return _Iterator{_M_bound}; }
839 {
return _M_value == _M_bound; }
843 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
844 || (integral<_Winc> && integral<_Bound>)
845 || sized_sentinel_for<_Bound, _Winc>
847 using __detail::__is_integer_like;
848 using __detail::__to_unsigned_like;
849 if constexpr (integral<_Winc> && integral<_Bound>)
852 return _Up(_M_bound) - _Up(_M_value);
854 else if constexpr (__is_integer_like<_Winc>)
855 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
857 return __to_unsigned_like(_M_bound - _M_value);
861 template<
typename _Winc,
typename _Bound>
862 requires (!__detail::__is_integer_like<_Winc>
863 || !__detail::__is_integer_like<_Bound>
864 || (__detail::__is_signed_integer_like<_Winc>
865 == __detail::__is_signed_integer_like<_Bound>))
866 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
868 template<
typename _Winc,
typename _Bound>
869 inline constexpr bool
870 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
874 template<
typename _Tp>
875 inline constexpr empty_view<_Tp> empty{};
879 template<
typename _Tp>
880 concept __can_single_view
886 template<__detail::__can_single_view _Tp>
888 operator() [[nodiscard]] (_Tp&& __e)
const
893 inline constexpr _Single single{};
897 template<
typename... _Args>
903 template<__detail::__can_iota_view _Tp>
905 operator() [[nodiscard]] (_Tp&& __e)
const
908 template<
typename _Tp,
typename _Up>
909 requires __detail::__can_iota_view<_Tp, _Up>
911 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
915 inline constexpr _Iota iota{};
917#ifdef __cpp_lib_ranges_indices
920 template<ranges::__detail::__is_
integer_like _Tp>
921 requires __detail::__can_iota_view<_Tp>
922 [[nodiscard]]
constexpr auto
923 operator() (_Tp __e)
const noexcept
924 {
return iota(_Tp{}, __e); }
927 inline constexpr _Indices indices{};
934 template<
typename _Val,
typename _CharT,
typename _Traits>
935 concept __stream_extractable
936 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
939 template<movable _Val,
typename _CharT,
940 typename _Traits = char_traits<_CharT>>
941 requires default_initializable<_Val>
942 && __detail::__stream_extractable<_Val, _CharT, _Traits>
943 class basic_istream_view
944 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
948 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
955 *_M_stream >> _M_object;
956 return _Iterator{
this};
959 constexpr default_sentinel_t
964 basic_istream<_CharT, _Traits>* _M_stream;
965 _Val _M_object = _Val();
970 using iterator_concept = input_iterator_tag;
971 using difference_type = ptrdiff_t;
972 using value_type = _Val;
975 _Iterator(basic_istream_view* __parent) noexcept
976 : _M_parent(__parent)
979 _Iterator(
const _Iterator&) =
delete;
980 _Iterator(_Iterator&&) =
default;
981 _Iterator& operator=(
const _Iterator&) =
delete;
982 _Iterator& operator=(_Iterator&&) =
default;
987 *_M_parent->_M_stream >> _M_parent->_M_object;
997 {
return _M_parent->_M_object; }
1000 operator==(
const _Iterator& __x, default_sentinel_t)
1001 {
return !*__x._M_parent->_M_stream; }
1004 basic_istream_view* _M_parent;
1010 template<
typename _Val>
1011 using istream_view = basic_istream_view<_Val, char>;
1013 template<
typename _Val>
1014 using wistream_view = basic_istream_view<_Val, wchar_t>;
1020 template<
typename _Tp,
typename _Up>
1021 concept __can_istream_view =
requires (_Up __e) {
1022 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
1026 template<
typename _Tp>
1029 template<
typename _CharT,
typename _Traits>
1031 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
1033 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
1036 template<
typename _Tp>
1037 inline constexpr _Istream<_Tp> istream;
1045 template<
typename _Tp,
int _Disc>
1054 template<
bool _Present,
typename _Tp,
int _Disc = 0>
1055 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
1058 template<
bool _Const,
typename _Tp>
1059 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
1064using __detail::__maybe_const_t;
1066namespace views::__adaptor
1069 template<
typename _Adaptor,
typename... _Args>
1070 concept __adaptor_invocable
1075 template<
typename _Adaptor,
typename... _Args>
1076 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
1077 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
1078 && (constructible_from<decay_t<_Args>, _Args> && ...);
1080 template<
typename _Adaptor,
typename... _Args>
1083 template<
typename _Lhs,
typename _Rhs>
1091 template<
typename _Derived>
1092 struct _RangeAdaptorClosure;
1094 template<
typename _Tp,
typename _Up>
1095 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
1096 void __is_range_adaptor_closure_fn
1097 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
1099 template<
typename _Tp>
1100 concept __is_range_adaptor_closure
1101 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
1103#pragma GCC diagnostic push
1104#pragma GCC diagnostic ignored "-Wdangling-reference"
1106 template<
typename _Self,
typename _Range>
1107 requires __is_range_adaptor_closure<_Self>
1108 && __adaptor_invocable<_Self, _Range>
1110 operator|(_Range&& __r, _Self&& __self)
1115 template<
typename _Lhs,
typename _Rhs>
1116 requires __is_range_adaptor_closure<_Lhs>
1117 && __is_range_adaptor_closure<_Rhs>
1119 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
1124#pragma GCC diagnostic pop
1126 template<
typename _Derived>
1127 struct _RangeAdaptorClosure
1133 template<
typename _Self,
typename _Range>
1134 requires __is_range_adaptor_closure<_Self>
1135 && __adaptor_invocable<_Self, _Range>
1136 friend constexpr auto
1137 operator|(_Range&& __r, _Self&& __self);
1139 template<
typename _Lhs,
typename _Rhs>
1140 requires __is_range_adaptor_closure<_Lhs>
1141 && __is_range_adaptor_closure<_Rhs>
1142 friend constexpr auto
1143 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1157 template<
typename _Derived>
1158 struct _RangeAdaptor
1162 template<
typename... _Args>
1163 requires __adaptor_partial_app_viable<_Derived, _Args...>
1165 operator()(_Args&&... __args)
const
1174 template<
typename _Adaptor>
1175 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1179 template<
typename _Adaptor,
typename... _Args>
1180 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1181 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1185 template<
typename _Adaptor,
typename... _Args>
1186 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1188 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1189 [[no_unique_address]] _Binder _M_binder;
1193 template<
typename... _Ts>
1195 _Partial(
int, _Ts&&... __args)
1196 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1201#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1202# pragma GCC diagnostic push
1203# pragma GCC diagnostic ignored "-Wc++23-extensions"
1204 template<
typename _Self,
typename _Range>
1205 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1207 operator()(
this _Self&& __self, _Range&& __r)
1209 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1212# pragma GCC diagnostic pop
1214 template<
typename _Range>
1215 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1217 operator()(_Range&& __r)
const &
1220 template<
typename _Range>
1221 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1223 operator()(_Range&& __r) &&
1226 template<
typename _Range>
1228 operator()(_Range&& __r)
const && =
delete;
1236 template<
typename _Adaptor,
typename... _Args>
1237 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1238 && (is_trivially_copy_constructible_v<_Args> && ...)
1239 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1241 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1242 [[no_unique_address]] _Binder _M_binder;
1244 template<
typename... _Ts>
1246 _Partial(
int, _Ts&&... __args)
1247 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1252 template<
typename _Range>
1253 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1255 operator()(_Range&& __r)
const
1258 static constexpr bool _S_has_simple_call_op =
true;
1261 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1262 concept __pipe_invocable
1267 template<
typename _Lhs,
typename _Rhs>
1268 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1270 [[no_unique_address]] _Lhs _M_lhs;
1271 [[no_unique_address]] _Rhs _M_rhs;
1273 template<
typename _Tp,
typename _Up>
1275 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1276 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1281#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1282# pragma GCC diagnostic push
1283# pragma GCC diagnostic ignored "-Wc++23-extensions"
1284 template<
typename _Self,
typename _Range>
1285 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1287 operator()(
this _Self&& __self, _Range&& __r)
1289 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1290 (__like_t<_Self, _Pipe>(__self)._M_lhs
1293# pragma GCC diagnostic pop
1295 template<
typename _Range>
1296 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1298 operator()(_Range&& __r)
const &
1301 template<
typename _Range>
1302 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1304 operator()(_Range&& __r) &&
1307 template<
typename _Range>
1309 operator()(_Range&& __r)
const && =
delete;
1317 template<
typename _Lhs,
typename _Rhs>
1318 requires __closure_has_simple_call_op<_Lhs>
1319 && __closure_has_simple_call_op<_Rhs>
1320 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1322 [[no_unique_address]] _Lhs _M_lhs;
1323 [[no_unique_address]] _Rhs _M_rhs;
1325 template<
typename _Tp,
typename _Up>
1327 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1328 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1331 template<
typename _Range>
1332 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1334 operator()(_Range&& __r)
const
1337 static constexpr bool _S_has_simple_call_op =
true;
1341#if __cpp_lib_ranges >= 202202L
1343 template<
typename _Derived>
1344 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1345 class range_adaptor_closure
1346 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1350 template<range _Range>
requires is_object_v<_Range>
1356 static void _S_fun(_Range&);
1357 static void _S_fun(_Range&&) =
delete;
1360 template<__detail::__different_from<ref_view> _Tp>
1361 requires convertible_to<_Tp, _Range&>
1373 constexpr iterator_t<_Range>
1375 {
return ranges::begin(*_M_r); }
1377 constexpr sentinel_t<_Range>
1379 {
return ranges::end(*_M_r); }
1382 empty() const requires requires { ranges::empty(*_M_r); }
1383 {
return ranges::empty(*_M_r); }
1386 size() const requires sized_range<_Range>
1387 {
return ranges::size(*_M_r); }
1390 data() const requires contiguous_range<_Range>
1391 {
return ranges::data(*_M_r); }
1394 template<
typename _Range>
1395 ref_view(_Range&) -> ref_view<_Range>;
1397 template<
typename _Tp>
1398 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1400 template<range _Range>
1401 requires movable<_Range>
1402 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1406 _Range _M_r = _Range();
1409 owning_view()
requires default_initializable<_Range> = default;
1412 owning_view(_Range&& __t)
1413 noexcept(is_nothrow_move_constructible_v<_Range>)
1414 : _M_r(std::move(__t))
1417 owning_view(owning_view&&) =
default;
1418 owning_view& operator=(owning_view&&) =
default;
1424 constexpr const _Range&
1425 base() const& noexcept
1432 constexpr const _Range&&
1433 base() const&& noexcept
1436 constexpr iterator_t<_Range>
1438 {
return ranges::begin(_M_r); }
1440 constexpr sentinel_t<_Range>
1442 {
return ranges::end(_M_r); }
1446 {
return ranges::begin(_M_r); }
1449 end() const requires
range<const _Range>
1450 {
return ranges::end(_M_r); }
1453 empty()
requires requires { ranges::empty(_M_r); }
1454 {
return ranges::empty(_M_r); }
1457 empty() const requires requires { ranges::empty(_M_r); }
1458 {
return ranges::empty(_M_r); }
1462 {
return ranges::size(_M_r); }
1466 {
return ranges::size(_M_r); }
1470 {
return ranges::data(_M_r); }
1474 {
return ranges::data(_M_r); }
1477 template<
typename _Tp>
1478 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1479 = enable_borrowed_range<_Tp>;
1485 template<
typename _Range>
1488 template<
typename _Range>
1492 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1494 template<
typename _Range>
1495 static constexpr bool
1498 if constexpr (view<decay_t<_Range>>)
1500 else if constexpr (__detail::__can_ref_view<_Range>)
1506 template<viewable_range _Range>
1507 requires view<decay_t<_Range>>
1508 || __detail::__can_ref_view<_Range>
1509 || __detail::__can_owning_view<_Range>
1511 operator() [[nodiscard]] (_Range&& __r)
const
1512 noexcept(_S_noexcept<_Range>())
1514 if constexpr (view<decay_t<_Range>>)
1516 else if constexpr (__detail::__can_ref_view<_Range>)
1522 static constexpr bool _S_has_simple_call_op =
true;
1525 inline constexpr _All all;
1527 template<viewable_range _Range>
1533 template<
typename _Tp>
1534 struct __non_propagating_cache
1542 template<
typename _Tp>
1543 requires is_object_v<_Tp>
1544 struct __non_propagating_cache<_Tp>
1545 :
protected _Optional_base<_Tp>
1547 __non_propagating_cache() =
default;
1550 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1554 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1555 { __other._M_reset(); }
1557 constexpr __non_propagating_cache&
1558 operator=(
const __non_propagating_cache& __other)
noexcept
1565 constexpr __non_propagating_cache&
1566 operator=(__non_propagating_cache&& __other)
noexcept
1573 constexpr __non_propagating_cache&
1574 operator=(_Tp __val)
1577 this->_M_payload._M_construct(
std::move(__val));
1582 operator bool() const noexcept
1583 {
return this->_M_is_engaged(); }
1587 {
return this->_M_get(); }
1589 constexpr const _Tp&
1591 {
return this->_M_get(); }
1593 template<
typename _Iter>
1595 _M_emplace_deref(
const _Iter& __i)
1598 auto __f = [] (
auto& __x) {
return *__x; };
1599 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1600 return this->_M_get();
1603 using _Optional_base<_Tp>::_M_reset;
1606 template<range _Range>
1607 struct _CachedPosition
1610 _M_has_value()
const
1613 constexpr iterator_t<_Range>
1614 _M_get(
const _Range&)
const
1616 __glibcxx_assert(
false);
1617 __builtin_unreachable();
1621 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1625 template<forward_range _Range>
1626 struct _CachedPosition<_Range>
1627 :
protected __non_propagating_cache<iterator_t<_Range>>
1630 _M_has_value()
const
1631 {
return this->_M_is_engaged(); }
1633 constexpr iterator_t<_Range>
1634 _M_get(
const _Range&)
const
1636 __glibcxx_assert(_M_has_value());
1641 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1643 __glibcxx_assert(!_M_has_value());
1646 this->_M_payload._M_engaged =
true;
1650 template<random_access_range _Range>
1651 struct _CachedPosition<_Range>
1654 range_difference_t<_Range> _M_offset = -1;
1657 _CachedPosition() =
default;
1660 _CachedPosition(
const _CachedPosition&) =
default;
1663 _CachedPosition(_CachedPosition&& __other)
noexcept
1666 constexpr _CachedPosition&
1667 operator=(
const _CachedPosition&) =
default;
1669 constexpr _CachedPosition&
1670 operator=(_CachedPosition&& __other)
noexcept
1673 _M_offset = __other._M_offset;
1674 __other._M_offset = -1;
1679 _M_has_value()
const
1680 {
return _M_offset >= 0; }
1682 constexpr iterator_t<_Range>
1683 _M_get(_Range& __r)
const
1685 __glibcxx_assert(_M_has_value());
1686 return ranges::begin(__r) + _M_offset;
1690 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1692 __glibcxx_assert(!_M_has_value());
1693 _M_offset = __it - ranges::begin(__r);
1700 template<
typename _Base>
1701 struct __filter_view_iter_cat
1704 template<forward_range _Base>
1705 struct __filter_view_iter_cat<_Base>
1711 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1712 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1713 return bidirectional_iterator_tag{};
1714 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1715 return forward_iterator_tag{};
1720 using iterator_category =
decltype(_S_iter_cat());
1725 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1726 requires view<_Vp> && is_object_v<_Pred>
1727 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1730 template<
bool _Const>
1733 template<
bool _Const>
1734 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1737 static constexpr auto
1740 if constexpr (_Const)
1741 return input_iterator_tag{};
1742 else if constexpr (bidirectional_range<_Vp>)
1743 return bidirectional_iterator_tag{};
1744 else if constexpr (forward_range<_Vp>)
1745 return forward_iterator_tag{};
1747 return input_iterator_tag{};
1751 friend _Iterator<!_Const>;
1753 using _Parent = __maybe_const_t<_Const, filter_view>;
1754 using _Base = __maybe_const_t<_Const, _Vp>;
1755 using _Base_iter = iterator_t<_Base>;
1757 _Base_iter _M_current = _Base_iter();
1758 _Parent* _M_parent =
nullptr;
1761 using iterator_concept =
decltype(_S_iter_concept());
1763 using value_type = range_value_t<_Base>;
1764 using difference_type = range_difference_t<_Base>;
1766 _Iterator()
requires default_initializable<_Base_iter> = default;
1769 _Iterator(_Parent* __parent, _Base_iter __current)
1770 : _M_current(std::move(__current)),
1775 _Iterator(_Iterator<!_Const> __i)
1776 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
1777 : _M_current(
std::move(__i._M_current)),
1781 constexpr const _Base_iter&
1782 base() const & noexcept
1783 {
return _M_current; }
1785 constexpr _Base_iter
1789 constexpr range_reference_t<_Base>
1791 {
return *_M_current; }
1793 constexpr _Base_iter
1795 requires __detail::__has_arrow<_Base_iter>
1796 && copyable<_Base_iter>
1797 {
return _M_current; }
1799 constexpr _Iterator&
1802 _M_current = ranges::find_if(
std::move(++_M_current),
1803 ranges::end(_M_parent->_M_base),
1813 operator++(
int)
requires forward_range<_Base>
1820 constexpr _Iterator&
1821 operator--()
requires bidirectional_range<_Base>
1830 operator--(
int)
requires bidirectional_range<_Base>
1837 friend constexpr bool
1838 operator==(
const _Iterator& __x,
const _Iterator& __y)
1839 requires equality_comparable<_Base_iter>
1840 {
return __x._M_current == __y._M_current; }
1842 friend constexpr range_rvalue_reference_t<_Base>
1843 iter_move(
const _Iterator& __i)
1844 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1845 {
return ranges::iter_move(__i._M_current); }
1847 friend constexpr void
1848 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1849 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1850 requires indirectly_swappable<_Base_iter>
1851 { ranges::iter_swap(__x._M_current, __y._M_current); }
1854 template<
bool _Const>
1858 using _Parent = __maybe_const_t<_Const, filter_view>;
1859 using _Base = __maybe_const_t<_Const, _Vp>;
1860 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1862 friend _Sentinel<!_Const>;
1865 _Sentinel() =
default;
1868 _Sentinel(_Parent* __parent)
1869 : _M_end(ranges::end(__parent->_M_base))
1873 _Sentinel(_Sentinel<!_Const> __i)
1874 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1878 constexpr sentinel_t<_Base>
1882 template<
bool _Const2>
1883 requires sentinel_for<sentinel_t<_Base>,
1884 iterator_t<__maybe_const_t<_Const2, _Vp>>>
1885 friend constexpr bool
1886 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
1887 {
return __x._M_current == __y._M_end; }
1890 _Vp _M_base = _Vp();
1891 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1892 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1895 filter_view()
requires (default_initializable<_Vp>
1896 && default_initializable<_Pred>)
1900 filter_view(_Vp __base, _Pred __pred)
1901 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
1905 base() const& requires copy_constructible<_Vp>
1912 constexpr const _Pred&
1914 {
return *_M_pred; }
1916 constexpr _Iterator<false>
1919 if (_M_cached_begin._M_has_value())
1920 return {
this, _M_cached_begin._M_get(_M_base)};
1922 __glibcxx_assert(_M_pred.has_value());
1923 auto __it = ranges::find_if(ranges::begin(_M_base),
1924 ranges::end(_M_base),
1926 _M_cached_begin._M_set(_M_base, __it);
1930 constexpr _Iterator<true>
1932 requires (input_range<const _Vp> && !forward_range<const _Vp>
1933 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1935 __glibcxx_assert(_M_pred.has_value());
1936 auto __it = ranges::find_if(ranges::begin(_M_base),
1937 ranges::end(_M_base),
1945 if constexpr (common_range<_Vp>)
1946 return _Iterator<false>{
this, ranges::end(_M_base)};
1948 return _Sentinel<false>{
this};
1951 constexpr _Sentinel<true>
1953 requires (input_range<const _Vp> && !forward_range<const _Vp>
1954 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1955 {
return _Sentinel<true>{
this}; }
1958 template<
typename _Range,
typename _Pred>
1959 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1965 template<
typename _Range,
typename _Pred>
1966 concept __can_filter_view
1970 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1972 template<viewable_range _Range,
typename _Pred>
1973 requires __detail::__can_filter_view<_Range, _Pred>
1975 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1980 using _RangeAdaptor<_Filter>::operator();
1981 static constexpr int _S_arity = 2;
1982 static constexpr bool _S_has_simple_extra_args =
true;
1985 inline constexpr _Filter filter;
1988#if __cpp_lib_ranges >= 202207L
1989 template<input_range _Vp, move_constructible _Fp>
1991 template<input_range _Vp, copy_constructible _Fp>
1994 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1995 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1996 range_reference_t<_Vp>>>
1997 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
2000 template<
bool _Const>
2001 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2003 template<
bool _Const>
2007 template<
bool _Const>
2008 requires forward_range<_Base<_Const>>
2009 struct __iter_cat<_Const>
2018 using _Base = transform_view::_Base<_Const>;
2019 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2020 range_reference_t<_Base>>;
2023 if constexpr (is_reference_v<_Res>)
2026 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
2027 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
2028 return random_access_iterator_tag{};
2033 return input_iterator_tag{};
2036 using iterator_category =
decltype(_S_iter_cat());
2039 template<
bool _Const>
2042 template<
bool _Const>
2043 struct _Iterator : __iter_cat<_Const>
2046 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2047 using _Base = transform_view::_Base<_Const>;
2048 using _Base_iter = iterator_t<_Base>;
2049 using _Func_handle = __detail::__func_handle_t<
2050 __detail::__maybe_const_t<_Const, _Fp>,
2056 if constexpr (random_access_range<_Base>)
2057 return random_access_iterator_tag{};
2058 else if constexpr (bidirectional_range<_Base>)
2059 return bidirectional_iterator_tag{};
2060 else if constexpr (forward_range<_Base>)
2061 return forward_iterator_tag{};
2063 return input_iterator_tag{};
2066 _Base_iter _M_current = _Base_iter();
2067 [[no_unique_address]] _Func_handle _M_fun;
2070 using iterator_concept =
decltype(_S_iter_concept());
2073 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2074 range_reference_t<_Base>>>;
2075 using difference_type = range_difference_t<_Base>;
2077 _Iterator()
requires default_initializable<_Base_iter> = default;
2080 _Iterator(_Func_handle __fun, _Base_iter __current)
2081 : _M_current(std::move(__current)), _M_fun(__fun)
2085 _Iterator(_Parent* __parent, _Base_iter __current)
2086 : _M_current(std::move(__current)), _M_fun(*__parent->_M_fun)
2090 _Iterator(_Iterator<!_Const> __i)
2092 && convertible_to<iterator_t<_Vp>, _Base_iter>
2093 : _M_current(
std::move(__i._M_current)), _M_fun(__i._M_fun)
2096 constexpr const _Base_iter&
2097 base() const & noexcept
2098 {
return _M_current; }
2100 constexpr _Base_iter
2104 constexpr decltype(
auto)
2106 noexcept(
noexcept(_M_fun._M_call_deref(_M_current)))
2107 {
return _M_fun._M_call_deref(_M_current); }
2109 constexpr _Iterator&
2121 operator++(
int)
requires forward_range<_Base>
2128 constexpr _Iterator&
2129 operator--()
requires bidirectional_range<_Base>
2136 operator--(
int)
requires bidirectional_range<_Base>
2143 constexpr _Iterator&
2144 operator+=(difference_type __n)
requires random_access_range<_Base>
2150 constexpr _Iterator&
2151 operator-=(difference_type __n)
requires random_access_range<_Base>
2157 constexpr decltype(
auto)
2158 operator[](difference_type __n)
const
2159 requires random_access_range<_Base>
2160 {
return _M_fun._M_call_subscript(__n, _M_current); }
2162 friend constexpr bool
2163 operator==(
const _Iterator& __x,
const _Iterator& __y)
2164 requires equality_comparable<_Base_iter>
2165 {
return __x._M_current == __y._M_current; }
2167 friend constexpr bool
2168 operator<(
const _Iterator& __x,
const _Iterator& __y)
2169 requires random_access_range<_Base>
2170 {
return __x._M_current < __y._M_current; }
2172 friend constexpr bool
2173 operator>(
const _Iterator& __x,
const _Iterator& __y)
2174 requires random_access_range<_Base>
2175 {
return __y < __x; }
2177 friend constexpr bool
2178 operator<=(
const _Iterator& __x,
const _Iterator& __y)
2179 requires random_access_range<_Base>
2180 {
return !(__y < __x); }
2182 friend constexpr bool
2183 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2184 requires random_access_range<_Base>
2185 {
return !(__x < __y); }
2187#ifdef __cpp_lib_three_way_comparison
2188 friend constexpr auto
2189 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2190 requires random_access_range<_Base>
2191 && three_way_comparable<_Base_iter>
2192 {
return __x._M_current <=> __y._M_current; }
2195 friend constexpr _Iterator
2196 operator+(_Iterator __i, difference_type __n)
2197 requires random_access_range<_Base>
2198 {
return {__i._M_fun, __i._M_current + __n}; }
2200 friend constexpr _Iterator
2201 operator+(difference_type __n, _Iterator __i)
2202 requires random_access_range<_Base>
2203 {
return {__i._M_fun, __i._M_current + __n}; }
2205 friend constexpr _Iterator
2206 operator-(_Iterator __i, difference_type __n)
2207 requires random_access_range<_Base>
2208 {
return {__i._M_fun, __i._M_current - __n}; }
2212 friend constexpr difference_type
2213 operator-(
const _Iterator& __x,
const _Iterator& __y)
2214 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2215 {
return __x._M_current - __y._M_current; }
2217 friend constexpr decltype(
auto)
2218 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2220 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2226 friend _Iterator<!_Const>;
2227 template<
bool>
friend struct _Sentinel;
2230 template<
bool _Const>
2234 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2235 using _Base = transform_view::_Base<_Const>;
2237 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2240 _Sentinel() =
default;
2243 _Sentinel(sentinel_t<_Base> __end)
2248 _Sentinel(_Sentinel<!_Const> __i)
2250 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2254 constexpr sentinel_t<_Base>
2258 template<
bool _Const2>
2259 requires sentinel_for<sentinel_t<_Base>,
2260 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2261 friend constexpr bool
2262 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2263 {
return __x._M_current == __y._M_end; }
2265 template<
bool _Const2,
2266 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2267 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2268 friend constexpr range_difference_t<_Base2>
2269 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2270 {
return -(__y._M_end - __x._M_current); }
2272 template<
bool _Const2,
2273 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2274 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2275 friend constexpr range_difference_t<_Base2>
2276 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2277 {
return __y._M_end - __x._M_current; }
2279 friend _Sentinel<!_Const>;
2282 _Vp _M_base = _Vp();
2283 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2286 transform_view()
requires (default_initializable<_Vp>
2287 && default_initializable<_Fp>)
2291 transform_view(_Vp __base, _Fp __fun)
2292 : _M_base(std::move(
__base)), _M_fun(std::move(__fun))
2296 base() const& requires copy_constructible<_Vp>
2297 {
return _M_base ; }
2303 constexpr _Iterator<false>
2305 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2307 constexpr _Iterator<true>
2309 requires range<const _Vp>
2310 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2311 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2313 constexpr _Sentinel<false>
2315 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2317 constexpr _Iterator<false>
2318 end()
requires common_range<_Vp>
2319 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2321 constexpr _Sentinel<true>
2323 requires range<const _Vp>
2324 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2325 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2327 constexpr _Iterator<true>
2329 requires common_range<const _Vp>
2330 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2331 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2334 size()
requires sized_range<_Vp>
2335 {
return ranges::size(_M_base); }
2338 size() const requires sized_range<const _Vp>
2339 {
return ranges::size(_M_base); }
2342 template<
typename _Range,
typename _Fp>
2343 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2349 template<
typename _Range,
typename _Fp>
2350 concept __can_transform_view
2354 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2356 template<viewable_range _Range,
typename _Fp>
2357 requires __detail::__can_transform_view<_Range, _Fp>
2359 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2364 using _RangeAdaptor<_Transform>::operator();
2365 static constexpr int _S_arity = 2;
2366 static constexpr bool _S_has_simple_extra_args =
true;
2369 inline constexpr _Transform transform;
2376 template<
bool _Const>
2377 using _CI = counted_iterator<
2378 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2380 template<
bool _Const>
2384 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2385 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2388 _Sentinel() =
default;
2391 _Sentinel(sentinel_t<_Base> __end)
2396 _Sentinel(_Sentinel<!_Const> __s)
2397 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2401 constexpr sentinel_t<_Base>
2405 friend constexpr bool
2406 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2407 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2409 template<
bool _OtherConst = !_Const,
2410 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2411 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2412 friend constexpr bool
2413 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2414 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2416 friend _Sentinel<!_Const>;
2419 _Vp _M_base = _Vp();
2420 range_difference_t<_Vp> _M_count = 0;
2423 take_view()
requires default_initializable<_Vp> = default;
2426 take_view(_Vp __base, range_difference_t<_Vp> __count)
2427 : _M_base(std::move(__base)), _M_count(std::move(__count))
2431 base() const& requires copy_constructible<_Vp>
2439 begin()
requires (!__detail::__simple_view<_Vp>)
2441 if constexpr (sized_range<_Vp>)
2443 if constexpr (random_access_range<_Vp>)
2444 return ranges::begin(_M_base);
2448 return counted_iterator(ranges::begin(_M_base), __sz);
2452 return counted_iterator(ranges::begin(_M_base), _M_count);
2456 begin() const requires range<const _Vp>
2458 if constexpr (sized_range<const _Vp>)
2460 if constexpr (random_access_range<const _Vp>)
2461 return ranges::begin(_M_base);
2465 return counted_iterator(ranges::begin(_M_base), __sz);
2469 return counted_iterator(ranges::begin(_M_base), _M_count);
2473 end()
requires (!__detail::__simple_view<_Vp>)
2475 if constexpr (sized_range<_Vp>)
2477 if constexpr (random_access_range<_Vp>)
2478 return ranges::begin(_M_base) + size();
2483 return _Sentinel<false>{ranges::end(_M_base)};
2487 end() const requires range<const _Vp>
2489 if constexpr (sized_range<const _Vp>)
2491 if constexpr (random_access_range<const _Vp>)
2492 return ranges::begin(_M_base) + size();
2497 return _Sentinel<true>{ranges::end(_M_base)};
2501 size()
requires sized_range<_Vp>
2503 auto __n = ranges::size(_M_base);
2504 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2508 size() const requires sized_range<const _Vp>
2510 auto __n = ranges::size(_M_base);
2511 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2518 template<
typename _Range>
2519 take_view(_Range&&, range_difference_t<_Range>)
2520 -> take_view<views::all_t<_Range>>;
2522 template<
typename _Tp>
2523 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2524 = enable_borrowed_range<_Tp>;
2530 template<
typename _Range>
2531 inline constexpr bool __is_empty_view =
false;
2533 template<
typename _Tp>
2534 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2536 template<
typename _Range>
2537 inline constexpr bool __is_basic_string_view =
false;
2539 template<
typename _CharT,
typename _Traits>
2540 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2543 using ranges::__detail::__is_subrange;
2545 template<
typename _Range>
2546 inline constexpr bool __is_iota_view =
false;
2548 template<
typename _Winc,
typename _Bound>
2549 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2551 template<
typename _Range>
2552 inline constexpr bool __is_repeat_view =
false;
2554 template<
typename _Range>
2556 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2558 template<
typename _Range,
typename _Dp>
2559 concept __can_take_view
2563 struct _Take : __adaptor::_RangeAdaptor<_Take>
2565 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2566 requires __detail::__can_take_view<_Range, _Dp>
2568 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2570 using _Tp = remove_cvref_t<_Range>;
2571 if constexpr (__detail::__is_empty_view<_Tp>)
2573#ifdef __cpp_lib_optional_range_support
2574 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2577 else if constexpr (random_access_range<_Tp>
2579 && (std::__detail::__is_span<_Tp>
2580 || __detail::__is_basic_string_view<_Tp>
2581 || __detail::__is_subrange<_Tp>
2582 || __detail::__is_iota_view<_Tp>))
2585 auto __begin = ranges::begin(__r);
2586 auto __end = __begin + __n;
2587 if constexpr (std::__detail::__is_span<_Tp>)
2588 return span<typename _Tp::element_type>(__begin, __end);
2589 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2590 return _Tp(__begin, __end);
2591 else if constexpr (__detail::__is_subrange<_Tp>)
2592 return subrange<iterator_t<_Tp>>(__begin, __end);
2594 return iota_view(*__begin, *__end);
2596 else if constexpr (__detail::__is_repeat_view<_Tp>)
2602 using _RangeAdaptor<_Take>::operator();
2603 static constexpr int _S_arity = 2;
2607 template<
typename _Tp>
2608 static constexpr bool _S_has_simple_extra_args
2609 = ranges::__detail::__is_integer_like<_Tp>;
2612 inline constexpr _Take take;
2615 template<view _Vp,
typename _Pred>
2617 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2618 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2620 template<
bool _Const>
2624 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2626 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2627 const _Pred* _M_pred =
nullptr;
2630 _Sentinel() =
default;
2633 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2634 : _M_end(__end), _M_pred(__pred)
2638 _Sentinel(_Sentinel<!_Const> __s)
2639 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2640 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2643 constexpr sentinel_t<_Base>
2644 base()
const {
return _M_end; }
2646 friend constexpr bool
2647 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2648 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2650 template<
bool _OtherConst = !_Const,
2651 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2652 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2653 friend constexpr bool
2654 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2655 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2657 friend _Sentinel<!_Const>;
2660 _Vp _M_base = _Vp();
2661 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2664 take_while_view()
requires (default_initializable<_Vp>
2665 && default_initializable<_Pred>)
2669 take_while_view(_Vp __base, _Pred __pred)
2670 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2674 base() const& requires copy_constructible<_Vp>
2681 constexpr const _Pred&
2683 {
return *_M_pred; }
2686 begin()
requires (!__detail::__simple_view<_Vp>)
2687 {
return ranges::begin(_M_base); }
2690 begin() const requires range<const _Vp>
2691 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2692 {
return ranges::begin(_M_base); }
2695 end()
requires (!__detail::__simple_view<_Vp>)
2696 {
return _Sentinel<false>(ranges::end(_M_base),
2700 end() const requires range<const _Vp>
2701 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2702 {
return _Sentinel<true>(ranges::end(_M_base),
2706 template<
typename _Range,
typename _Pred>
2707 take_while_view(_Range&&, _Pred)
2708 -> take_while_view<views::all_t<_Range>, _Pred>;
2714 template<
typename _Range,
typename _Pred>
2715 concept __can_take_while_view
2719 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2721 template<viewable_range _Range,
typename _Pred>
2722 requires __detail::__can_take_while_view<_Range, _Pred>
2724 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2729 using _RangeAdaptor<_TakeWhile>::operator();
2730 static constexpr int _S_arity = 2;
2731 static constexpr bool _S_has_simple_extra_args =
true;
2734 inline constexpr _TakeWhile take_while;
2741 _Vp _M_base = _Vp();
2742 range_difference_t<_Vp> _M_count = 0;
2746 static constexpr bool _S_needs_cached_begin
2747 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2748 [[no_unique_address]]
2749 __detail::__maybe_present_t<_S_needs_cached_begin,
2750 __detail::_CachedPosition<_Vp>>
2754 drop_view()
requires default_initializable<_Vp> = default;
2757 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2758 : _M_base(std::move(__base)), _M_count(__count)
2759 { __glibcxx_assert(__count >= 0); }
2762 base() const& requires copy_constructible<_Vp>
2772 requires (!(__detail::__simple_view<_Vp>
2773 && random_access_range<const _Vp>
2774 && sized_range<const _Vp>))
2776 if constexpr (_S_needs_cached_begin)
2777 if (_M_cached_begin._M_has_value())
2778 return _M_cached_begin._M_get(_M_base);
2780 auto __it = ranges::next(ranges::begin(_M_base),
2781 _M_count, ranges::end(_M_base));
2782 if constexpr (_S_needs_cached_begin)
2783 _M_cached_begin._M_set(_M_base, __it);
2791 requires random_access_range<const _Vp> && sized_range<const _Vp>
2793 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2798 end()
requires (!__detail::__simple_view<_Vp>)
2799 {
return ranges::end(_M_base); }
2802 end() const requires range<const _Vp>
2803 {
return ranges::end(_M_base); }
2806 size()
requires sized_range<_Vp>
2808 const auto __s = ranges::size(_M_base);
2809 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2810 return __s < __c ? 0 : __s - __c;
2814 size() const requires sized_range<const _Vp>
2816 const auto __s = ranges::size(_M_base);
2817 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2818 return __s < __c ? 0 : __s - __c;
2822 template<
typename _Range>
2823 drop_view(_Range&&, range_difference_t<_Range>)
2824 -> drop_view<views::all_t<_Range>>;
2826 template<
typename _Tp>
2827 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2828 = enable_borrowed_range<_Tp>;
2834 template<
typename _Range>
2836 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2838 template<
typename _Range,
typename _Dp>
2839 concept __can_drop_view
2843 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2845 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2846 requires __detail::__can_drop_view<_Range, _Dp>
2848 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2850 using _Tp = remove_cvref_t<_Range>;
2851 if constexpr (__detail::__is_empty_view<_Tp>)
2853#ifdef __cpp_lib_optional_range_support
2854 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2857 else if constexpr (random_access_range<_Tp>
2859 && (std::__detail::__is_span<_Tp>
2860 || __detail::__is_basic_string_view<_Tp>
2861 || __detail::__is_iota_view<_Tp>
2862 || __detail::__is_subrange<_Tp>))
2865 auto __begin = ranges::begin(__r) + __n;
2866 auto __end = ranges::end(__r);
2867 if constexpr (std::__detail::__is_span<_Tp>)
2868 return span<typename _Tp::element_type>(__begin, __end);
2869 else if constexpr (__detail::__is_subrange<_Tp>)
2871 if constexpr (_Tp::_S_store_size)
2873 using ranges::__detail::__to_unsigned_like;
2874 auto __m = ranges::distance(__r) - __n;
2875 return _Tp(__begin, __end, __to_unsigned_like(__m));
2878 return _Tp(__begin, __end);
2881 return _Tp(__begin, __end);
2883 else if constexpr (__detail::__is_repeat_view<_Tp>)
2889 using _RangeAdaptor<_Drop>::operator();
2890 static constexpr int _S_arity = 2;
2891 template<
typename _Tp>
2892 static constexpr bool _S_has_simple_extra_args
2893 = _Take::_S_has_simple_extra_args<_Tp>;
2896 inline constexpr _Drop drop;
2899 template<view _Vp,
typename _Pred>
2901 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2902 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2905 _Vp _M_base = _Vp();
2906 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2907 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2910 drop_while_view()
requires (default_initializable<_Vp>
2911 && default_initializable<_Pred>)
2915 drop_while_view(_Vp __base, _Pred __pred)
2916 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2920 base() const& requires copy_constructible<_Vp>
2927 constexpr const _Pred&
2929 {
return *_M_pred; }
2934 if (_M_cached_begin._M_has_value())
2935 return _M_cached_begin._M_get(_M_base);
2937 __glibcxx_assert(_M_pred.has_value());
2938 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2939 ranges::end(_M_base),
2941 _M_cached_begin._M_set(_M_base, __it);
2947 {
return ranges::end(_M_base); }
2950 template<
typename _Range,
typename _Pred>
2951 drop_while_view(_Range&&, _Pred)
2952 -> drop_while_view<views::all_t<_Range>, _Pred>;
2954 template<
typename _Tp,
typename _Pred>
2955 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2956 = enable_borrowed_range<_Tp>;
2962 template<
typename _Range,
typename _Pred>
2963 concept __can_drop_while_view
2967 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2969 template<viewable_range _Range,
typename _Pred>
2970 requires __detail::__can_drop_while_view<_Range, _Pred>
2972 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2978 using _RangeAdaptor<_DropWhile>::operator();
2979 static constexpr int _S_arity = 2;
2980 static constexpr bool _S_has_simple_extra_args =
true;
2983 inline constexpr _DropWhile drop_while;
2988 template<
typename _Tp>
2990 __as_lvalue(_Tp&& __t)
2991 {
return static_cast<_Tp&
>(__t); }
2994 template<input_range _Vp>
2999 using _InnerRange = range_reference_t<_Vp>;
3001 template<
bool _Const>
3002 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3004 template<
bool _Const>
3005 using _Outer_iter = iterator_t<_Base<_Const>>;
3007 template<
bool _Const>
3008 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
3010 template<
bool _Const>
3011 static constexpr bool _S_ref_is_glvalue
3012 = is_reference_v<range_reference_t<_Base<_Const>>>;
3014 template<
bool _Const>
3018 template<
bool _Const>
3019 requires _S_ref_is_glvalue<_Const>
3020 && forward_range<_Base<_Const>>
3021 && forward_range<range_reference_t<_Base<_Const>>>
3022 struct __iter_cat<_Const>
3025 static constexpr auto
3028 using _Outer_iter = join_view::_Outer_iter<_Const>;
3029 using _Inner_iter = join_view::_Inner_iter<_Const>;
3030 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
3031 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
3032 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
3033 && derived_from<_InnerCat, bidirectional_iterator_tag>
3034 && common_range<range_reference_t<_Base<_Const>>>)
3035 return bidirectional_iterator_tag{};
3036 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
3037 && derived_from<_InnerCat, forward_iterator_tag>)
3038 return forward_iterator_tag{};
3040 return input_iterator_tag{};
3043 using iterator_category =
decltype(_S_iter_cat());
3046 template<
bool _Const>
3049 template<
bool _Const>
3050 struct _Iterator : __iter_cat<_Const>
3053 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3054 using _Base = join_view::_Base<_Const>;
3058 static constexpr bool _S_ref_is_glvalue
3059 = join_view::_S_ref_is_glvalue<_Const>;
3064 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
3065 if constexpr (_S_ref_is_glvalue)
3068 return _M_parent->_M_inner._M_emplace_deref(__x);
3071 _Outer_iter& __outer = _M_get_outer();
3072 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
3074 auto&& __inner = __update_inner(__outer);
3075 _M_inner = ranges::begin(__inner);
3076 if (_M_inner != ranges::end(__inner))
3080 if constexpr (_S_ref_is_glvalue)
3082 if constexpr (forward_iterator<_Inner_iter>)
3083 _M_inner = _Inner_iter();
3089 static constexpr auto
3092 if constexpr (_S_ref_is_glvalue
3093 && bidirectional_range<_Base>
3094 && bidirectional_range<range_reference_t<_Base>>
3095 && common_range<range_reference_t<_Base>>)
3096 return bidirectional_iterator_tag{};
3097 else if constexpr (_S_ref_is_glvalue
3098 && forward_range<_Base>
3099 && forward_range<range_reference_t<_Base>>)
3100 return forward_iterator_tag{};
3102 return input_iterator_tag{};
3105 using _Outer_iter = join_view::_Outer_iter<_Const>;
3106 using _Inner_iter = join_view::_Inner_iter<_Const>;
3108 constexpr _Outer_iter&
3111 if constexpr (forward_range<_Base>)
3114 return *_M_parent->_M_outer;
3117 constexpr const _Outer_iter&
3118 _M_get_outer()
const
3120 if constexpr (forward_range<_Base>)
3123 return *_M_parent->_M_outer;
3126 constexpr _Inner_iter&
3127 _M_get_inner() noexcept
3129 if constexpr (forward_iterator<_Inner_iter>)
3135 constexpr const _Inner_iter&
3136 _M_get_inner() const noexcept
3138 if constexpr (forward_iterator<_Inner_iter>)
3145 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
3146 : _M_outer(
std::move(__outer)), _M_parent(__parent)
3150 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
3151 : _M_parent(__parent)
3154 [[no_unique_address]]
3155 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
3156 =
decltype(_M_outer)();
3157 __conditional_t<forward_iterator<_Inner_iter>,
3158 _Inner_iter, optional<_Inner_iter>> _M_inner
3159 =
decltype(_M_inner)();
3160 _Parent* _M_parent =
nullptr;
3163 using iterator_concept =
decltype(_S_iter_concept());
3165 using value_type = range_value_t<range_reference_t<_Base>>;
3166 using difference_type
3168 range_difference_t<range_reference_t<_Base>>>;
3170 _Iterator() =
default;
3173 _Iterator(_Iterator<!_Const> __i)
3175 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3176 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3178 _M_parent(__i._M_parent)
3181 constexpr decltype(
auto)
3183 {
return *_M_get_inner(); }
3187 constexpr _Inner_iter
3189 requires __detail::__has_arrow<_Inner_iter>
3190 && copyable<_Inner_iter>
3191 {
return _M_get_inner(); }
3193 constexpr _Iterator&
3196 auto&& __inner_range = [
this] () ->
auto&& {
3197 if constexpr (_S_ref_is_glvalue)
3198 return *_M_get_outer();
3200 return *_M_parent->_M_inner;
3202 if (++_M_get_inner() == ranges::end(__inner_range))
3216 requires _S_ref_is_glvalue && forward_range<_Base>
3217 && forward_range<range_reference_t<_Base>>
3224 constexpr _Iterator&
3226 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3227 && bidirectional_range<range_reference_t<_Base>>
3228 && common_range<range_reference_t<_Base>>
3230 if (_M_outer == ranges::end(_M_parent->_M_base))
3231 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3232 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3233 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3240 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3241 && bidirectional_range<range_reference_t<_Base>>
3242 && common_range<range_reference_t<_Base>>
3249 friend constexpr bool
3250 operator==(
const _Iterator& __x,
const _Iterator& __y)
3251 requires _S_ref_is_glvalue
3252 && forward_range<_Base>
3253 && equality_comparable<_Inner_iter>
3255 return (__x._M_outer == __y._M_outer
3256 && __x._M_inner == __y._M_inner);
3259 friend constexpr decltype(
auto)
3260 iter_move(
const _Iterator& __i)
3261 noexcept(
noexcept(ranges::iter_move(__i._M_get_inner())))
3262 {
return ranges::iter_move(__i._M_get_inner()); }
3264 friend constexpr void
3265 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3266 noexcept(
noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3267 requires indirectly_swappable<_Inner_iter>
3268 {
return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3270 friend _Iterator<!_Const>;
3271 template<
bool>
friend struct _Sentinel;
3274 template<
bool _Const>
3278 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3279 using _Base = join_view::_Base<_Const>;
3281 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3284 _Sentinel() =
default;
3287 _Sentinel(_Parent* __parent)
3288 : _M_end(ranges::end(__parent->_M_base))
3292 _Sentinel(_Sentinel<!_Const> __s)
3293 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3297 template<
bool _Const2>
3298 requires sentinel_for<sentinel_t<_Base>,
3299 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3300 friend constexpr bool
3301 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3302 {
return __x._M_get_outer() == __y._M_end; }
3304 friend _Sentinel<!_Const>;
3307 _Vp _M_base = _Vp();
3308 [[no_unique_address]]
3309 __detail::__maybe_present_t<!forward_range<_Vp>,
3310 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3311 [[no_unique_address]]
3312 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3315 join_view()
requires default_initializable<_Vp> = default;
3318 join_view(_Vp __base)
3319 : _M_base(std::move(__base))
3323 base() const& requires copy_constructible<_Vp>
3333 if constexpr (forward_range<_Vp>)
3335 constexpr bool __use_const
3336 = (__detail::__simple_view<_Vp>
3337 && is_reference_v<range_reference_t<_Vp>>);
3338 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3342 _M_outer = ranges::begin(_M_base);
3343 return _Iterator<false>{
this};
3349 requires forward_range<const _Vp>
3350 && is_reference_v<range_reference_t<const _Vp>>
3351 && input_range<range_reference_t<const _Vp>>
3353 return _Iterator<true>{
this, ranges::begin(_M_base)};
3359 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3360 && forward_range<_InnerRange>
3361 && common_range<_Vp> && common_range<_InnerRange>)
3362 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3363 ranges::end(_M_base)};
3365 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3370 requires forward_range<const _Vp>
3371 && is_reference_v<range_reference_t<const _Vp>>
3372 && input_range<range_reference_t<const _Vp>>
3374 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3375 && forward_range<range_reference_t<const _Vp>>
3376 && common_range<const _Vp>
3377 && common_range<range_reference_t<const _Vp>>)
3378 return _Iterator<true>{
this, ranges::end(_M_base)};
3380 return _Sentinel<true>{
this};
3384 template<
typename _Range>
3385 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3391 template<
typename _Range>
3392 concept __can_join_view
3396 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3398 template<viewable_range _Range>
3399 requires __detail::__can_join_view<_Range>
3401 operator() [[nodiscard]] (_Range&& __r)
const
3408 static constexpr bool _S_has_simple_call_op =
true;
3411 inline constexpr _Join join;
3417 struct __require_constant;
3419 template<
typename _Range>
3420 concept __tiny_range = sized_range<_Range>
3422 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3423 && (remove_reference_t<_Range>::size() <= 1);
3425 template<
typename _Base>
3426 struct __lazy_split_view_outer_iter_cat
3429 template<forward_range _Base>
3430 struct __lazy_split_view_outer_iter_cat<_Base>
3431 {
using iterator_category = input_iterator_tag; };
3433 template<
typename _Base>
3434 struct __lazy_split_view_inner_iter_cat
3437 template<forward_range _Base>
3438 struct __lazy_split_view_inner_iter_cat<_Base>
3441 static constexpr auto
3444 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3445 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3446 return forward_iterator_tag{};
3451 using iterator_category =
decltype(_S_iter_cat());
3455 template<input_range _Vp, forward_range _Pattern>
3457 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3460 class lazy_split_view : public
view_interface<lazy_split_view<_Vp, _Pattern>>
3463 template<
bool _Const>
3464 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3466 template<
bool _Const>
3469 template<
bool _Const>
3471 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3474 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3475 using _Base = lazy_split_view::_Base<_Const>;
3482 __current() noexcept
3484 if constexpr (forward_range<_Vp>)
3487 return *_M_parent->_M_current;
3491 __current() const noexcept
3493 if constexpr (forward_range<_Vp>)
3496 return *_M_parent->_M_current;
3499 _Parent* _M_parent =
nullptr;
3501 [[no_unique_address]]
3502 __detail::__maybe_present_t<forward_range<_Vp>,
3503 iterator_t<_Base>> _M_current
3504 =
decltype(_M_current)();
3505 bool _M_trailing_empty =
false;
3508 using iterator_concept = __conditional_t<forward_range<_Base>,
3509 forward_iterator_tag,
3510 input_iterator_tag>;
3512 using difference_type = range_difference_t<_Base>;
3514 struct value_type : view_interface<value_type>
3517 _OuterIter _M_i = _OuterIter();
3523 value_type(_OuterIter __i)
3524 : _M_i(std::move(__i))
3530 constexpr _InnerIter<_Const>
3532 {
return _InnerIter<_Const>{_M_i}; }
3534 constexpr default_sentinel_t
3535 end() const noexcept
3539 _OuterIter() =
default;
3542 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3543 : _M_parent(__parent)
3547 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3548 requires forward_range<_Base>
3549 : _M_parent(__parent),
3554 _OuterIter(_OuterIter<!_Const> __i)
3556 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3557 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3558 _M_trailing_empty(__i._M_trailing_empty)
3561 constexpr value_type
3563 {
return value_type{*
this}; }
3565 constexpr _OuterIter&
3570 const auto __end = ranges::end(_M_parent->_M_base);
3571 if (__current() == __end)
3573 _M_trailing_empty =
false;
3576 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3577 if (__pbegin == __pend)
3579 else if constexpr (__detail::__tiny_range<_Pattern>)
3581 __current() = ranges::find(
std::move(__current()), __end,
3583 if (__current() != __end)
3586 if (__current() == __end)
3587 _M_trailing_empty =
true;
3594 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3598 if (__current() == __end)
3599 _M_trailing_empty =
true;
3602 }
while (++__current() != __end);
3606 constexpr decltype(
auto)
3609 if constexpr (forward_range<_Base>)
3619 friend constexpr bool
3620 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3621 requires forward_range<_Base>
3623 return __x._M_current == __y._M_current
3624 && __x._M_trailing_empty == __y._M_trailing_empty;
3627 friend constexpr bool
3628 operator==(
const _OuterIter& __x, default_sentinel_t)
3630 return __x.__current() == ranges::end(__x._M_parent->_M_base)
3631 && !__x._M_trailing_empty;
3634 friend _OuterIter<!_Const>;
3635 friend _InnerIter<_Const>;
3638 template<
bool _Const>
3640 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3643 using _Base = lazy_split_view::_Base<_Const>;
3648 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3649 auto __end = ranges::end(_M_i._M_parent->_M_base);
3650 if constexpr (__detail::__tiny_range<_Pattern>)
3652 const auto& __cur = _M_i_current();
3655 if (__pcur == __pend)
3656 return _M_incremented;
3657 return *__cur == *__pcur;
3661 auto __cur = _M_i_current();
3664 if (__pcur == __pend)
3665 return _M_incremented;
3668 if (*__cur != *__pcur)
3670 if (++__pcur == __pend)
3672 }
while (++__cur != __end);
3678 _M_i_current() noexcept
3679 {
return _M_i.__current(); }
3682 _M_i_current() const noexcept
3683 {
return _M_i.__current(); }
3685 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3686 bool _M_incremented =
false;
3689 using iterator_concept
3690 =
typename _OuterIter<_Const>::iterator_concept;
3692 using value_type = range_value_t<_Base>;
3693 using difference_type = range_difference_t<_Base>;
3695 _InnerIter() =
default;
3698 _InnerIter(_OuterIter<_Const> __i)
3699 : _M_i(std::move(__i))
3702 constexpr const iterator_t<_Base>&
3703 base() const& noexcept
3704 {
return _M_i_current(); }
3706 constexpr iterator_t<_Base>
3707 base() &&
requires forward_range<_Vp>
3710 constexpr decltype(
auto)
3712 {
return *_M_i_current(); }
3714 constexpr _InnerIter&
3717 _M_incremented =
true;
3718 if constexpr (!forward_range<_Base>)
3719 if constexpr (_Pattern::size() == 0)
3725 constexpr decltype(
auto)
3728 if constexpr (forward_range<_Base>)
3738 friend constexpr bool
3739 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3740 requires forward_range<_Base>
3741 {
return __x._M_i == __y._M_i; }
3743 friend constexpr bool
3744 operator==(
const _InnerIter& __x, default_sentinel_t)
3745 {
return __x.__at_end(); }
3747 friend constexpr decltype(
auto)
3748 iter_move(
const _InnerIter& __i)
3749 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3750 {
return ranges::iter_move(__i._M_i_current()); }
3752 friend constexpr void
3753 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3754 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3755 __y._M_i_current())))
3756 requires indirectly_swappable<iterator_t<_Base>>
3757 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3760 _Vp _M_base = _Vp();
3761 _Pattern _M_pattern = _Pattern();
3762 [[no_unique_address]]
3763 __detail::__maybe_present_t<!forward_range<_Vp>,
3764 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3768 lazy_split_view()
requires (default_initializable<_Vp>
3769 && default_initializable<_Pattern>)
3773 lazy_split_view(_Vp __base, _Pattern __pattern)
3774 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3777 template<input_range _Range>
3778 requires constructible_from<_Vp, views::all_t<_Range>>
3779 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3781 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3782 : _M_base(views::all(std::
forward<_Range>(__r))),
3783 _M_pattern(views::single(std::move(__e)))
3787 base() const& requires copy_constructible<_Vp>
3797 if constexpr (forward_range<_Vp>)
3799 constexpr bool __simple
3800 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3801 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3805 _M_current = ranges::begin(_M_base);
3806 return _OuterIter<false>{
this};
3811 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3813 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3817 end()
requires forward_range<_Vp> && common_range<_Vp>
3819 constexpr bool __simple
3820 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3821 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3827 if constexpr (forward_range<_Vp>
3828 && forward_range<const _Vp>
3829 && common_range<const _Vp>)
3830 return _OuterIter<true>{
this, ranges::end(_M_base)};
3836 template<
typename _Range,
typename _Pattern>
3837 lazy_split_view(_Range&&, _Pattern&&)
3838 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3840 template<input_range _Range>
3841 lazy_split_view(_Range&&, range_value_t<_Range>)
3848 template<
typename _Range,
typename _Pattern>
3849 concept __can_lazy_split_view
3853 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3855 template<viewable_range _Range,
typename _Pattern>
3856 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3858 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3863 using _RangeAdaptor<_LazySplit>::operator();
3864 static constexpr int _S_arity = 2;
3869 template<
typename _Pattern>
3870 static constexpr bool _S_has_simple_extra_args
3871 = is_scalar_v<_Pattern> || (view<_Pattern>
3872 && copy_constructible<_Pattern>);
3875 inline constexpr _LazySplit lazy_split;
3878 template<forward_range _Vp, forward_range _Pattern>
3880 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3882 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3885 _Vp _M_base = _Vp();
3886 _Pattern _M_pattern = _Pattern();
3887 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3893 split_view()
requires (default_initializable<_Vp>
3894 && default_initializable<_Pattern>)
3898 split_view(_Vp __base, _Pattern __pattern)
3899 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3902 template<forward_range _Range>
3903 requires constructible_from<_Vp, views::all_t<_Range>>
3904 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3906 split_view(_Range&& __r, range_value_t<_Range> __e)
3907 : _M_base(views::all(std::
forward<_Range>(__r))),
3908 _M_pattern(views::single(std::move(__e)))
3912 base() const& requires copy_constructible<_Vp>
3922 if (!_M_cached_begin)
3923 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3924 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3930 if constexpr (common_range<_Vp>)
3931 return _Iterator{
this, ranges::end(_M_base), {}};
3933 return _Sentinel{
this};
3936 constexpr subrange<iterator_t<_Vp>>
3937 _M_find_next(iterator_t<_Vp> __it)
3939 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3940 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3952 split_view* _M_parent =
nullptr;
3953 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3954 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3955 bool _M_trailing_empty =
false;
3957 friend struct _Sentinel;
3960 using iterator_concept = forward_iterator_tag;
3961 using iterator_category = input_iterator_tag;
3962 using value_type = subrange<iterator_t<_Vp>>;
3963 using difference_type = range_difference_t<_Vp>;
3965 _Iterator() =
default;
3968 _Iterator(split_view* __parent,
3969 iterator_t<_Vp> __current,
3970 subrange<iterator_t<_Vp>> __next)
3971 : _M_parent(__parent),
3972 _M_cur(std::move(__current)),
3973 _M_next(std::move(__next))
3976 constexpr iterator_t<_Vp>
3980 constexpr value_type
3982 {
return {_M_cur, _M_next.begin()}; }
3984 constexpr _Iterator&
3987 _M_cur = _M_next.begin();
3988 if (_M_cur != ranges::end(_M_parent->_M_base))
3990 _M_cur = _M_next.end();
3991 if (_M_cur == ranges::end(_M_parent->_M_base))
3993 _M_trailing_empty =
true;
3994 _M_next = {_M_cur, _M_cur};
3997 _M_next = _M_parent->_M_find_next(_M_cur);
4000 _M_trailing_empty =
false;
4012 friend constexpr bool
4013 operator==(
const _Iterator& __x,
const _Iterator& __y)
4015 return __x._M_cur == __y._M_cur
4016 && __x._M_trailing_empty == __y._M_trailing_empty;
4023 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
4026 _Sentinel() =
default;
4029 _Sentinel(split_view* __parent)
4030 : _M_end(ranges::end(__parent->_M_base))
4033 friend constexpr bool
4034 operator==(
const _Iterator& __x,
const _Sentinel& __y)
4035 {
return __x._M_cur == __y._M_end && !__x._M_trailing_empty; }
4039 template<
typename _Range,
typename _Pattern>
4040 split_view(_Range&&, _Pattern&&)
4041 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
4043 template<forward_range _Range>
4044 split_view(_Range&&, range_value_t<_Range>)
4051 template<
typename _Range,
typename _Pattern>
4052 concept __can_split_view
4056 struct _Split : __adaptor::_RangeAdaptor<_Split>
4058 template<viewable_range _Range,
typename _Pattern>
4059 requires __detail::__can_split_view<_Range, _Pattern>
4061 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
4066 using _RangeAdaptor<_Split>::operator();
4067 static constexpr int _S_arity = 2;
4068 template<
typename _Pattern>
4069 static constexpr bool _S_has_simple_extra_args
4070 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
4073 inline constexpr _Split split;
4080 template<input_or_output_iterator _Iter>
4082 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
4084 if constexpr (contiguous_iterator<_Iter>)
4086 else if constexpr (random_access_iterator<_Iter>)
4087 return subrange(__i, __i + __n);
4089 return subrange(counted_iterator(
std::move(__i), __n),
4094 inline constexpr _Counted counted{};
4102 _Vp _M_base = _Vp();
4105 common_view()
requires default_initializable<_Vp> = default;
4108 common_view(_Vp __r)
4109 : _M_base(std::move(__r))
4113 base() const& requires copy_constructible<_Vp>
4123 begin()
requires (!__detail::__simple_view<_Vp>)
4126 return ranges::begin(_M_base);
4128 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4129 (ranges::begin(_M_base));
4136 return ranges::begin(_M_base);
4138 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4139 (ranges::begin(_M_base));
4143 end()
requires (!__detail::__simple_view<_Vp>)
4146 return ranges::begin(_M_base) + ranges::size(_M_base);
4148 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4149 (ranges::end(_M_base));
4153 end() const requires
range<const _Vp>
4156 return ranges::begin(_M_base) + ranges::size(_M_base);
4158 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4159 (ranges::end(_M_base));
4164 {
return ranges::size(_M_base); }
4168 {
return ranges::size(_M_base); }
4171 template<
typename _Range>
4172 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4174 template<
typename _Tp>
4175 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4176 = enable_borrowed_range<_Tp>;
4182 template<
typename _Range>
4183 concept __already_common = common_range<_Range>
4186 template<
typename _Range>
4187 concept __can_common_view
4191 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4193 template<viewable_range _Range>
4194 requires __detail::__already_common<_Range>
4195 || __detail::__can_common_view<_Range>
4197 operator() [[nodiscard]] (_Range&& __r)
const
4199 if constexpr (__detail::__already_common<_Range>)
4205 static constexpr bool _S_has_simple_call_op =
true;
4208 inline constexpr _Common common;
4216 static constexpr bool _S_needs_cached_begin
4217 = !common_range<_Vp> && !(random_access_range<_Vp>
4218 && sized_sentinel_for<sentinel_t<_Vp>,
4221 _Vp _M_base = _Vp();
4222 [[no_unique_address]]
4223 __detail::__maybe_present_t<_S_needs_cached_begin,
4224 __detail::_CachedPosition<_Vp>>
4228 reverse_view()
requires default_initializable<_Vp> = default;
4231 reverse_view(_Vp __r)
4232 : _M_base(std::move(__r))
4236 base() const& requires copy_constructible<_Vp>
4243 constexpr reverse_iterator<iterator_t<_Vp>>
4246 if constexpr (_S_needs_cached_begin)
4247 if (_M_cached_begin._M_has_value())
4250 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4251 if constexpr (_S_needs_cached_begin)
4252 _M_cached_begin._M_set(_M_base, __it);
4257 begin()
requires common_range<_Vp>
4261 begin() const requires common_range<const _Vp>
4264 constexpr reverse_iterator<iterator_t<_Vp>>
4269 end() const requires common_range<const _Vp>
4273 size()
requires sized_range<_Vp>
4274 {
return ranges::size(_M_base); }
4277 size() const requires sized_range<const _Vp>
4278 {
return ranges::size(_M_base); }
4281 template<
typename _Range>
4282 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4284 template<
typename _Tp>
4285 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4286 = enable_borrowed_range<_Tp>;
4293 inline constexpr bool __is_reversible_subrange =
false;
4295 template<
typename _Iter, subrange_kind _Kind>
4296 inline constexpr bool
4297 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4298 reverse_iterator<_Iter>,
4302 inline constexpr bool __is_reverse_view =
false;
4304 template<
typename _Vp>
4305 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4307 template<
typename _Range>
4308 concept __can_reverse_view
4312 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4314 template<viewable_range _Range>
4315 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4316 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4317 || __detail::__can_reverse_view<_Range>
4319 operator() [[nodiscard]] (_Range&& __r)
const
4321 using _Tp = remove_cvref_t<_Range>;
4322 if constexpr (__detail::__is_reverse_view<_Tp>)
4324#ifdef __cpp_lib_optional_range_support
4325 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
4328 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4330 using _Iter =
decltype(ranges::begin(__r).base());
4331 if constexpr (sized_range<_Tp>)
4332 return subrange<_Iter, _Iter, subrange_kind::sized>
4333 {__r.end().base(), __r.begin().base(), __r.size()};
4335 return subrange<_Iter, _Iter, subrange_kind::unsized>
4336 {__r.end().base(), __r.begin().base()};
4342 static constexpr bool _S_has_simple_call_op =
true;
4345 inline constexpr _Reverse reverse;
4350#if __cpp_lib_tuple_like
4351 template<
typename _Tp,
size_t _Nm>
4352 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4354 template<
typename _Tp,
size_t _Nm>
4355 concept __has_tuple_element =
requires(_Tp __t)
4357 typename tuple_size<_Tp>::type;
4358 requires _Nm < tuple_size_v<_Tp>;
4359 typename tuple_element_t<_Nm, _Tp>;
4360 { std::get<_Nm>(__t) }
4361 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4365 template<
typename _Tp,
size_t _Nm>
4366 concept __returnable_element
4367 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4370 template<input_range _Vp,
size_t _Nm>
4372 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4373 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4375 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4376 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4379 elements_view()
requires default_initializable<_Vp> = default;
4382 elements_view(_Vp __base)
4383 : _M_base(std::move(__base))
4387 base() const& requires copy_constructible<_Vp>
4395 begin()
requires (!__detail::__simple_view<_Vp>)
4396 {
return _Iterator<false>(ranges::begin(_M_base)); }
4399 begin() const requires range<const _Vp>
4400 {
return _Iterator<true>(ranges::begin(_M_base)); }
4403 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4404 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4407 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4408 {
return _Iterator<false>{ranges::end(_M_base)}; }
4411 end() const requires range<const _Vp>
4412 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4415 end() const requires common_range<const _Vp>
4416 {
return _Iterator<true>{ranges::end(_M_base)}; }
4419 size()
requires sized_range<_Vp>
4420 {
return ranges::size(_M_base); }
4423 size() const requires sized_range<const _Vp>
4424 {
return ranges::size(_M_base); }
4427 template<
bool _Const>
4428 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4430 template<
bool _Const>
4434 template<
bool _Const>
4435 requires forward_range<_Base<_Const>>
4436 struct __iter_cat<_Const>
4439 static auto _S_iter_cat()
4441 using _Base = elements_view::_Base<_Const>;
4442 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4443 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4444 if constexpr (!is_lvalue_reference_v<_Res>)
4445 return input_iterator_tag{};
4446 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4447 return random_access_iterator_tag{};
4452 using iterator_category =
decltype(_S_iter_cat());
4455 template<
bool _Const>
4458 template<
bool _Const>
4459 struct _Iterator : __iter_cat<_Const>
4462 using _Base = elements_view::_Base<_Const>;
4464 iterator_t<_Base> _M_current = iterator_t<_Base>();
4466 static constexpr decltype(
auto)
4467 _S_get_element(
const iterator_t<_Base>& __i)
4469 if constexpr (is_reference_v<range_reference_t<_Base>>)
4470 return std::get<_Nm>(*__i);
4473 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4474 return static_cast<_Et
>(std::get<_Nm>(*__i));
4481 if constexpr (random_access_range<_Base>)
4482 return random_access_iterator_tag{};
4483 else if constexpr (bidirectional_range<_Base>)
4484 return bidirectional_iterator_tag{};
4485 else if constexpr (forward_range<_Base>)
4486 return forward_iterator_tag{};
4488 return input_iterator_tag{};
4491 friend _Iterator<!_Const>;
4494 using iterator_concept =
decltype(_S_iter_concept());
4497 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4498 using difference_type = range_difference_t<_Base>;
4500 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4503 _Iterator(iterator_t<_Base> __current)
4504 : _M_current(std::move(__current))
4508 _Iterator(_Iterator<!_Const> __i)
4509 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4513 constexpr const iterator_t<_Base>&
4514 base() const& noexcept
4515 {
return _M_current; }
4517 constexpr iterator_t<_Base>
4521 constexpr decltype(
auto)
4523 {
return _S_get_element(_M_current); }
4525 constexpr _Iterator&
4537 operator++(
int)
requires forward_range<_Base>
4544 constexpr _Iterator&
4545 operator--()
requires bidirectional_range<_Base>
4552 operator--(
int)
requires bidirectional_range<_Base>
4559 constexpr _Iterator&
4560 operator+=(difference_type __n)
4561 requires random_access_range<_Base>
4567 constexpr _Iterator&
4568 operator-=(difference_type __n)
4569 requires random_access_range<_Base>
4575 constexpr decltype(
auto)
4576 operator[](difference_type __n)
const
4577 requires random_access_range<_Base>
4578 {
return _S_get_element(_M_current + __n); }
4580 friend constexpr bool
4581 operator==(
const _Iterator& __x,
const _Iterator& __y)
4582 requires equality_comparable<iterator_t<_Base>>
4583 {
return __x._M_current == __y._M_current; }
4585 friend constexpr bool
4586 operator<(
const _Iterator& __x,
const _Iterator& __y)
4587 requires random_access_range<_Base>
4588 {
return __x._M_current < __y._M_current; }
4590 friend constexpr bool
4591 operator>(
const _Iterator& __x,
const _Iterator& __y)
4592 requires random_access_range<_Base>
4593 {
return __y._M_current < __x._M_current; }
4595 friend constexpr bool
4596 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4597 requires random_access_range<_Base>
4598 {
return !(__y._M_current > __x._M_current); }
4600 friend constexpr bool
4601 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4602 requires random_access_range<_Base>
4603 {
return !(__x._M_current > __y._M_current); }
4605#ifdef __cpp_lib_three_way_comparison
4606 friend constexpr auto
4607 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4608 requires random_access_range<_Base>
4609 && three_way_comparable<iterator_t<_Base>>
4610 {
return __x._M_current <=> __y._M_current; }
4613 friend constexpr _Iterator
4614 operator+(
const _Iterator& __x, difference_type __y)
4615 requires random_access_range<_Base>
4616 {
return _Iterator{__x} += __y; }
4618 friend constexpr _Iterator
4619 operator+(difference_type __x,
const _Iterator& __y)
4620 requires random_access_range<_Base>
4621 {
return __y + __x; }
4623 friend constexpr _Iterator
4624 operator-(
const _Iterator& __x, difference_type __y)
4625 requires random_access_range<_Base>
4626 {
return _Iterator{__x} -= __y; }
4630 friend constexpr difference_type
4631 operator-(
const _Iterator& __x,
const _Iterator& __y)
4632 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4633 {
return __x._M_current - __y._M_current; }
4635 template <
bool>
friend struct _Sentinel;
4638 template<
bool _Const>
4642 using _Base = elements_view::_Base<_Const>;
4643 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4646 _Sentinel() =
default;
4649 _Sentinel(sentinel_t<_Base> __end)
4650 : _M_end(std::move(__end))
4654 _Sentinel(_Sentinel<!_Const> __other)
4656 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4660 constexpr sentinel_t<_Base>
4664 template<
bool _Const2>
4665 requires sentinel_for<sentinel_t<_Base>,
4666 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4667 friend constexpr bool
4668 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4669 {
return __x._M_current == __y._M_end; }
4671 template<
bool _Const2,
4672 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4673 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4674 friend constexpr range_difference_t<_Base2>
4675 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4676 {
return -(__y._M_end - __x._M_current); }
4678 template<
bool _Const2,
4679 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4680 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4681 friend constexpr range_difference_t<_Base2>
4682 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4683 {
return __x._M_end - __y._M_current; }
4685 friend _Sentinel<!_Const>;
4688 _Vp _M_base = _Vp();
4691 template<
typename _Tp,
size_t _Nm>
4692 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4693 = enable_borrowed_range<_Tp>;
4697 template<
typename _Range>
4698 using keys_view = elements_view<_Range, 0>;
4700 template<
typename _Range>
4701 using values_view = elements_view<_Range, 1>;
4707 template<
size_t _Nm,
typename _Range>
4708 concept __can_elements_view
4712 template<
size_t _Nm>
4713 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4715 template<viewable_range _Range>
4716 requires __detail::__can_elements_view<_Nm, _Range>
4718 operator() [[nodiscard]] (_Range&& __r)
const
4723 static constexpr bool _S_has_simple_call_op =
true;
4726 template<
size_t _Nm>
4727 inline constexpr _Elements<_Nm> elements;
4728 inline constexpr auto keys = elements<0>;
4729 inline constexpr auto values = elements<1>;
4732#ifdef __cpp_lib_ranges_zip
4735 template<
typename... _Rs>
4736 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4737 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4738 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4740 template<
typename _Fp,
typename _Tuple>
4742 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4744 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4745 return tuple<invoke_result_t<_Fp&, _Ts>...>
4750 template<
typename _Fp,
typename _Tuple>
4752 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4754 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4761 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4764 tuple<_Vs...> _M_views;
4766 template<
bool>
class _Iterator;
4767 template<
bool>
class _Sentinel;
4770 zip_view() =
default;
4773 zip_view(_Vs... __views)
4774 : _M_views(std::move(__views)...)
4778 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4779 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4782 begin() const requires (
range<const _Vs> && ...)
4783 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4786 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4788 if constexpr (!__detail::__zip_is_common<_Vs...>)
4789 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4791 return begin() + iter_difference_t<_Iterator<false>>(
size());
4793 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4797 end() const requires (
range<const _Vs> && ...)
4799 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4800 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4802 return begin() + iter_difference_t<_Iterator<true>>(
size());
4804 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4810 return std::apply([](
auto... __sizes) {
4811 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4812 return ranges::min({_CT(__sizes)...});
4813 }, __detail::__tuple_transform(ranges::size, _M_views));
4819 return std::apply([](
auto... __sizes) {
4820 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4821 return ranges::min({_CT(__sizes)...});
4822 }, __detail::__tuple_transform(ranges::size, _M_views));
4826 template<
typename... _Rs>
4827 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4829 template<
typename... _Views>
4830 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4831 = (enable_borrowed_range<_Views> && ...);
4835 template<
bool _Const,
typename... _Vs>
4836 concept __all_random_access
4837 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4839 template<
bool _Const,
typename... _Vs>
4840 concept __all_bidirectional
4841 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4843 template<
bool _Const,
typename... _Vs>
4844 concept __all_forward
4845 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4847 template<
bool _Const,
typename... _Views>
4848 struct __zip_view_iter_cat
4851 template<
bool _Const,
typename... _Views>
4852 requires __all_forward<_Const, _Views...>
4853 struct __zip_view_iter_cat<_Const, _Views...>
4854 {
using iterator_category = input_iterator_tag; };
4858 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4859 template<bool _Const>
4860 class zip_view<_Vs...>::_Iterator
4861 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4863#ifdef _GLIBCXX_CLANG
4866 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4869 _Iterator(
decltype(_M_current) __current)
4870 : _M_current(std::move(__current))
4876 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4877 return random_access_iterator_tag{};
4878 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4879 return bidirectional_iterator_tag{};
4880 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4881 return forward_iterator_tag{};
4883 return input_iterator_tag{};
4886#ifndef _GLIBCXX_CLANG
4887 template<move_constructible _Fp,
input_range... _Ws>
4888 requires (
view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4889 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4890 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4891 friend class zip_transform_view;
4896 using iterator_concept =
decltype(_S_iter_concept());
4898 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4899 using difference_type
4902 _Iterator() =
default;
4905 _Iterator(_Iterator<!_Const> __i)
4907 && (convertible_to<iterator_t<_Vs>,
4908 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4909 : _M_current(std::move(__i._M_current))
4915 auto __f = [](
auto& __i) ->
decltype(
auto) {
4918 return __detail::__tuple_transform(__f, _M_current);
4921 constexpr _Iterator&
4924 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4934 requires __detail::__all_forward<_Const, _Vs...>
4941 constexpr _Iterator&
4943 requires __detail::__all_bidirectional<_Const, _Vs...>
4945 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4951 requires __detail::__all_bidirectional<_Const, _Vs...>
4958 constexpr _Iterator&
4959 operator+=(difference_type __x)
4960 requires __detail::__all_random_access<_Const, _Vs...>
4962 auto __f = [&]<
typename _It>(_It& __i) {
4963 __i += iter_difference_t<_It>(__x);
4965 __detail::__tuple_for_each(__f, _M_current);
4969 constexpr _Iterator&
4970 operator-=(difference_type __x)
4971 requires __detail::__all_random_access<_Const, _Vs...>
4973 auto __f = [&]<
typename _It>(_It& __i) {
4974 __i -= iter_difference_t<_It>(__x);
4976 __detail::__tuple_for_each(__f, _M_current);
4981 operator[](difference_type __n)
const
4982 requires __detail::__all_random_access<_Const, _Vs...>
4984 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
4985 return __i[iter_difference_t<_It>(__n)];
4987 return __detail::__tuple_transform(__f, _M_current);
4990 friend constexpr bool
4991 operator==(
const _Iterator& __x,
const _Iterator& __y)
4992 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4994 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4995 return __x._M_current == __y._M_current;
4998 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
5002 friend constexpr auto
5003 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5004 requires __detail::__all_random_access<_Const, _Vs...>
5005 {
return __x._M_current <=> __y._M_current; }
5007 friend constexpr _Iterator
5008 operator+(
const _Iterator& __i, difference_type __n)
5009 requires __detail::__all_random_access<_Const, _Vs...>
5016 friend constexpr _Iterator
5017 operator+(difference_type __n,
const _Iterator& __i)
5018 requires __detail::__all_random_access<_Const, _Vs...>
5025 friend constexpr _Iterator
5026 operator-(
const _Iterator& __i, difference_type __n)
5027 requires __detail::__all_random_access<_Const, _Vs...>
5034 friend constexpr difference_type
5035 operator-(
const _Iterator& __x,
const _Iterator& __y)
5036 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
5037 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5040 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
5041 - std::get<_Is>(__y._M_current))...},
5043 [](difference_type __i) {
5044 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5049 friend constexpr auto
5050 iter_move(
const _Iterator& __i)
5051 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5053 friend constexpr void
5054 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5055 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5058 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
5062 friend class zip_view;
5066 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
5067 template<bool _Const>
5068 class zip_view<_Vs...>::_Sentinel
5070 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
5073 _Sentinel(
decltype(_M_end) __end)
5077 friend class zip_view;
5080 _Sentinel() =
default;
5083 _Sentinel(_Sentinel<!_Const> __i)
5085 && (convertible_to<sentinel_t<_Vs>,
5086 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5087 : _M_end(std::move(__i._M_end))
5090 template<
bool _OtherConst>
5091 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5092 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5093 friend constexpr bool
5094 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5097 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
5101 template<
bool _OtherConst>
5102 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5103 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5104 friend constexpr auto
5105 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5110 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
5113 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5118 template<
bool _OtherConst>
5119 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5120 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5121 friend constexpr auto
5122 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5123 {
return -(__x - __y); }
5130 template<
typename... _Ts>
5131 concept __can_zip_view
5137 template<
typename... _Ts>
5138 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5140 operator() [[nodiscard]] (_Ts&&... __ts)
const
5142 if constexpr (
sizeof...(_Ts) == 0)
5143 return views::empty<tuple<>>;
5149 inline constexpr _Zip zip;
5154 template<
typename _Range,
bool _Const>
5155 using __range_iter_cat
5156 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5159 template<move_constructible _Fp,
input_range... _Vs>
5160 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5161 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5162 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5163 class zip_transform_view : public
view_interface<zip_transform_view<_Fp, _Vs...>>
5165 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5166 zip_view<_Vs...> _M_zip;
5168 using _InnerView = zip_view<_Vs...>;
5170 template<
bool _Const>
5171 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5173 template<
bool _Const>
5174 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5176 template<
bool _Const>
5177 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5179 template<
bool _Const>
5183 template<
bool _Const>
5185 struct __iter_cat<_Const>
5191 using __detail::__maybe_const_t;
5192 using __detail::__range_iter_cat;
5193 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5194 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5197 if constexpr (!is_reference_v<_Res>)
5198 return input_iterator_tag{};
5199 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5200 random_access_iterator_tag> && ...))
5201 return random_access_iterator_tag{};
5202 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5203 bidirectional_iterator_tag> && ...))
5204 return bidirectional_iterator_tag{};
5205 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5206 forward_iterator_tag> && ...))
5207 return forward_iterator_tag{};
5209 return input_iterator_tag{};
5212 using iterator_category =
decltype(_S_iter_cat());
5215 template<
bool>
class _Iterator;
5216 template<
bool>
class _Sentinel;
5219 zip_transform_view() =
default;
5222 zip_transform_view(_Fp __fun, _Vs... __views)
5223 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5228 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5232 requires
range<const _InnerView>
5233 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5234 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5240 return _Iterator<false>(*
this, _M_zip.end());
5242 return _Sentinel<false>(_M_zip.end());
5247 requires
range<const _InnerView>
5248 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5251 return _Iterator<true>(*
this, _M_zip.end());
5253 return _Sentinel<true>(_M_zip.end());
5258 {
return _M_zip.size(); }
5262 {
return _M_zip.size(); }
5265 template<
class _Fp,
class... _Rs>
5266 zip_transform_view(_Fp, _Rs&&...)
5267 -> zip_transform_view<_Fp, views::all_t<_Rs>...>;
5269 template<move_constructible _Fp,
input_range... _Vs>
5270 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5271 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5272 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5273 template<bool _Const>
5274 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5276 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5277 using _Fun_handle = __detail::__func_handle_t<
5278 __detail::__maybe_const_t<_Const, _Fp>,
5279 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
5281 [[no_unique_address]] _Fun_handle _M_fun;
5282 __ziperator<_Const> _M_inner;
5285 _Iterator(_Fun_handle __fun, __ziperator<_Const> __inner)
5286 : _M_fun(__fun), _M_inner(std::move(__inner))
5290 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5291 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
5294 friend class zip_transform_view;
5298 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5300 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5301 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5302 using difference_type = range_difference_t<_Base<_Const>>;
5304 _Iterator() =
default;
5307 _Iterator(_Iterator<!_Const> __i)
5308 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5309 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
5312 constexpr decltype(
auto)
5315 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5316 return _M_fun._M_call_deref(__iters...);
5317 }, _M_inner._M_current);
5320 constexpr _Iterator&
5339 constexpr _Iterator&
5354 constexpr _Iterator&
5361 constexpr _Iterator&
5368 constexpr decltype(
auto)
5371 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5372 return _M_fun._M_call_subscript(__n, __iters...);
5373 }, _M_inner._M_current);
5376 friend constexpr bool
5377 operator==(
const _Iterator& __x,
const _Iterator& __y)
5378 requires equality_comparable<__ziperator<_Const>>
5379 {
return __x._M_inner == __y._M_inner; }
5381 friend constexpr auto
5382 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5384 {
return __x._M_inner <=> __y._M_inner; }
5386 friend constexpr _Iterator
5387 operator+(
const _Iterator& __i, difference_type __n)
5389 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5391 friend constexpr _Iterator
5392 operator+(difference_type __n,
const _Iterator& __i)
5394 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5396 friend constexpr _Iterator
5397 operator-(
const _Iterator& __i, difference_type __n)
5399 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
5401 friend constexpr difference_type
5402 operator-(
const _Iterator& __x,
const _Iterator& __y)
5403 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5404 {
return __x._M_inner - __y._M_inner; }
5407 template<move_constructible _Fp,
input_range... _Vs>
5408 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5409 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5410 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5411 template<bool _Const>
5412 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5414 __zentinel<_Const> _M_inner;
5417 _Sentinel(__zentinel<_Const> __inner)
5421 friend class zip_transform_view;
5424 _Sentinel() =
default;
5427 _Sentinel(_Sentinel<!_Const> __i)
5428 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5432 template<
bool _OtherConst>
5433 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5434 friend constexpr bool
5435 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5436 {
return __x._M_inner == __y._M_inner; }
5438 template<
bool _OtherConst>
5439 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5440 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5441 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5442 {
return __x._M_inner - __y._M_inner; }
5444 template<
bool _OtherConst>
5445 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5446 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5447 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5448 {
return __x._M_inner - __y._M_inner; }
5455 template<
typename _Fp,
typename... _Ts>
5456 concept __can_zip_transform_view
5460 struct _ZipTransform
5462 template<
typename _Fp>
5463 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5464 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5466 operator() [[nodiscard]] (_Fp&&)
const
5468 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5471 template<
typename _Fp,
typename... _Ts>
5472 requires (
sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5474 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5480 inline constexpr _ZipTransform zip_transform;
5483 template<forward_range _Vp,
size_t _Nm>
5485 class adjacent_view : public
view_interface<adjacent_view<_Vp, _Nm>>
5487 _Vp _M_base = _Vp();
5489 template<
bool>
class _Iterator;
5490 template<
bool>
class _Sentinel;
5492 struct __as_sentinel
5496 adjacent_view()
requires default_initializable<_Vp> = default;
5499 adjacent_view(_Vp __base)
5500 : _M_base(std::move(__base))
5506 base() const & requires copy_constructible<_Vp>
5514 begin()
requires (!__detail::__simple_view<_Vp>)
5515 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5519 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5522 end()
requires (!__detail::__simple_view<_Vp>)
5525 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5527 return _Sentinel<false>(ranges::end(_M_base));
5531 end() const requires
range<const _Vp>
5534 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5536 return _Sentinel<true>(ranges::end(_M_base));
5542 using _ST =
decltype(ranges::size(_M_base));
5544 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5546 return static_cast<_ST
>(__sz);
5552 using _ST =
decltype(ranges::size(_M_base));
5554 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5556 return static_cast<_ST
>(__sz);
5560 template<
typename _Vp,
size_t _Nm>
5561 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5562 = enable_borrowed_range<_Vp>;
5567 template<
typename _Tp,
size_t _Nm>
5568 using __repeated_tuple =
typename __make_tuple<array<_Tp, _Nm>>::__type;
5572 template<
typename _Fp,
size_t _Nm>
5575 template<
typename... _Ts>
5576 static invoke_result_t<_Fp, _Ts...>
5577 __tuple_apply(
const tuple<_Ts...>&);
5579 template<
typename _Tp>
5580 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5585 template<forward_range _Vp,
size_t _Nm>
5587 template<bool _Const>
5588 class adjacent_view<_Vp, _Nm>::_Iterator
5590#ifdef _GLIBCXX_CLANG
5593 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5594 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5597 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5599 for (
auto& __i : _M_current)
5602 ranges::advance(__first, 1, __last);
5607 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5610 for (
auto& __it : _M_current)
5613 for (
size_t __i = 0; __i < _Nm; ++__i)
5615 _M_current[_Nm - 1 - __i] = __last;
5616 ranges::advance(__last, -1, __first);
5624 return random_access_iterator_tag{};
5626 return bidirectional_iterator_tag{};
5628 return forward_iterator_tag{};
5631 friend class adjacent_view;
5633#ifndef _GLIBCXX_CLANG
5634 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5635 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5636 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5637 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5638 range_reference_t<_Wp>>>
5639 friend class adjacent_transform_view;
5643 using iterator_category = input_iterator_tag;
5644 using iterator_concept =
decltype(_S_iter_concept());
5645 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5646 using difference_type = range_difference_t<_Base>;
5648 _Iterator() =
default;
5651 _Iterator(_Iterator<!_Const> __i)
5652 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5654 for (
size_t __j = 0; __j < _Nm; ++__j)
5655 _M_current[__j] =
std::move(__i._M_current[__j]);
5661 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5662 return __detail::__tuple_transform(__f, _M_current);
5665 constexpr _Iterator&
5668 for (
auto& __i : _M_current)
5681 constexpr _Iterator&
5684 for (
auto& __i : _M_current)
5697 constexpr _Iterator&
5698 operator+=(difference_type __x)
5701 for (
auto& __i : _M_current)
5706 constexpr _Iterator&
5707 operator-=(difference_type __x)
5710 for (
auto& __i : _M_current)
5716 operator[](difference_type __n)
const
5719 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5720 return __detail::__tuple_transform(__f, _M_current);
5723 friend constexpr bool
5724 operator==(
const _Iterator& __x,
const _Iterator& __y)
5725 {
return __x._M_current.back() == __y._M_current.back(); }
5727 friend constexpr bool
5728 operator<(
const _Iterator& __x,
const _Iterator& __y)
5730 {
return __x._M_current.back() < __y._M_current.back(); }
5732 friend constexpr bool
5733 operator>(
const _Iterator& __x,
const _Iterator& __y)
5735 {
return __y < __x; }
5737 friend constexpr bool
5738 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5740 {
return !(__y < __x); }
5742 friend constexpr bool
5743 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5745 {
return !(__x < __y); }
5747 friend constexpr auto
5748 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5750 && three_way_comparable<iterator_t<_Base>>
5751 {
return __x._M_current.back() <=> __y._M_current.back(); }
5753 friend constexpr _Iterator
5754 operator+(
const _Iterator& __i, difference_type __n)
5762 friend constexpr _Iterator
5763 operator+(difference_type __n,
const _Iterator& __i)
5771 friend constexpr _Iterator
5772 operator-(
const _Iterator& __i, difference_type __n)
5780 friend constexpr difference_type
5781 operator-(
const _Iterator& __x,
const _Iterator& __y)
5782 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5783 {
return __x._M_current.back() - __y._M_current.back(); }
5785 friend constexpr auto
5786 iter_move(
const _Iterator& __i)
5787 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5789 friend constexpr void
5790 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5791 requires indirectly_swappable<iterator_t<_Base>>
5793 for (
size_t __i = 0; __i < _Nm; __i++)
5794 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5798 template<forward_range _Vp,
size_t _Nm>
5800 template<bool _Const>
5801 class adjacent_view<_Vp, _Nm>::_Sentinel
5803 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5805 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5808 _Sentinel(sentinel_t<_Base> __end)
5812 friend class adjacent_view;
5815 _Sentinel() =
default;
5818 _Sentinel(_Sentinel<!_Const> __i)
5819 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5823 template<
bool _OtherConst>
5824 requires sentinel_for<sentinel_t<_Base>,
5825 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5826 friend constexpr bool
5827 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5828 {
return __x._M_current.back() == __y._M_end; }
5830 template<
bool _OtherConst>
5831 requires sized_sentinel_for<sentinel_t<_Base>,
5832 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5833 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5834 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5835 {
return __x._M_current.back() - __y._M_end; }
5837 template<
bool _OtherConst>
5838 requires sized_sentinel_for<sentinel_t<_Base>,
5839 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5840 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5841 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5842 {
return __y._M_end - __x._M_current.back(); }
5849 template<
size_t _Nm,
typename _Range>
5850 concept __can_adjacent_view
5854 template<
size_t _Nm>
5855 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5857 template<viewable_range _Range>
5858 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5860 operator() [[nodiscard]] (_Range&& __r)
const
5862 if constexpr (_Nm == 0)
5863 return views::empty<tuple<>>;
5869 template<
size_t _Nm>
5870 inline constexpr _Adjacent<_Nm> adjacent;
5872 inline constexpr auto pairwise = adjacent<2>;
5875 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5876 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5877 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5878 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5879 range_reference_t<_Vp>>>
5880 class adjacent_transform_view : public
view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5882 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5883 adjacent_view<_Vp, _Nm> _M_inner;
5885 using _InnerView = adjacent_view<_Vp, _Nm>;
5887 template<
bool _Const>
5888 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5890 template<
bool _Const>
5891 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5893 template<
bool>
class _Iterator;
5894 template<
bool>
class _Sentinel;
5897 adjacent_transform_view() =
default;
5900 adjacent_transform_view(_Vp __base, _Fp __fun)
5901 : _M_fun(std::move(__fun)), _M_inner(std::move(
__base))
5908 base() const & requires copy_constructible<_Vp>
5909 {
return _M_inner.base(); }
5917 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5921 requires
range<const _InnerView>
5922 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5923 range_reference_t<const _Vp>>
5924 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5930 return _Iterator<false>(*
this, _M_inner.end());
5932 return _Sentinel<false>(_M_inner.end());
5937 requires
range<const _InnerView>
5938 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5939 range_reference_t<const _Vp>>
5942 return _Iterator<true>(*
this, _M_inner.end());
5944 return _Sentinel<true>(_M_inner.end());
5949 {
return _M_inner.size(); }
5953 {
return _M_inner.size(); }
5956 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5957 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5958 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5959 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5960 range_reference_t<_Vp>>>
5961 template<bool _Const>
5962 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5964 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5965 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5967 return __detail::__func_handle_t<
5968 __detail::__maybe_const_t<_Const, _Fp>,
5969 iterator_t<__detail::__maybe_const_t<(_Ids, _Const), _Vp>>...>();
5972 [[no_unique_address]] _Fun_handle _M_fun;
5973 _InnerIter<_Const> _M_inner;
5976 _Iterator(_Fun_handle __fun, _InnerIter<_Const> __inner)
5977 : _M_fun(__fun), _M_inner(std::move(__inner))
5981 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5982 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
5988 using __detail::__maybe_const_t;
5989 using __detail::__unarize;
5990 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5991 range_reference_t<_Base>>;
5992 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
5995 if constexpr (!is_reference_v<_Res>)
5996 return input_iterator_tag{};
5997 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5998 return random_access_iterator_tag{};
5999 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
6000 return bidirectional_iterator_tag{};
6001 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
6002 return forward_iterator_tag{};
6004 return input_iterator_tag{};
6007 friend class adjacent_transform_view;
6010 using iterator_category =
decltype(_S_iter_cat());
6011 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
6013 = remove_cvref_t<invoke_result_t
6014 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
6015 range_reference_t<_Base>>>;
6016 using difference_type = range_difference_t<_Base>;
6018 _Iterator() =
default;
6021 _Iterator(_Iterator<!_Const> __i)
6022 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
6023 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
6026 constexpr decltype(
auto)
6029 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6030 return _M_fun._M_call_deref(__iters...);
6031 }, _M_inner._M_current);
6034 constexpr _Iterator&
6049 constexpr _Iterator&
6064 constexpr _Iterator&
6071 constexpr _Iterator&
6078 constexpr decltype(
auto)
6081 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6082 return _M_fun._M_call_subscript(__n, __iters...);
6083 }, _M_inner._M_current);
6086 friend constexpr bool
6087 operator==(
const _Iterator& __x,
const _Iterator& __y)
6088 {
return __x._M_inner == __y._M_inner; }
6090 friend constexpr bool
6091 operator<(
const _Iterator& __x,
const _Iterator& __y)
6093 {
return __x._M_inner < __y._M_inner; }
6095 friend constexpr bool
6096 operator>(
const _Iterator& __x,
const _Iterator& __y)
6098 {
return __x._M_inner > __y._M_inner; }
6100 friend constexpr bool
6101 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6103 {
return __x._M_inner <= __y._M_inner; }
6105 friend constexpr bool
6106 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6108 {
return __x._M_inner >= __y._M_inner; }
6110 friend constexpr auto
6111 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6113 three_way_comparable<_InnerIter<_Const>>
6114 {
return __x._M_inner <=> __y._M_inner; }
6116 friend constexpr _Iterator
6117 operator+(
const _Iterator& __i, difference_type __n)
6119 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6121 friend constexpr _Iterator
6122 operator+(difference_type __n,
const _Iterator& __i)
6124 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6126 friend constexpr _Iterator
6127 operator-(
const _Iterator& __i, difference_type __n)
6129 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
6131 friend constexpr difference_type
6132 operator-(
const _Iterator& __x,
const _Iterator& __y)
6133 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
6134 {
return __x._M_inner - __y._M_inner; }
6137 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6138 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6139 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6140 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6141 range_reference_t<_Vp>>>
6142 template<bool _Const>
6143 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6145 _InnerSent<_Const> _M_inner;
6148 _Sentinel(_InnerSent<_Const> __inner)
6152 friend class adjacent_transform_view;
6155 _Sentinel() =
default;
6158 _Sentinel(_Sentinel<!_Const> __i)
6159 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6163 template<
bool _OtherConst>
6164 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6165 friend constexpr bool
6166 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6167 {
return __x._M_inner == __y._M_inner; }
6169 template<
bool _OtherConst>
6170 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6171 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6172 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6173 {
return __x._M_inner - __y._M_inner; }
6175 template<
bool _OtherConst>
6176 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6177 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6178 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
6179 {
return __x._M_inner - __y._M_inner; }
6186 template<
size_t _Nm,
typename _Range,
typename _Fp>
6187 concept __can_adjacent_transform_view
6188 =
requires { adjacent_transform_view<all_t<_Range>,
decay_t<_Fp>, _Nm>
6192 template<
size_t _Nm>
6193 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6195 template<viewable_range _Range,
typename _Fp>
6196 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6198 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
6200 if constexpr (_Nm == 0)
6203 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6207 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6208 static constexpr int _S_arity = 2;
6209 static constexpr bool _S_has_simple_extra_args =
true;
6212 template<
size_t _Nm>
6213 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6215 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6219#ifdef __cpp_lib_ranges_chunk
6222 template<
typename _Tp>
6223 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6225 _Tp __r = __num / __denom;
6226 if (__num % __denom)
6237 range_difference_t<_Vp> _M_n;
6238 range_difference_t<_Vp> _M_remainder = 0;
6239 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6246 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6247 : _M_base(std::move(
__base)), _M_n(__n)
6248 { __glibcxx_assert(__n >= 0); }
6251 base() const & requires copy_constructible<_Vp>
6258 constexpr _OuterIter
6261 _M_current = ranges::begin(_M_base);
6262 _M_remainder = _M_n;
6263 return _OuterIter(*
this);
6266 constexpr default_sentinel_t
6267 end() const noexcept
6271 size()
requires sized_range<_Vp>
6273 return __detail::__to_unsigned_like(__detail::__div_ceil
6274 (ranges::distance(_M_base), _M_n));
6278 size() const requires sized_range<const _Vp>
6280 return __detail::__to_unsigned_like(__detail::__div_ceil
6281 (ranges::distance(_M_base), _M_n));
6285 template<
typename _Range>
6286 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6290 class chunk_view<_Vp>::_OuterIter
6292 chunk_view* _M_parent;
6295 _OuterIter(chunk_view& __parent) noexcept
6302 using iterator_concept = input_iterator_tag;
6303 using difference_type = range_difference_t<_Vp>;
6307 _OuterIter(_OuterIter&&) =
default;
6308 _OuterIter& operator=(_OuterIter&&) =
default;
6310 constexpr value_type
6313 __glibcxx_assert(*
this != default_sentinel);
6314 return value_type(*_M_parent);
6317 constexpr _OuterIter&
6320 __glibcxx_assert(*
this != default_sentinel);
6321 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6322 ranges::end(_M_parent->_M_base));
6323 _M_parent->_M_remainder = _M_parent->_M_n;
6331 friend constexpr bool
6332 operator==(
const _OuterIter& __x, default_sentinel_t)
6334 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6335 && __x._M_parent->_M_remainder != 0;
6338 friend constexpr difference_type
6339 operator-(default_sentinel_t,
const _OuterIter& __x)
6340 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6342 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6344 if (__dist < __x._M_parent->_M_remainder)
6345 return __dist == 0 ? 0 : 1;
6347 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6348 __x._M_parent->_M_n);
6351 friend constexpr difference_type
6352 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6353 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6354 {
return -(__y - __x); }
6359 struct chunk_view<_Vp>::_OuterIter::value_type :
view_interface<value_type>
6362 chunk_view* _M_parent;
6365 value_type(chunk_view& __parent) noexcept
6372 constexpr _InnerIter
6373 begin() const noexcept
6374 {
return _InnerIter(*_M_parent); }
6376 constexpr default_sentinel_t
6377 end() const noexcept
6382 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6384 return __detail::__to_unsigned_like
6385 (ranges::min(_M_parent->_M_remainder,
6386 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6392 class chunk_view<_Vp>::_InnerIter
6394 chunk_view* _M_parent;
6397 _InnerIter(chunk_view& __parent) noexcept
6401 friend _OuterIter::value_type;
6404 using iterator_concept = input_iterator_tag;
6405 using difference_type = range_difference_t<_Vp>;
6406 using value_type = range_value_t<_Vp>;
6408 _InnerIter(_InnerIter&&) =
default;
6409 _InnerIter& operator=(_InnerIter&&) =
default;
6411 constexpr const iterator_t<_Vp>&
6413 {
return *_M_parent->_M_current; }
6415 constexpr range_reference_t<_Vp>
6418 __glibcxx_assert(*
this != default_sentinel);
6419 return **_M_parent->_M_current;
6422 constexpr _InnerIter&
6425 __glibcxx_assert(*
this != default_sentinel);
6426 ++*_M_parent->_M_current;
6427 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6428 _M_parent->_M_remainder = 0;
6430 --_M_parent->_M_remainder;
6438 friend constexpr bool
6439 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6440 {
return __x._M_parent->_M_remainder == 0; }
6442 friend constexpr difference_type
6443 operator-(default_sentinel_t,
const _InnerIter& __x)
6444 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6446 return ranges::min(__x._M_parent->_M_remainder,
6447 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6450 friend constexpr difference_type
6451 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6452 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6453 {
return -(__y - __x); }
6457 friend constexpr range_rvalue_reference_t<_Vp>
6458 iter_move(
const _InnerIter& __i)
6459 noexcept(
noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6460 {
return ranges::iter_move(*__i._M_parent->_M_current); }
6462 friend constexpr void
6463 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
6464 noexcept(
noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6465 *__x._M_parent->_M_current)))
6466 requires indirectly_swappable<iterator_t<_Vp>>
6467 {
return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6475 range_difference_t<_Vp> _M_n;
6476 template<
bool>
class _Iterator;
6480 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6481 : _M_base(std::move(
__base)), _M_n(__n)
6482 { __glibcxx_assert(__n > 0); }
6485 base() const & requires copy_constructible<_Vp>
6493 begin()
requires (!__detail::__simple_view<_Vp>)
6494 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6497 begin() const requires forward_range<const _Vp>
6498 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6501 end()
requires (!__detail::__simple_view<_Vp>)
6503 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6505 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6506 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6508 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6509 return _Iterator<false>(
this, ranges::end(_M_base));
6515 end() const requires forward_range<const _Vp>
6517 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6519 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6520 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6522 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6523 return _Iterator<true>(
this, ranges::end(_M_base));
6529 size()
requires sized_range<_Vp>
6531 return __detail::__to_unsigned_like(__detail::__div_ceil
6532 (ranges::distance(_M_base), _M_n));
6536 size() const requires sized_range<const _Vp>
6538 return __detail::__to_unsigned_like(__detail::__div_ceil
6539 (ranges::distance(_M_base), _M_n));
6543 template<
typename _Vp>
6544 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6549 template<
bool _Const>
6550 class chunk_view<_Vp>::_Iterator
6552 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6553 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6555 iterator_t<_Base> _M_current = iterator_t<_Base>();
6556 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6557 range_difference_t<_Base> _M_n = 0;
6558 range_difference_t<_Base> _M_missing = 0;
6561 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6562 range_difference_t<_Base> __missing = 0)
6563 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6564 _M_n(__parent->_M_n), _M_missing(__missing)
6570 if constexpr (random_access_range<_Base>)
6571 return random_access_iterator_tag{};
6572 else if constexpr (bidirectional_range<_Base>)
6573 return bidirectional_iterator_tag{};
6575 return forward_iterator_tag{};
6581 using iterator_category = input_iterator_tag;
6582 using iterator_concept =
decltype(_S_iter_cat());
6583 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6584 using difference_type = range_difference_t<_Base>;
6586 _Iterator() =
default;
6588 constexpr _Iterator(_Iterator<!_Const> __i)
6590 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6591 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6593 _M_n(__i._M_n), _M_missing(__i._M_missing)
6596 constexpr iterator_t<_Base>
6598 {
return _M_current; }
6600 constexpr value_type
6603 __glibcxx_assert(_M_current != _M_end);
6604 return views::take(subrange(_M_current, _M_end), _M_n);
6607 constexpr _Iterator&
6610 __glibcxx_assert(_M_current != _M_end);
6611 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6623 constexpr _Iterator&
6624 operator--()
requires bidirectional_range<_Base>
6626 ranges::advance(_M_current, _M_missing - _M_n);
6632 operator--(
int)
requires bidirectional_range<_Base>
6639 constexpr _Iterator&
6640 operator+=(difference_type __x)
6641 requires random_access_range<_Base>
6645 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6646 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6650 ranges::advance(_M_current, _M_n * __x + _M_missing);
6656 constexpr _Iterator&
6657 operator-=(difference_type __x)
6658 requires random_access_range<_Base>
6659 {
return *
this += -__x; }
6661 constexpr value_type
6662 operator[](difference_type __n)
const
6663 requires random_access_range<_Base>
6664 {
return *(*
this + __n); }
6666 friend constexpr bool
6667 operator==(
const _Iterator& __x,
const _Iterator& __y)
6668 {
return __x._M_current == __y._M_current; }
6670 friend constexpr bool
6671 operator==(
const _Iterator& __x, default_sentinel_t)
6672 {
return __x._M_current == __x._M_end; }
6674 friend constexpr bool
6675 operator<(
const _Iterator& __x,
const _Iterator& __y)
6676 requires random_access_range<_Base>
6677 {
return __x._M_current > __y._M_current; }
6679 friend constexpr bool
6680 operator>(
const _Iterator& __x,
const _Iterator& __y)
6681 requires random_access_range<_Base>
6682 {
return __y < __x; }
6684 friend constexpr bool
6685 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6686 requires random_access_range<_Base>
6687 {
return !(__y < __x); }
6689 friend constexpr bool
6690 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6691 requires random_access_range<_Base>
6692 {
return !(__x < __y); }
6694 friend constexpr auto
6695 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6696 requires random_access_range<_Base>
6697 && three_way_comparable<iterator_t<_Base>>
6698 {
return __x._M_current <=> __y._M_current; }
6700 friend constexpr _Iterator
6701 operator+(
const _Iterator& __i, difference_type __n)
6702 requires random_access_range<_Base>
6709 friend constexpr _Iterator
6710 operator+(difference_type __n,
const _Iterator& __i)
6711 requires random_access_range<_Base>
6718 friend constexpr _Iterator
6719 operator-(
const _Iterator& __i, difference_type __n)
6720 requires random_access_range<_Base>
6727 friend constexpr difference_type
6728 operator-(
const _Iterator& __x,
const _Iterator& __y)
6729 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6731 return (__x._M_current - __y._M_current
6732 + __x._M_missing - __y._M_missing) / __x._M_n;
6735 friend constexpr difference_type
6736 operator-(default_sentinel_t,
const _Iterator& __x)
6737 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6738 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6740 friend constexpr difference_type
6741 operator-(
const _Iterator& __x, default_sentinel_t __y)
6742 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6743 {
return -(__y - __x); }
6750 template<
typename _Range,
typename _Dp>
6751 concept __can_chunk_view
6755 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6757 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6758 requires __detail::__can_chunk_view<_Range, _Dp>
6760 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6763 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6764 static constexpr int _S_arity = 2;
6765 static constexpr bool _S_has_simple_extra_args =
true;
6768 inline constexpr _Chunk chunk;
6772#ifdef __cpp_lib_ranges_slide
6775 template<
typename _Vp>
6776 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6778 template<
typename _Vp>
6779 concept __slide_caches_last
6780 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6782 template<
typename _Vp>
6783 concept __slide_caches_first
6784 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6787 template<forward_range _Vp>
6792 range_difference_t<_Vp> _M_n;
6793 [[no_unique_address]]
6794 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6795 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6796 [[no_unique_address]]
6797 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6798 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6800 template<
bool>
class _Iterator;
6805 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6806 : _M_base(std::move(
__base)), _M_n(__n)
6807 { __glibcxx_assert(__n > 0); }
6812 base() const & requires copy_constructible<_Vp>
6820 begin()
requires (!(__detail::__simple_view<_Vp>
6821 && __detail::__slide_caches_nothing<const _Vp>))
6823 if constexpr (__detail::__slide_caches_first<_Vp>)
6825 iterator_t<_Vp> __it;
6826 if (_M_cached_begin._M_has_value())
6827 __it = _M_cached_begin._M_get(_M_base);
6830 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6831 _M_cached_begin._M_set(_M_base, __it);
6833 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6836 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6840 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6841 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6844 end()
requires (!(__detail::__simple_view<_Vp>
6845 && __detail::__slide_caches_nothing<const _Vp>))
6847 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6848 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6850 else if constexpr (__detail::__slide_caches_last<_Vp>)
6852 iterator_t<_Vp> __it;
6853 if (_M_cached_end._M_has_value())
6854 __it = _M_cached_end._M_get(_M_base);
6857 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6858 _M_cached_end._M_set(_M_base, __it);
6860 return _Iterator<false>(
std::move(__it), _M_n);
6862 else if constexpr (common_range<_Vp>)
6863 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6865 return _Sentinel(ranges::end(_M_base));
6869 end() const requires __detail::__slide_caches_nothing<const _Vp>
6870 {
return begin() + range_difference_t<const _Vp>(size()); }
6873 size()
requires sized_range<_Vp>
6875 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6878 return __detail::__to_unsigned_like(__sz);
6882 size() const requires sized_range<const _Vp>
6884 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6887 return __detail::__to_unsigned_like(__sz);
6891 template<
typename _Range>
6892 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6894 template<
typename _Vp>
6895 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6896 = enable_borrowed_range<_Vp>;
6898 template<forward_range _Vp>
6900 template<
bool _Const>
6901 class slide_view<_Vp>::_Iterator
6903 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6904 static constexpr bool _S_last_elt_present
6905 = __detail::__slide_caches_first<_Base>;
6907 iterator_t<_Base> _M_current = iterator_t<_Base>();
6908 [[no_unique_address]]
6909 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6910 _M_last_elt =
decltype(_M_last_elt)();
6911 range_difference_t<_Base> _M_n = 0;
6914 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6915 requires (!_S_last_elt_present)
6916 : _M_current(__current), _M_n(__n)
6920 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6921 range_difference_t<_Base> __n)
6922 requires _S_last_elt_present
6923 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6929 if constexpr (random_access_range<_Base>)
6930 return random_access_iterator_tag{};
6931 else if constexpr (bidirectional_range<_Base>)
6932 return bidirectional_iterator_tag{};
6934 return forward_iterator_tag{};
6938 friend slide_view::_Sentinel;
6941 using iterator_category = input_iterator_tag;
6942 using iterator_concept =
decltype(_S_iter_concept());
6943 using value_type =
decltype(views::counted(_M_current, _M_n));
6944 using difference_type = range_difference_t<_Base>;
6946 _Iterator() =
default;
6949 _Iterator(_Iterator<!_Const> __i)
6950 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6951 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
6956 {
return views::counted(_M_current, _M_n); }
6958 constexpr _Iterator&
6962 if constexpr (_S_last_elt_present)
6975 constexpr _Iterator&
6976 operator--()
requires bidirectional_range<_Base>
6979 if constexpr (_S_last_elt_present)
6985 operator--(
int)
requires bidirectional_range<_Base>
6992 constexpr _Iterator&
6993 operator+=(difference_type __x)
6994 requires random_access_range<_Base>
6997 if constexpr (_S_last_elt_present)
7002 constexpr _Iterator&
7003 operator-=(difference_type __x)
7004 requires random_access_range<_Base>
7007 if constexpr (_S_last_elt_present)
7013 operator[](difference_type __n)
const
7014 requires random_access_range<_Base>
7015 {
return views::counted(_M_current + __n, _M_n); }
7017 friend constexpr bool
7018 operator==(
const _Iterator& __x,
const _Iterator& __y)
7020 if constexpr (_S_last_elt_present)
7021 return __x._M_last_elt == __y._M_last_elt;
7023 return __x._M_current == __y._M_current;
7026 friend constexpr bool
7027 operator<(
const _Iterator& __x,
const _Iterator& __y)
7028 requires random_access_range<_Base>
7029 {
return __x._M_current < __y._M_current; }
7031 friend constexpr bool
7032 operator>(
const _Iterator& __x,
const _Iterator& __y)
7033 requires random_access_range<_Base>
7034 {
return __y < __x; }
7036 friend constexpr bool
7037 operator<=(
const _Iterator& __x,
const _Iterator& __y)
7038 requires random_access_range<_Base>
7039 {
return !(__y < __x); }
7041 friend constexpr bool
7042 operator>=(
const _Iterator& __x,
const _Iterator& __y)
7043 requires random_access_range<_Base>
7044 {
return !(__x < __y); }
7046 friend constexpr auto
7047 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7048 requires random_access_range<_Base>
7049 && three_way_comparable<iterator_t<_Base>>
7050 {
return __x._M_current <=> __y._M_current; }
7052 friend constexpr _Iterator
7053 operator+(
const _Iterator& __i, difference_type __n)
7054 requires random_access_range<_Base>
7061 friend constexpr _Iterator
7062 operator+(difference_type __n,
const _Iterator& __i)
7063 requires random_access_range<_Base>
7070 friend constexpr _Iterator
7071 operator-(
const _Iterator& __i, difference_type __n)
7072 requires random_access_range<_Base>
7079 friend constexpr difference_type
7080 operator-(
const _Iterator& __x,
const _Iterator& __y)
7081 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7083 if constexpr (_S_last_elt_present)
7084 return __x._M_last_elt - __y._M_last_elt;
7086 return __x._M_current - __y._M_current;
7090 template<forward_range _Vp>
7092 class slide_view<_Vp>::_Sentinel
7094 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
7097 _Sentinel(sentinel_t<_Vp> __end)
7104 _Sentinel() =
default;
7106 friend constexpr bool
7107 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
7108 {
return __x._M_last_elt == __y._M_end; }
7110 friend constexpr range_difference_t<_Vp>
7111 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
7112 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7113 {
return __x._M_last_elt - __y._M_end; }
7115 friend constexpr range_difference_t<_Vp>
7116 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
7117 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7118 {
return __y._M_end -__x._M_last_elt; }
7125 template<
typename _Range,
typename _Dp>
7126 concept __can_slide_view
7130 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
7132 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
7133 requires __detail::__can_slide_view<_Range, _Dp>
7135 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
7138 using __adaptor::_RangeAdaptor<_Slide>::operator();
7139 static constexpr int _S_arity = 2;
7140 static constexpr bool _S_has_simple_extra_args =
true;
7143 inline constexpr _Slide slide;
7147#ifdef __cpp_lib_ranges_chunk_by
7149 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7150 requires view<_Vp> && is_object_v<_Pred>
7151 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
7153 _Vp _M_base = _Vp();
7154 __detail::__box<_Pred> _M_pred;
7155 __detail::_CachedPosition<_Vp> _M_cached_begin;
7157 constexpr iterator_t<_Vp>
7158 _M_find_next(iterator_t<_Vp> __current)
7160 __glibcxx_assert(_M_pred.has_value());
7161 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7164 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7165 return ranges::next(__it, 1, ranges::end(_M_base));
7168 constexpr iterator_t<_Vp>
7169 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
7171 __glibcxx_assert(_M_pred.has_value());
7172 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7177 __glibcxx_assert(__rbegin != __rend);
7178 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7179 return ranges::prev(__it, 1, ranges::begin(_M_base));
7185 chunk_by_view()
requires (default_initializable<_Vp>
7186 && default_initializable<_Pred>)
7190 chunk_by_view(_Vp __base, _Pred __pred)
7191 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
7195 base() const & requires copy_constructible<_Vp>
7202 constexpr const _Pred&
7204 {
return *_M_pred; }
7209 __glibcxx_assert(_M_pred.has_value());
7210 iterator_t<_Vp> __it;
7211 if (_M_cached_begin._M_has_value())
7212 __it = _M_cached_begin._M_get(_M_base);
7215 __it = _M_find_next(ranges::begin(_M_base));
7216 _M_cached_begin._M_set(_M_base, __it);
7218 return _Iterator(*
this, ranges::begin(_M_base), __it);
7224 if constexpr (common_range<_Vp>)
7225 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
7231 template<
typename _Range,
typename _Pred>
7232 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7235 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7236 requires view<_Vp> && is_object_v<_Pred>
7237 class chunk_by_view<_Vp, _Pred>::_Iterator
7239 chunk_by_view* _M_parent =
nullptr;
7240 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7241 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7244 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7245 : _M_parent(std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7251 if constexpr (bidirectional_range<_Vp>)
7252 return bidirectional_iterator_tag{};
7254 return forward_iterator_tag{};
7257 friend chunk_by_view;
7260 using value_type = subrange<iterator_t<_Vp>>;
7261 using difference_type = range_difference_t<_Vp>;
7262 using iterator_category = input_iterator_tag;
7263 using iterator_concept =
decltype(_S_iter_concept());
7265 _Iterator() =
default;
7267 constexpr value_type
7270 __glibcxx_assert(_M_current != _M_next);
7271 return ranges::subrange(_M_current, _M_next);
7274 constexpr _Iterator&
7277 __glibcxx_assert(_M_current != _M_next);
7278 _M_current = _M_next;
7279 _M_next = _M_parent->_M_find_next(_M_current);
7291 constexpr _Iterator&
7292 operator--()
requires bidirectional_range<_Vp>
7294 _M_next = _M_current;
7295 _M_current = _M_parent->_M_find_prev(_M_next);
7300 operator--(
int)
requires bidirectional_range<_Vp>
7307 friend constexpr bool
7308 operator==(
const _Iterator& __x,
const _Iterator& __y)
7309 {
return __x._M_current == __y._M_current; }
7311 friend constexpr bool
7312 operator==(
const _Iterator& __x, default_sentinel_t)
7313 {
return __x._M_current == __x._M_next; }
7320 template<
typename _Range,
typename _Pred>
7321 concept __can_chunk_by_view
7325 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7327 template<viewable_range _Range,
typename _Pred>
7328 requires __detail::__can_chunk_by_view<_Range, _Pred>
7330 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7333 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7334 static constexpr int _S_arity = 2;
7335 static constexpr bool _S_has_simple_extra_args =
true;
7338 inline constexpr _ChunkBy chunk_by;
7342#ifdef __cpp_lib_ranges_join_with
7345 template<
typename _Range,
typename _Pattern>
7346 concept __compatible_joinable_ranges
7347 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7348 && common_reference_with<range_reference_t<_Range>,
7349 range_reference_t<_Pattern>>
7350 && common_reference_with<range_rvalue_reference_t<_Range>,
7351 range_rvalue_reference_t<_Pattern>>;
7353 template<
typename _Range>
7354 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7357 template<input_range _Vp, forward_range _Pattern>
7360 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7361 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7363 using _InnerRange = range_reference_t<_Vp>;
7365 _Vp _M_base = _Vp();
7366 [[no_unique_address]]
7367 __detail::__maybe_present_t<!forward_range<_Vp>,
7368 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7369 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7370 _Pattern _M_pattern = _Pattern();
7372 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7373 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7374 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7376 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7377 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7378 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7380 template<
bool _Const>
7381 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7383 template<
bool _Const>
7387 template<
bool _Const>
7388 requires _S_ref_is_glvalue<_Const>
7389 && forward_range<_Base<_Const>>
7390 && forward_range<_InnerBase<_Const>>
7391 struct __iter_cat<_Const>
7397 using _OuterIter = join_with_view::_OuterIter<_Const>;
7398 using _InnerIter = join_with_view::_InnerIter<_Const>;
7399 using _PatternIter = join_with_view::_PatternIter<_Const>;
7400 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7401 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7402 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7405 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7406 iter_reference_t<_PatternIter>>>)
7407 return input_iterator_tag{};
7408 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7409 && derived_from<_InnerCat, bidirectional_iterator_tag>
7410 && derived_from<_PatternCat, bidirectional_iterator_tag>
7411 && common_range<_InnerBase<_Const>>
7412 && common_range<_PatternBase<_Const>>)
7413 return bidirectional_iterator_tag{};
7414 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7415 && derived_from<_InnerCat, forward_iterator_tag>
7416 && derived_from<_PatternCat, forward_iterator_tag>)
7417 return forward_iterator_tag{};
7419 return input_iterator_tag{};
7422 using iterator_category =
decltype(_S_iter_cat());
7425 template<
bool>
class _Iterator;
7426 template<
bool>
class _Sentinel;
7429 join_with_view()
requires (default_initializable<_Vp>
7430 && default_initializable<_Pattern>)
7434 join_with_view(_Vp __base, _Pattern __pattern)
7435 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
7438 template<input_range _Range>
7439 requires constructible_from<_Vp, views::all_t<_Range>>
7440 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7442 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7443 : _M_base(views::all(std::
forward<_Range>(__r))),
7444 _M_pattern(views::single(std::move(__e)))
7448 base() const& requires copy_constructible<_Vp>
7458 if constexpr (forward_range<_Vp>)
7460 constexpr bool __use_const = is_reference_v<_InnerRange>
7461 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7462 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7466 _M_outer_it = ranges::begin(_M_base);
7467 return _Iterator<false>{*
this};
7473 requires forward_range<const _Vp>
7474 && forward_range<const _Pattern>
7475 && is_reference_v<range_reference_t<const _Vp>>
7476 && input_range<range_reference_t<const _Vp>>
7477 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7482 constexpr bool __use_const
7483 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7484 if constexpr (is_reference_v<_InnerRange>
7485 && forward_range<_Vp> && common_range<_Vp>
7486 && forward_range<_InnerRange> && common_range<_InnerRange>)
7487 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7489 return _Sentinel<__use_const>{*
this};
7494 requires forward_range<const _Vp>
7495 && forward_range<const _Pattern>
7496 && is_reference_v<range_reference_t<const _Vp>>
7497 && input_range<range_reference_t<const _Vp>>
7499 using _InnerConstRange = range_reference_t<const _Vp>;
7500 if constexpr (forward_range<_InnerConstRange>
7501 && common_range<const _Vp>
7502 && common_range<_InnerConstRange>)
7503 return _Iterator<true>{*
this, ranges::end(_M_base)};
7505 return _Sentinel<true>{*
this};
7509 template<
typename _Range,
typename _Pattern>
7510 join_with_view(_Range&&, _Pattern&&)
7511 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7513 template<input_range _Range>
7514 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7515 -> join_with_view<views::all_t<_Range>,
7518 template<input_range _Vp, forward_range _Pattern>
7521 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7522 template<
bool _Const>
7523 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7525 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7526 using _Base = join_with_view::_Base<_Const>;
7527 using _InnerBase = join_with_view::_InnerBase<_Const>;
7528 using _PatternBase = join_with_view::_PatternBase<_Const>;
7530 using _OuterIter = join_with_view::_OuterIter<_Const>;
7531 using _InnerIter = join_with_view::_InnerIter<_Const>;
7532 using _PatternIter = join_with_view::_PatternIter<_Const>;
7534 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7536 _Parent* _M_parent =
nullptr;
7537 [[no_unique_address]]
7538 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7539 =
decltype(_M_outer_it)();
7540 variant<_PatternIter, _InnerIter> _M_inner_it;
7542 constexpr _OuterIter&
7545 if constexpr (forward_range<_Base>)
7548 return *_M_parent->_M_outer_it;
7551 constexpr const _OuterIter&
7552 _M_get_outer()
const
7554 if constexpr (forward_range<_Base>)
7557 return *_M_parent->_M_outer_it;
7561 _Iterator(_Parent& __parent, _OuterIter __outer)
7562 requires forward_range<_Base>
7565 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7567 auto&& __inner = _M_update_inner();
7568 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7574 _Iterator(_Parent& __parent)
7575 requires (!forward_range<_Base>)
7578 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7580 auto&& __inner = _M_update_inner();
7581 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7589 _OuterIter& __outer = _M_get_outer();
7590 if constexpr (_S_ref_is_glvalue)
7591 return __detail::__as_lvalue(*__outer);
7593 return _M_parent->_M_inner._M_emplace_deref(__outer);
7599 if constexpr (_S_ref_is_glvalue)
7600 return __detail::__as_lvalue(*_M_get_outer());
7602 return *_M_parent->_M_inner;
7610 if (_M_inner_it.index() == 0)
7612 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7615 auto&& __inner = _M_update_inner();
7616 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7620 auto&& __inner = _M_get_inner();
7621 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7624 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7626 if constexpr (_S_ref_is_glvalue)
7627 _M_inner_it.template emplace<0>();
7631 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7639 if constexpr (_S_ref_is_glvalue
7640 && bidirectional_range<_Base>
7641 && __detail::__bidirectional_common<_InnerBase>
7642 && __detail::__bidirectional_common<_PatternBase>)
7643 return bidirectional_iterator_tag{};
7644 else if constexpr (_S_ref_is_glvalue
7645 && forward_range<_Base>
7646 && forward_range<_InnerBase>)
7647 return forward_iterator_tag{};
7649 return input_iterator_tag{};
7652 friend join_with_view;
7655 using iterator_concept =
decltype(_S_iter_concept());
7657 using value_type = common_type_t<iter_value_t<_InnerIter>,
7658 iter_value_t<_PatternIter>>;
7659 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7660 iter_difference_t<_InnerIter>,
7661 iter_difference_t<_PatternIter>>;
7663 _Iterator() =
default;
7666 _Iterator(_Iterator<!_Const> __i)
7668 && convertible_to<iterator_t<_Vp>, _OuterIter>
7669 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7670 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7671 : _M_parent(__i._M_parent),
7674 if (__i._M_inner_it.index() == 0)
7675 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7677 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7680 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7681 iter_reference_t<_PatternIter>>
7684 if (_M_inner_it.index() == 0)
7685 return *std::get<0>(_M_inner_it);
7687 return *std::get<1>(_M_inner_it);
7690 constexpr _Iterator&
7693 if (_M_inner_it.index() == 0)
7694 ++std::get<0>(_M_inner_it);
7696 ++std::get<1>(_M_inner_it);
7707 requires _S_ref_is_glvalue
7708 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7710 _Iterator __tmp = *
this;
7715 constexpr _Iterator&
7717 requires _S_ref_is_glvalue
7718 && bidirectional_range<_Base>
7719 && __detail::__bidirectional_common<_InnerBase>
7720 && __detail::__bidirectional_common<_PatternBase>
7722 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7724 auto&& __inner = *--_M_outer_it;
7725 _M_inner_it.template emplace<1>(ranges::end(__inner));
7730 if (_M_inner_it.index() == 0)
7732 auto& __it = std::get<0>(_M_inner_it);
7733 if (__it == ranges::begin(_M_parent->_M_pattern))
7735 auto&& __inner = *--_M_outer_it;
7736 _M_inner_it.template emplace<1>(ranges::end(__inner));
7743 auto& __it = std::get<1>(_M_inner_it);
7744 auto&& __inner = *_M_outer_it;
7745 if (__it == ranges::begin(__inner))
7746 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7752 if (_M_inner_it.index() == 0)
7753 --std::get<0>(_M_inner_it);
7755 --std::get<1>(_M_inner_it);
7761 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7762 && __detail::__bidirectional_common<_InnerBase>
7763 && __detail::__bidirectional_common<_PatternBase>
7765 _Iterator __tmp = *
this;
7770 friend constexpr bool
7771 operator==(
const _Iterator& __x,
const _Iterator& __y)
7772 requires _S_ref_is_glvalue
7773 && forward_range<_Base> && equality_comparable<_InnerIter>
7774 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7776 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7777 iter_rvalue_reference_t<_PatternIter>>
7778 iter_move(
const _Iterator& __x)
7780 if (__x._M_inner_it.index() == 0)
7781 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7783 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7786 friend constexpr void
7787 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7788 requires indirectly_swappable<_InnerIter, _PatternIter>
7790 if (__x._M_inner_it.index() == 0)
7792 if (__y._M_inner_it.index() == 0)
7793 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7795 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7799 if (__y._M_inner_it.index() == 0)
7800 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7802 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7807 template<input_range _Vp, forward_range _Pattern>
7810 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7811 template<
bool _Const>
7812 class join_with_view<_Vp, _Pattern>::_Sentinel
7814 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7815 using _Base = join_with_view::_Base<_Const>;
7817 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7820 _Sentinel(_Parent& __parent)
7821 : _M_end(ranges::end(__parent._M_base))
7824 friend join_with_view;
7827 _Sentinel() =
default;
7830 _Sentinel(_Sentinel<!_Const> __s)
7831 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7835 template<
bool _OtherConst>
7836 requires sentinel_for<sentinel_t<_Base>,
7837 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7838 friend constexpr bool
7839 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7840 {
return __x._M_get_outer() == __y._M_end; }
7847 template<
typename _Range,
typename _Pattern>
7848 concept __can_join_with_view
7852 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7854 template<viewable_range _Range,
typename _Pattern>
7855 requires __detail::__can_join_with_view<_Range, _Pattern>
7857 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7862 using _RangeAdaptor<_JoinWith>::operator();
7863 static constexpr int _S_arity = 2;
7864 template<
typename _Pattern>
7865 static constexpr bool _S_has_simple_extra_args
7866 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7869 inline constexpr _JoinWith join_with;
7873#ifdef __cpp_lib_ranges_repeat
7874 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7875 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7876 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7877 class repeat_view : public
view_interface<repeat_view<_Tp, _Bound>>
7879 [[no_unique_address]] __detail::__box<_Tp> _M_value;
7880 [[no_unique_address]] _Bound _M_bound = _Bound();
7884 template<
typename _Range>
7885 friend constexpr auto
7886 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7888 template<
typename _Range>
7889 friend constexpr auto
7890 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7893 repeat_view()
requires default_initializable<_Tp> = default;
7896 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7897 requires copy_constructible<_Tp>
7898 : _M_value(__value), _M_bound(__bound)
7900 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7901 __glibcxx_assert(__bound >= 0);
7905 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7906 : _M_value(std::move(__value)), _M_bound(__bound)
7909 template<
typename... _Args,
typename... _BoundArgs>
7910 requires constructible_from<_Tp, _Args...>
7911 && constructible_from<_Bound, _BoundArgs...>
7913 repeat_view(piecewise_construct_t,
7914 tuple<_Args...> __args,
7915 tuple<_BoundArgs...> __bound_args = tuple<>{})
7916 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7917 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7925 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7928 constexpr unreachable_sentinel_t
7929 end() const noexcept
7930 {
return unreachable_sentinel; }
7933 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7934 {
return __detail::__to_unsigned_like(_M_bound); }
7939 template<
typename _Tp,
typename _Bound = unreachable_sentinel_t>
7940 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7942 template<move_constructible _Tp, semiregular _Bound>
7943 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7944 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7945 class repeat_view<_Tp, _Bound>::_Iterator
7948 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7950 const _Tp* _M_value =
nullptr;
7951 __index_type _M_current = __index_type();
7954 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
7955 : _M_value(__value), _M_current(__bound)
7957 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7958 __glibcxx_assert(__bound >= 0);
7964 using iterator_concept = random_access_iterator_tag;
7965 using iterator_category = random_access_iterator_tag;
7966 using value_type = _Tp;
7967 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7969 __detail::__iota_diff_t<__index_type>>;
7971 _Iterator() =
default;
7973 constexpr const _Tp&
7975 {
return *_M_value; }
7977 constexpr _Iterator&
7992 constexpr _Iterator&
7995 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7996 __glibcxx_assert(_M_current > 0);
8009 constexpr _Iterator&
8010 operator+=(difference_type __n)
8012 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8013 __glibcxx_assert(_M_current + __n >= 0);
8018 constexpr _Iterator&
8019 operator-=(difference_type __n)
8021 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8022 __glibcxx_assert(_M_current - __n >= 0);
8027 constexpr const _Tp&
8028 operator[](difference_type __n)
const noexcept
8029 {
return *(*
this + __n); }
8031 friend constexpr bool
8032 operator==(
const _Iterator& __x,
const _Iterator& __y)
8033 {
return __x._M_current == __y._M_current; }
8035 friend constexpr auto
8036 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8037 {
return __x._M_current <=> __y._M_current; }
8039 friend constexpr _Iterator
8040 operator+(_Iterator __i, difference_type __n)
8046 friend constexpr _Iterator
8047 operator+(difference_type __n, _Iterator __i)
8048 {
return __i + __n; }
8050 friend constexpr _Iterator
8051 operator-(_Iterator __i, difference_type __n)
8057 friend constexpr difference_type
8058 operator-(
const _Iterator& __x,
const _Iterator& __y)
8060 return (
static_cast<difference_type
>(__x._M_current)
8061 -
static_cast<difference_type
>(__y._M_current));
8069 template<
typename _Tp,
typename _Bound>
8070 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
8072 template<
typename _Tp>
8073 concept __can_repeat_view
8076 template<
typename _Tp,
typename _Bound>
8077 concept __can_bounded_repeat_view
8083 template<
typename _Tp>
8084 requires __detail::__can_repeat_view<_Tp>
8086 operator() [[nodiscard]] (_Tp&& __value)
const
8093 template<
typename _Tp,
typename _Bound>
8094 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
8096 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
8100 inline constexpr _Repeat repeat;
8104 template<
typename _Range>
8106 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8108 using _Tp = remove_cvref_t<_Range>;
8109 static_assert(__is_repeat_view<_Tp>);
8110 if constexpr (sized_range<_Tp>)
8112 std::min(ranges::distance(__r), __n));
8117 template<
typename _Range>
8119 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8121 using _Tp = remove_cvref_t<_Range>;
8122 static_assert(__is_repeat_view<_Tp>);
8123 if constexpr (sized_range<_Tp>)
8125 auto __sz = ranges::distance(__r);
8136#ifdef __cpp_lib_ranges_stride
8137 template<input_range _Vp>
8142 range_difference_t<_Vp> _M_stride;
8144 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8146 template<
bool _Const>
8150 template<
bool _Const>
8151 requires forward_range<_Base<_Const>>
8152 struct __iter_cat<_Const>
8158 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8159 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8160 return random_access_iterator_tag{};
8165 using iterator_category =
decltype(_S_iter_cat());
8168 template<
bool>
class _Iterator;
8172 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8173 : _M_base(std::move(
__base)), _M_stride(__stride)
8174 { __glibcxx_assert(__stride > 0); }
8177 base() const& requires copy_constructible<_Vp>
8184 constexpr range_difference_t<_Vp>
8185 stride() const noexcept
8186 {
return _M_stride; }
8189 begin()
requires (!__detail::__simple_view<_Vp>)
8190 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
8193 begin() const requires range<const _Vp>
8194 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
8197 end()
requires (!__detail::__simple_view<_Vp>)
8199 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8201 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8202 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
8204 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8205 return _Iterator<false>(
this, ranges::end(_M_base));
8211 end() const requires range<const _Vp>
8213 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8214 && forward_range<const _Vp>)
8216 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8217 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
8219 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8220 return _Iterator<true>(
this, ranges::end(_M_base));
8226 size()
requires sized_range<_Vp>
8228 return __detail::__to_unsigned_like
8229 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8233 size() const requires sized_range<const _Vp>
8235 return __detail::__to_unsigned_like
8236 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8240 template<
typename _Range>
8241 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8243 template<
typename _Vp>
8244 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8245 = enable_borrowed_range<_Vp>;
8247 template<input_range _Vp>
8249 template<
bool _Const>
8250 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8252 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8253 using _Base = stride_view::_Base<_Const>;
8255 iterator_t<_Base> _M_current = iterator_t<_Base>();
8256 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8257 range_difference_t<_Base> _M_stride = 0;
8258 range_difference_t<_Base> _M_missing = 0;
8261 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8262 range_difference_t<_Base> __missing = 0)
8263 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8264 _M_stride(__parent->_M_stride), _M_missing(__missing)
8270 if constexpr (random_access_range<_Base>)
8271 return random_access_iterator_tag{};
8272 else if constexpr (bidirectional_range<_Base>)
8273 return bidirectional_iterator_tag{};
8274 else if constexpr (forward_range<_Base>)
8275 return forward_iterator_tag{};
8277 return input_iterator_tag{};
8283 using difference_type = range_difference_t<_Base>;
8284 using value_type = range_value_t<_Base>;
8285 using iterator_concept =
decltype(_S_iter_concept());
8288 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8291 _Iterator(_Iterator<!_Const> __other)
8293 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8294 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8295 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8296 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8299 constexpr iterator_t<_Base>
8303 constexpr const iterator_t<_Base>&
8304 base() const & noexcept
8305 {
return _M_current; }
8307 constexpr decltype(
auto)
8309 {
return *_M_current; }
8311 constexpr _Iterator&
8314 __glibcxx_assert(_M_current != _M_end);
8315 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8324 operator++(
int)
requires forward_range<_Base>
8331 constexpr _Iterator&
8332 operator--()
requires bidirectional_range<_Base>
8334 ranges::advance(_M_current, _M_missing - _M_stride);
8340 operator--(
int)
requires bidirectional_range<_Base>
8347 constexpr _Iterator&
8348 operator+=(difference_type __n)
requires random_access_range<_Base>
8352 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8353 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8357 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8363 constexpr _Iterator&
8364 operator-=(difference_type __n)
requires random_access_range<_Base>
8365 {
return *
this += -__n; }
8367 constexpr decltype(
auto)
operator[](difference_type __n)
const
8368 requires random_access_range<_Base>
8369 {
return *(*
this + __n); }
8371 friend constexpr bool
8372 operator==(
const _Iterator& __x, default_sentinel_t)
8373 {
return __x._M_current == __x._M_end; }
8375 friend constexpr bool
8376 operator==(
const _Iterator& __x,
const _Iterator& __y)
8377 requires equality_comparable<iterator_t<_Base>>
8378 {
return __x._M_current == __y._M_current; }
8380 friend constexpr bool
8381 operator<(
const _Iterator& __x,
const _Iterator& __y)
8382 requires random_access_range<_Base>
8383 {
return __x._M_current < __y._M_current; }
8385 friend constexpr bool
8386 operator>(
const _Iterator& __x,
const _Iterator& __y)
8387 requires random_access_range<_Base>
8388 {
return __y._M_current < __x._M_current; }
8390 friend constexpr bool
8391 operator<=(
const _Iterator& __x,
const _Iterator& __y)
8392 requires random_access_range<_Base>
8393 {
return !(__y._M_current < __x._M_current); }
8395 friend constexpr bool
8396 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8397 requires random_access_range<_Base>
8398 {
return !(__x._M_current < __y._M_current); }
8400 friend constexpr auto
8401 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8402 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8403 {
return __x._M_current <=> __y._M_current; }
8405 friend constexpr _Iterator
8406 operator+(
const _Iterator& __i, difference_type __n)
8407 requires random_access_range<_Base>
8414 friend constexpr _Iterator
8415 operator+(difference_type __n,
const _Iterator& __i)
8416 requires random_access_range<_Base>
8417 {
return __i + __n; }
8419 friend constexpr _Iterator
8420 operator-(
const _Iterator& __i, difference_type __n)
8421 requires random_access_range<_Base>
8428 friend constexpr difference_type
8429 operator-(
const _Iterator& __x,
const _Iterator& __y)
8430 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8432 auto __n = __x._M_current - __y._M_current;
8433 if constexpr (forward_range<_Base>)
8434 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8436 return -__detail::__div_ceil(-__n, __x._M_stride);
8438 return __detail::__div_ceil(__n, __x._M_stride);
8441 friend constexpr difference_type
8442 operator-(default_sentinel_t,
const _Iterator& __x)
8443 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8444 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8446 friend constexpr difference_type
8447 operator-(
const _Iterator& __x, default_sentinel_t __y)
8448 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8449 {
return -(__y - __x); }
8451 friend constexpr range_rvalue_reference_t<_Base>
8452 iter_move(
const _Iterator& __i)
8453 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8454 {
return ranges::iter_move(__i._M_current); }
8456 friend constexpr void
8457 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8458 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8459 requires indirectly_swappable<iterator_t<_Base>>
8460 { ranges::iter_swap(__x._M_current, __y._M_current); }
8467 template<
typename _Range,
typename _Dp>
8468 concept __can_stride_view
8472 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8474 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8475 requires __detail::__can_stride_view<_Range, _Dp>
8477 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8480 using __adaptor::_RangeAdaptor<_Stride>::operator();
8481 static constexpr int _S_arity = 2;
8482 static constexpr bool _S_has_simple_extra_args =
true;
8485 inline constexpr _Stride stride;
8489#ifdef __cpp_lib_ranges_cartesian_product
8492 template<
bool _Const,
typename _First,
typename... _Vs>
8493 concept __cartesian_product_is_random_access
8494 = (random_access_range<__maybe_const_t<_Const, _First>>
8496 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8497 && sized_range<__maybe_const_t<_Const, _Vs>>));
8499 template<
typename _Range>
8500 concept __cartesian_product_common_arg
8501 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8503 template<
bool _Const,
typename _First,
typename... _Vs>
8504 concept __cartesian_product_is_bidirectional
8505 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8507 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8508 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8510 template<
typename _First,
typename... _Vs>
8511 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8513 template<
typename... _Vs>
8514 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8516 template<
bool _Const,
template<
typename>
class _FirstSent,
8517 typename _First,
typename... _Vs>
8518 concept __cartesian_is_sized_sentinel
8519 = (sized_sentinel_for<_FirstSent<__maybe_const_t<_Const, _First>>,
8520 iterator_t<__maybe_const_t<_Const, _First>>>
8522 && (sized_range<__maybe_const_t<_Const, _Vs>>
8523 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8524 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8526 template<__cartesian_product_common_arg _Range>
8528 __cartesian_common_arg_end(_Range& __r)
8530 if constexpr (common_range<_Range>)
8531 return ranges::end(__r);
8533 return ranges::begin(__r) + ranges::distance(__r);
8539 class cartesian_product_view : public
view_interface<cartesian_product_view<_First, _Vs...>>
8541 tuple<_First, _Vs...> _M_bases;
8543 template<
bool>
class _Iterator;
8546 _S_difference_type()
8552 range_difference_t<_First>,
8553 range_difference_t<_Vs>...>{};
8557 cartesian_product_view() =
default;
8560 cartesian_product_view(_First __first, _Vs... __rest)
8561 : _M_bases(std::move(__first), std::move(__rest)...)
8564 constexpr _Iterator<false>
8565 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8566 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8568 constexpr _Iterator<true>
8569 begin() const requires (
range<const _First> && ... &&
range<const _Vs>)
8570 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8572 constexpr _Iterator<false>
8573 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8574 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8577 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8578 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8579 auto& __first = std::get<0>(_M_bases);
8580 return _Ret{(__empty_tail
8581 ? ranges::begin(__first)
8582 : __detail::__cartesian_common_arg_end(__first)),
8583 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8586 return _Iterator<false>{*
this,
std::move(__its)};
8589 constexpr _Iterator<true>
8590 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8593 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8594 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8595 auto& __first = std::get<0>(_M_bases);
8596 return _Ret{(__empty_tail
8597 ? ranges::begin(__first)
8598 : __detail::__cartesian_common_arg_end(__first)),
8599 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8602 return _Iterator<true>{*
this,
std::move(__its)};
8605 constexpr default_sentinel_t
8606 end() const noexcept
8610 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8612 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8614 auto __size =
static_cast<_ST
>(1);
8615#ifdef _GLIBCXX_ASSERTIONS
8616 if constexpr (integral<_ST>)
8619 = (__builtin_mul_overflow(__size,
8620 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8623 __glibcxx_assert(!__overflow);
8627 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8633 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8635 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8637 auto __size =
static_cast<_ST
>(1);
8638#ifdef _GLIBCXX_ASSERTIONS
8639 if constexpr (integral<_ST>)
8642 = (__builtin_mul_overflow(__size,
8643 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8646 __glibcxx_assert(!__overflow);
8650 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8656 template<
typename... _Vs>
8657 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8661 template<bool _Const>
8662 class cartesian_product_view<_First, _Vs...>::_Iterator
8664 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8665 _Parent* _M_parent =
nullptr;
8666 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8667 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8670 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8672 _M_current(std::move(__current))
8678 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8679 return random_access_iterator_tag{};
8680 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8681 return bidirectional_iterator_tag{};
8683 return forward_iterator_tag{};
8685 return input_iterator_tag{};
8688 friend cartesian_product_view;
8691 using iterator_category = input_iterator_tag;
8692 using iterator_concept =
decltype(_S_iter_concept());
8694 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8695 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8697 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8698 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8699 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8701 _Iterator() =
default;
8704 _Iterator(_Iterator<!_Const> __i)
8706 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8707 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8709 _M_current(std::move(__i._M_current))
8715 auto __f = [](
auto& __i) ->
decltype(
auto) {
8718 return __detail::__tuple_transform(__f, _M_current);
8721 constexpr _Iterator&
8740 constexpr _Iterator&
8742 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8750 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8757 constexpr _Iterator&
8758 operator+=(difference_type __x)
8759 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8765 constexpr _Iterator&
8766 operator-=(difference_type __x)
8767 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8768 {
return *
this += -__x; }
8771 operator[](difference_type __n)
const
8772 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8773 {
return *((*this) + __n); }
8775 friend constexpr bool
8776 operator==(
const _Iterator& __x,
const _Iterator& __y)
8777 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8778 {
return __x._M_current == __y._M_current; }
8780 friend constexpr bool
8781 operator==(
const _Iterator& __x, default_sentinel_t)
8784 return ((std::get<_Is>(__x._M_current)
8785 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8790 friend constexpr auto
8791 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8792 requires __detail::__all_random_access<_Const, _First, _Vs...>
8793 {
return __x._M_current <=> __y._M_current; }
8795 friend constexpr _Iterator
8796 operator+(_Iterator __x, difference_type __y)
8797 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8798 {
return __x += __y; }
8800 friend constexpr _Iterator
8801 operator+(difference_type __x, _Iterator __y)
8802 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8803 {
return __y += __x; }
8805 friend constexpr _Iterator
8806 operator-(_Iterator __x, difference_type __y)
8807 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8808 {
return __x -= __y; }
8810 friend constexpr difference_type
8811 operator-(
const _Iterator& __x,
const _Iterator& __y)
8812 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8813 {
return __x._M_distance_from(__y._M_current); }
8815 friend constexpr difference_type
8816 operator-(
const _Iterator& __i, default_sentinel_t)
8817 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8820 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8821 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8823 return __i._M_distance_from(__end_tuple);
8826 friend constexpr difference_type
8827 operator-(default_sentinel_t,
const _Iterator& __i)
8828 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8831 friend constexpr auto
8832 iter_move(
const _Iterator& __i)
8833 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8835 friend constexpr void
8836 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8837 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8839 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8842 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8847 template<
size_t _Nm =
sizeof...(_Vs)>
8851 auto& __it = std::get<_Nm>(_M_current);
8853 if constexpr (_Nm > 0)
8854 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8856 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8861 template<
size_t _Nm =
sizeof...(_Vs)>
8865 auto& __it = std::get<_Nm>(_M_current);
8866 if constexpr (_Nm > 0)
8867 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8869 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8875 template<
size_t _Nm =
sizeof...(_Vs)>
8877 _M_advance(difference_type __x)
8878 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8887 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8888 auto& __it = std::get<_Nm>(_M_current);
8889 if constexpr (_Nm == 0)
8891#ifdef _GLIBCXX_ASSERTIONS
8894 auto __size = ranges::ssize(__r);
8895 auto __begin = ranges::begin(__r);
8896 auto __offset = __it - __begin;
8897 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8904 auto __size = ranges::ssize(__r);
8905 auto __begin = ranges::begin(__r);
8906 auto __offset = __it - __begin;
8908 __x = __offset / __size;
8912 __offset = __size + __offset;
8915 __it = __begin + __offset;
8916 _M_advance<_Nm - 1>(__x);
8921 template<
typename _Tuple>
8922 constexpr difference_type
8923 _M_distance_from(
const _Tuple& __t)
const
8926 auto __sum =
static_cast<difference_type
>(0);
8927#ifdef _GLIBCXX_ASSERTIONS
8928 if constexpr (integral<difference_type>)
8931 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8933 __glibcxx_assert(!__overflow);
8937 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8942 template<
size_t _Nm,
typename _Tuple>
8943 constexpr difference_type
8944 _M_scaled_distance(
const _Tuple& __t)
const
8946 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8947 - std::get<_Nm>(__t));
8948#ifdef _GLIBCXX_ASSERTIONS
8949 if constexpr (integral<difference_type>)
8951 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8952 __glibcxx_assert(!__overflow);
8956 __dist *= _M_scaled_size<_Nm+1>();
8960 template<
size_t _Nm>
8961 constexpr difference_type
8962 _M_scaled_size()
const
8964 if constexpr (_Nm <=
sizeof...(_Vs))
8966 auto __size =
static_cast<difference_type
>(ranges::size
8967 (std::get<_Nm>(_M_parent->_M_bases)));
8968#ifdef _GLIBCXX_ASSERTIONS
8969 if constexpr (integral<difference_type>)
8971 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8972 __glibcxx_assert(!__overflow);
8976 __size *= _M_scaled_size<_Nm+1>();
8980 return static_cast<difference_type
>(1);
8988 template<
typename... _Ts>
8989 concept __can_cartesian_product_view
8993 struct _CartesianProduct
8995 template<
typename... _Ts>
8996 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8998 operator() [[nodiscard]] (_Ts&&... __ts)
const
9000 if constexpr (
sizeof...(_Ts) == 0)
9001 return views::single(tuple{});
9007 inline constexpr _CartesianProduct cartesian_product;
9011#ifdef __cpp_lib_ranges_as_rvalue
9012 template<input_range _Vp>
9014 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
9016 _Vp _M_base = _Vp();
9019 as_rvalue_view()
requires default_initializable<_Vp> = default;
9022 as_rvalue_view(_Vp __base)
9023 : _M_base(std::move(__base))
9027 base() const& requires copy_constructible<_Vp>
9035 begin()
requires (!__detail::__simple_view<_Vp>)
9036 {
return move_iterator(ranges::begin(_M_base)); }
9039 begin() const requires range<const _Vp>
9040 {
return move_iterator(ranges::begin(_M_base)); }
9043 end()
requires (!__detail::__simple_view<_Vp>)
9045 if constexpr (common_range<_Vp>)
9046 return move_iterator(ranges::end(_M_base));
9048 return move_sentinel(ranges::end(_M_base));
9052 end() const requires range<const _Vp>
9054 if constexpr (common_range<const _Vp>)
9055 return move_iterator(ranges::end(_M_base));
9057 return move_sentinel(ranges::end(_M_base));
9061 size()
requires sized_range<_Vp>
9062 {
return ranges::size(_M_base); }
9065 size() const requires sized_range<const _Vp>
9066 {
return ranges::size(_M_base); }
9069 template<
typename _Range>
9070 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
9072 template<
typename _Tp>
9073 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
9074 = enable_borrowed_range<_Tp>;
9080 template<
typename _Tp>
9081 concept __can_as_rvalue_view =
requires { as_rvalue_view(
std::declval<_Tp>()); };
9084 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
9086 template<viewable_range _Range>
9087 requires __detail::__can_as_rvalue_view<_Range>
9089 operator() [[nodiscard]] (_Range&& __r)
const
9091 if constexpr (same_as<range_rvalue_reference_t<_Range>,
9092 range_reference_t<_Range>>)
9099 inline constexpr _AsRvalue as_rvalue;
9103#ifdef __cpp_lib_ranges_enumerate
9106 template<
typename _Range>
9107 concept __range_with_movable_reference = input_range<_Range>
9108 && move_constructible<range_reference_t<_Range>>
9109 && move_constructible<range_rvalue_reference_t<_Range>>;
9113 requires __detail::__range_with_movable_reference<_Vp>
9114 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
9116 _Vp _M_base = _Vp();
9118 template<
bool _Const>
class _Iterator;
9119 template<
bool _Const>
class _Sentinel;
9122 enumerate_view()
requires default_initializable<_Vp> = default;
9125 enumerate_view(_Vp __base)
9126 : _M_base(std::move(__base))
9130 begin()
requires (!__detail::__simple_view<_Vp>)
9131 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
9134 begin() const requires __detail::__range_with_movable_reference<const _Vp>
9135 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
9138 end()
requires (!__detail::__simple_view<_Vp>)
9140 if constexpr (common_range<_Vp> && sized_range<_Vp>)
9141 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
9143 return _Sentinel<false>(ranges::end(_M_base));
9147 end() const requires __detail::__range_with_movable_reference<const _Vp>
9149 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9150 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9152 return _Sentinel<true>(ranges::end(_M_base));
9156 size()
requires sized_range<_Vp>
9157 {
return ranges::size(_M_base); }
9160 size() const requires sized_range<const _Vp>
9161 {
return ranges::size(_M_base); }
9164 base() const & requires copy_constructible<_Vp>
9172 template<
typename _Range>
9173 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9175 template<
typename _Tp>
9176 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9177 = enable_borrowed_range<_Tp>;
9180 requires __detail::__range_with_movable_reference<_Vp>
9181 template<
bool _Const>
9182 class enumerate_view<_Vp>::_Iterator
9184 using _Base = __maybe_const_t<_Const, _Vp>;
9189 if constexpr (random_access_range<_Base>)
9190 return random_access_iterator_tag{};
9191 else if constexpr (bidirectional_range<_Base>)
9192 return bidirectional_iterator_tag{};
9193 else if constexpr (forward_range<_Base>)
9194 return forward_iterator_tag{};
9196 return input_iterator_tag{};
9199 friend enumerate_view;
9202 using iterator_category = input_iterator_tag;
9203 using iterator_concept =
decltype(_S_iter_concept());
9204 using difference_type = range_difference_t<_Base>;
9205 using value_type = tuple<difference_type, range_value_t<_Base>>;
9208 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9210 iterator_t<_Base> _M_current = iterator_t<_Base>();
9211 difference_type _M_pos = 0;
9214 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9215 : _M_current(std::move(__current)), _M_pos(__pos)
9219 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
9222 _Iterator(_Iterator<!_Const> __i)
9223 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9224 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9227 constexpr const iterator_t<_Base> &
9228 base() const & noexcept
9229 {
return _M_current; }
9231 constexpr iterator_t<_Base>
9235 constexpr difference_type
9236 index() const noexcept
9241 {
return __reference_type(_M_pos, *_M_current); }
9243 constexpr _Iterator&
9256 operator++(
int)
requires forward_range<_Base>
9263 constexpr _Iterator&
9264 operator--()
requires bidirectional_range<_Base>
9272 operator--(
int)
requires bidirectional_range<_Base>
9279 constexpr _Iterator&
9280 operator+=(difference_type __n)
requires random_access_range<_Base>
9287 constexpr _Iterator&
9288 operator-=(difference_type __n)
requires random_access_range<_Base>
9296 operator[](difference_type __n)
const requires random_access_range<_Base>
9297 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9299 friend constexpr bool
9300 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9301 {
return __x._M_pos == __y._M_pos; }
9303 friend constexpr strong_ordering
9304 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9305 {
return __x._M_pos <=> __y._M_pos; }
9307 friend constexpr _Iterator
9308 operator+(
const _Iterator& __x, difference_type __y)
9309 requires random_access_range<_Base>
9310 {
return (
auto(__x) += __y); }
9312 friend constexpr _Iterator
9313 operator+(difference_type __x,
const _Iterator& __y)
9314 requires random_access_range<_Base>
9315 {
return auto(__y) += __x; }
9317 friend constexpr _Iterator
9318 operator-(
const _Iterator& __x, difference_type __y)
9319 requires random_access_range<_Base>
9320 {
return auto(__x) -= __y; }
9322 friend constexpr difference_type
9323 operator-(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9324 {
return __x._M_pos - __y._M_pos; }
9326 friend constexpr auto
9327 iter_move(
const _Iterator& __i)
9328 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9329 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9331 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9332 (__i._M_pos, ranges::iter_move(__i._M_current));
9337 requires __detail::__range_with_movable_reference<_Vp>
9338 template<
bool _Const>
9339 class enumerate_view<_Vp>::_Sentinel
9341 using _Base = __maybe_const_t<_Const, _Vp>;
9343 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9346 _Sentinel(sentinel_t<_Base> __end)
9347 : _M_end(std::move(__end))
9350 friend enumerate_view;
9353 _Sentinel() =
default;
9356 _Sentinel(_Sentinel<!_Const> __other)
9357 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9361 constexpr sentinel_t<_Base>
9365 template<
bool _OtherConst>
9366 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9367 friend constexpr bool
9368 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9369 {
return __x._M_current == __y._M_end; }
9371 template<
bool _OtherConst>
9372 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9373 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9374 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9375 {
return __x._M_current - __y._M_end; }
9377 template<
bool _OtherConst>
9378 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9379 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9380 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9381 {
return __x._M_end - __y._M_current; }
9388 template<
typename _Tp>
9389 concept __can_enumerate_view
9393 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9395 template<viewable_range _Range>
9396 requires __detail::__can_enumerate_view<_Range>
9398 operator() [[nodiscard]] (_Range&& __r)
const
9402 inline constexpr _Enumerate enumerate;
9406#ifdef __cpp_lib_ranges_as_const
9411 _Vp _M_base = _Vp();
9414 as_const_view()
requires default_initializable<_Vp> = default;
9417 as_const_view(_Vp __base)
9418 noexcept(is_nothrow_move_constructible_v<_Vp>)
9419 : _M_base(std::move(__base))
9424 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9425 requires copy_constructible<_Vp>
9430 noexcept(is_nothrow_move_constructible_v<_Vp>)
9434 begin()
requires (!__detail::__simple_view<_Vp>)
9435 {
return ranges::cbegin(_M_base); }
9438 begin() const requires range<const _Vp>
9439 {
return ranges::cbegin(_M_base); }
9442 end()
requires (!__detail::__simple_view<_Vp>)
9443 {
return ranges::cend(_M_base); }
9446 end() const requires range<const _Vp>
9447 {
return ranges::cend(_M_base); }
9450 size()
requires sized_range<_Vp>
9451 {
return ranges::size(_M_base); }
9454 size() const requires sized_range<const _Vp>
9455 {
return ranges::size(_M_base); }
9458 template<
typename _Range>
9459 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9461 template<
typename _Tp>
9462 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9463 = enable_borrowed_range<_Tp>;
9469 template<
typename _Tp>
9470 inline constexpr bool __is_constable_ref_view =
false;
9472 template<
typename _Range>
9473 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9474 = constant_range<const _Range>;
9476 template<
typename _Range>
9480 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9482 template<viewable_range _Range>
9484 operator()(_Range&& __r)
const
9486 requires __detail::__can_as_const_view<_Range>
9488 using _Tp = remove_cvref_t<_Range>;
9489 using element_type = remove_reference_t<range_reference_t<_Range>>;
9490 if constexpr (constant_range<views::all_t<_Range>>)
9492 else if constexpr (__detail::__is_empty_view<_Tp>)
9493 return views::empty<const element_type>;
9494#if __cpp_lib_optional >= 202506L && __cpp_lib_optional_range_support
9495 else if constexpr (__is_optional_ref_v<_Tp>)
9496 return optional<const typename _Tp::value_type&>(__r);
9498 else if constexpr (std::__detail::__is_span<_Tp>)
9500 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9502 else if constexpr (is_lvalue_reference_v<_Range>
9503 && constant_range<const _Tp>
9505 return ref_view(
static_cast<const _Tp&
>(__r));
9511 inline constexpr _AsConst as_const;
9516 namespace views = ranges::views;
9518#if __cpp_lib_ranges_to_container
9524 template<
typename _Container>
9525 constexpr bool __reservable_container
9526 = sized_range<_Container>
9527 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9529 { __c.capacity() } -> same_as<
decltype(__n)>;
9530 { __c.max_size() } -> same_as<
decltype(__n)>;
9533 template<
typename _Cont,
typename _Range>
9534 constexpr bool __toable =
requires {
9535 requires (!input_range<_Cont>
9536 || convertible_to<range_reference_t<_Range>,
9537 range_value_t<_Cont>>);
9558 template<
typename _Cont, input_range _Rg,
typename... _Args>
9559 requires (!view<_Cont>)
9561 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9563 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9564 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9566 if constexpr (__detail::__toable<_Cont, _Rg>)
9568 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9571 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9574 else if constexpr (
requires {
requires common_range<_Rg>;
9575 typename __iter_category_t<iterator_t<_Rg>>;
9576 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9577 input_iterator_tag>;
9578 requires constructible_from<_Cont, iterator_t<_Rg>,
9579 sentinel_t<_Rg>, _Args...>;
9581 return _Cont(ranges::begin(__r), ranges::end(__r),
9585 static_assert(constructible_from<_Cont, _Args...>);
9587 if constexpr (sized_range<_Rg>
9588 && __detail::__reservable_container<_Cont>)
9589 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9593 auto __it = ranges::begin(__r);
9594 const auto __sent = ranges::end(__r);
9595 while (__it != __sent)
9597 if constexpr (
requires { __c.emplace_back(*__it); })
9598 __c.emplace_back(*__it);
9599 else if constexpr (
requires { __c.push_back(*__it); })
9600 __c.push_back(*__it);
9601 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9602 __c.emplace(__c.end(), *__it);
9604 __c.insert(__c.end(), *__it);
9612 static_assert(input_range<range_reference_t<_Rg>>);
9615 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9616 []<
typename _Elt>(_Elt&& __elem) {
9617 using _ValT = range_value_t<_Cont>;
9626 template<
typename _Rg>
9629 using iterator_category = input_iterator_tag;
9630 using value_type = range_value_t<_Rg>;
9631 using difference_type = ptrdiff_t;
9632 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9633 using reference = range_reference_t<_Rg>;
9635 pointer operator->()
const;
9636 _InputIter& operator++();
9637 _InputIter operator++(
int);
9638 bool operator==(
const _InputIter&)
const;
9641 template<
template<
typename...>
typename _Cont, input_range _Rg,
9646 template<
template<
typename...>
typename _Cont, input_range _Rg,
9652 template<
template<
typename...>
typename _Cont, input_range _Rg,
9662 template<
template<
typename...>
typename _Cont, input_range _Rg,
9665 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9667 using __detail::_DeduceExpr1;
9668 using __detail::_DeduceExpr2;
9669 using __detail::_DeduceExpr3;
9670 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9671 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9673 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9674 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9676 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9677 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9680 static_assert(
false);
9686 template<
typename _Cont>
9689 template<
typename _Range,
typename... _Args>
9693 operator()(_Range&& __r, _Args&&... __args)
const
9717 template<
typename _Cont,
typename... _Args>
9718 requires (!view<_Cont>)
9720 to [[nodiscard]] (_Args&&... __args)
9722 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9723 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9725 using __detail::_To;
9726 using views::__adaptor::_Partial;
9733 template<
template<
typename...>
typename _Cont>
9736 template<
typename _Range,
typename... _Args>
9740 operator()(_Range&& __r, _Args&&... __args)
const
9766 template<
template<
typename...>
typename _Cont,
typename... _Args>
9768 to [[nodiscard]] (_Args&&... __args)
9770 using __detail::_To2;
9771 using views::__adaptor::_Partial;
9778#if __cpp_lib_ranges_concat
9783 template<
typename... _Rs>
9784 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9786 template<
typename... _Rs>
9787 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9789 template<
typename... _Rs>
9790 using __concat_rvalue_reference_t
9791 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9793 template<
typename _Ref,
typename _RRef,
typename _It>
9794 concept __concat_indirectly_readable_impl =
requires(
const _It __it) {
9795 { *__it } -> convertible_to<_Ref>;
9796 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9799 template<
typename... _Rs>
9800 concept __concat_indirectly_readable
9801 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9802 && common_reference_with<__concat_reference_t<_Rs...>&&,
9803 __concat_rvalue_reference_t<_Rs...>&&>
9804 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9805 __concat_value_t<_Rs...>
const&>
9806 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9807 __concat_rvalue_reference_t<_Rs...>,
9811 template<
typename... _Rs>
9812 concept __concatable =
requires {
9813 typename __concat_reference_t<_Rs...>;
9814 typename __concat_value_t<_Rs...>;
9815 typename __concat_rvalue_reference_t<_Rs...>;
9816 } && __concat_indirectly_readable<_Rs...>;
9818 template<
bool _Const,
typename _Range,
typename... _Rs>
9819 struct __all_but_last_common
9821 static inline constexpr bool value
9822 =
requires {
requires (common_range<__maybe_const_t<_Const, _Range>>
9823 && __all_but_last_common<_Const, _Rs...>::value); };
9826 template<
bool _Const,
typename _Range>
9827 struct __all_but_last_common<_Const, _Range>
9828 {
static inline constexpr bool value =
true; };
9830 template<
bool _Const,
typename... _Rs>
9831 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9832 && __all_but_last_common<_Const, _Rs...>::value;
9834 template<
bool _Const,
typename... _Rs>
9835 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9836 && __all_but_last_common<_Const, _Rs...>::value;
9838 template<
typename _Range,
typename... _Rs>
9839 struct __all_but_first_sized
9840 {
static inline constexpr bool value = (sized_range<_Rs> && ...); };
9843 template<input_range... _Vs>
9844 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9845 class concat_view : public view_interface<concat_view<_Vs...>>
9847 tuple<_Vs...> _M_views;
9849 template<
bool _Const>
class _Iterator;
9852 constexpr concat_view() =
default;
9855 concat_view(_Vs... __views)
9856 : _M_views(std::move(__views)...)
9859 constexpr _Iterator<false>
9860 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
9862 _Iterator<false> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9863 __it.template _M_satisfy<0>();
9867 constexpr _Iterator<true>
9868 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9870 _Iterator<true> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9871 __it.template _M_satisfy<0>();
9876 end()
requires (!(__detail::__simple_view<_Vs> && ...))
9878 constexpr auto __n =
sizeof...(_Vs);
9879 if constexpr (__detail::__all_forward<
false, _Vs...>
9880 && common_range<_Vs...[__n - 1]>)
9881 return _Iterator<false>(
this, in_place_index<__n - 1>,
9882 ranges::end(std::get<__n - 1>(_M_views)));
9888 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9890 constexpr auto __n =
sizeof...(_Vs);
9891 if constexpr (__detail::__all_forward<
true, _Vs...>
9892 && common_range<
const _Vs...[__n - 1]>)
9893 return _Iterator<true>(
this, in_place_index<__n - 1>,
9894 ranges::end(std::get<__n - 1>(_M_views)));
9900 size()
requires (sized_range<_Vs>&&...)
9902 return std::apply([](
auto... __sizes) {
9903 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9904 return (_CT(__sizes) + ...);
9905 }, __detail::__tuple_transform(ranges::size, _M_views));
9909 size() const requires (sized_range<const _Vs>&&...)
9911 return std::apply([](
auto... __sizes) {
9912 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9913 return (_CT(__sizes) + ...);
9914 }, __detail::__tuple_transform(ranges::size, _M_views));
9918 template<
typename... _Rs>
9919 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9923 template<
bool _Const,
typename... _Vs>
9924 struct __concat_view_iter_cat
9927 template<
bool _Const,
typename... _Vs>
9928 requires __detail::__all_forward<_Const, _Vs...>
9929 struct __concat_view_iter_cat<_Const, _Vs...>
9934 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9935 return input_iterator_tag{};
9937 return []<
typename... _Cats>(_Cats... __cats) {
9938 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9939 && __concat_is_random_access<_Const, _Vs...>)
9940 return random_access_iterator_tag{};
9941 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9942 && __concat_is_bidirectional<_Const, _Vs...>)
9943 return bidirectional_iterator_tag{};
9944 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9945 return forward_iterator_tag{};
9947 return input_iterator_tag{};
9948 }(
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9949 ::iterator_category{}...);
9954 template<input_range... _Vs>
9955 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9956 template<bool _Const>
9957 class concat_view<_Vs...>::_Iterator
9958 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9963 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9964 return random_access_iterator_tag{};
9965 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9966 return bidirectional_iterator_tag{};
9967 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9968 return forward_iterator_tag{};
9970 return input_iterator_tag{};
9974 friend _Iterator<!_Const>;
9978 using iterator_concept =
decltype(_S_iter_concept());
9979 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9980 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9983 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9985 __maybe_const_t<_Const, concat_view>* _M_parent =
nullptr;
9988 template<
size_t _Nm>
9992 if constexpr (_Nm < (
sizeof...(_Vs) - 1))
9994 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9996 _M_it.template emplace<_Nm + 1>(ranges::begin
9997 (std::get<_Nm + 1>(_M_parent->_M_views)));
9998 _M_satisfy<_Nm + 1>();
10003 template<
size_t _Nm>
10007 if constexpr (_Nm == 0)
10008 --std::get<0>(_M_it);
10011 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
10013 _M_it.template emplace<_Nm - 1>(ranges::end
10014 (std::get<_Nm - 1>(_M_parent->_M_views)));
10015 _M_prev<_Nm - 1>();
10018 --std::get<_Nm>(_M_it);
10022 template<
size_t _Nm>
10024 _M_advance_fwd(difference_type __offset, difference_type __steps)
10026 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10027 if constexpr (_Nm ==
sizeof...(_Vs) - 1)
10028 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10031 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
10032 if (__offset + __steps < __n_size)
10033 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10036 _M_it.template emplace<_Nm + 1>(ranges::begin
10037 (std::get<_Nm + 1>(_M_parent->_M_views)));
10038 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
10043 template<
size_t _Nm>
10045 _M_advance_bwd(difference_type __offset, difference_type __steps)
10047 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10048 if constexpr (_Nm == 0)
10049 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10051 if (__offset >= __steps)
10052 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10055 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
10056 _M_it.template emplace<_Nm - 1>(ranges::end
10057 (std::get<_Nm - 1>(_M_parent->_M_views)));
10058 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
10066 template<
typename _Fp>
10067 static constexpr auto
10068 _S_invoke_with_runtime_index(_Fp&& __f,
size_t __index)
10070 return [&__f, __index]<
size_t _Idx>(
this auto&& __self) {
10071 if (_Idx == __index)
10072 return __f.template operator()<_Idx>();
10073 if constexpr (_Idx + 1 <
sizeof...(_Vs))
10074 return __self.template
operator()<_Idx + 1>();
10075 __builtin_unreachable();
10076 }.template operator()<0>();
10079 template<
typename _Fp>
10081 _M_invoke_with_runtime_index(_Fp&& __f)
10082 {
return _S_invoke_with_runtime_index(
std::forward<_Fp>(__f), _M_it.index()); }
10084 template<
typename... _Args>
10086 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
10087 requires constructible_from<__base_iter, _Args&&...>
10092 _Iterator() =
default;
10095 _Iterator(_Iterator<!_Const> __it)
10096 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
10097 : _M_parent(__it._M_parent),
10098 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
10099 return __base_iter(in_place_index<_Idx>,
10100 std::get<_Idx>(
std::move(__it._M_it)));
10101 }, __it._M_it.index()))
10104 constexpr decltype(
auto)
10107 __glibcxx_assert(!_M_it.valueless_by_exception());
10108 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
10109 return std::visit([](
auto&& __it) -> reference {
return *__it; }, _M_it);
10112 constexpr _Iterator&
10115 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10116 ++std::get<_Idx>(_M_it);
10117 _M_satisfy<_Idx>();
10126 constexpr _Iterator
10128 requires __detail::__all_forward<_Const, _Vs...>
10130 auto __tmp = *
this;
10135 constexpr _Iterator&
10137 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10139 __glibcxx_assert(!_M_it.valueless_by_exception());
10140 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10146 constexpr _Iterator
10148 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10150 auto __tmp = *
this;
10155 constexpr _Iterator&
10156 operator+=(difference_type __n)
10157 requires __detail::__concat_is_random_access<_Const, _Vs...>
10159 __glibcxx_assert(!_M_it.valueless_by_exception());
10160 _M_invoke_with_runtime_index([
this, __n]<
size_t _Idx>() {
10161 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10163 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10165 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10170 constexpr _Iterator&
10171 operator-=(difference_type __n)
10172 requires __detail::__concat_is_random_access<_Const, _Vs...>
10178 constexpr decltype(
auto)
10179 operator[](difference_type __n)
const
10180 requires __detail::__concat_is_random_access<_Const, _Vs...>
10181 {
return *((*this) + __n); }
10183 friend constexpr bool
10184 operator==(
const _Iterator& __x,
const _Iterator& __y)
10185 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10187 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10188 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10189 return __x._M_it == __y._M_it;
10192 friend constexpr bool
10193 operator==(
const _Iterator& __it, default_sentinel_t)
10195 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10196 constexpr auto __last_idx =
sizeof...(_Vs) - 1;
10197 return (__it._M_it.index() == __last_idx
10198 && (std::get<__last_idx>(__it._M_it)
10199 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10202 friend constexpr bool
10203 operator<(
const _Iterator& __x,
const _Iterator& __y)
10204 requires __detail::__all_random_access<_Const, _Vs...>
10205 {
return __x._M_it < __y._M_it; }
10207 friend constexpr bool
10208 operator>(
const _Iterator& __x,
const _Iterator& __y)
10209 requires __detail::__all_random_access<_Const, _Vs...>
10210 {
return __x._M_it > __y._M_it; }
10212 friend constexpr bool
10213 operator<=(
const _Iterator& __x,
const _Iterator& __y)
10214 requires __detail::__all_random_access<_Const, _Vs...>
10215 {
return __x._M_it <= __y._M_it; }
10217 friend constexpr bool
10218 operator>=(
const _Iterator& __x,
const _Iterator& __y)
10219 requires __detail::__all_random_access<_Const, _Vs...>
10220 {
return __x._M_it >= __y._M_it; }
10222 friend constexpr auto
10223 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
10224 requires __detail::__all_random_access<_Const, _Vs...>
10225 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10226 {
return __x._M_it <=> __y._M_it; }
10228 friend constexpr _Iterator
10229 operator+(
const _Iterator& __it, difference_type __n)
10230 requires __detail::__concat_is_random_access<_Const, _Vs...>
10231 {
return auto(__it) += __n; }
10233 friend constexpr _Iterator
10234 operator+(difference_type __n,
const _Iterator& __it)
10235 requires __detail::__concat_is_random_access<_Const, _Vs...>
10236 {
return __it + __n; }
10238 friend constexpr _Iterator
10239 operator-(
const _Iterator& __it, difference_type __n)
10240 requires __detail::__concat_is_random_access<_Const, _Vs...>
10241 {
return auto(__it) -= __n; }
10243 friend constexpr difference_type
10244 operator-(
const _Iterator& __x,
const _Iterator& __y)
10245 requires __detail::__concat_is_random_access<_Const, _Vs...>
10247 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10248 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> difference_type {
10249 if constexpr (_Ix > _Iy)
10251 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10252 ranges::end(std::get<_Iy>(__y._M_parent
10254 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10256 std::get<_Ix>(__x._M_it));
10257 difference_type __s = 0;
10258 [&]<
size_t _Idx = _Iy + 1>(
this auto&& __self) {
10259 if constexpr (_Idx < _Ix)
10261 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10262 __self.template operator()<_Idx + 1>();
10265 return __dy + __s + __dx;
10267 else if constexpr (_Ix < _Iy)
10268 return -(__y - __x);
10270 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10271 }, __y._M_it.index());
10272 }, __x._M_it.index());
10275 friend constexpr difference_type
10276 operator-(
const _Iterator& __x, default_sentinel_t)
10277 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10278 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10279 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10281 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10282 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10283 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10284 difference_type __s = 0;
10285 [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) {
10286 if constexpr (_Idx <
sizeof...(_Vs))
10288 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10289 __self.template operator()<_Idx + 1>();
10292 return -(__dx + __s);
10293 }, __x._M_it.index());
10296 friend constexpr difference_type
10297 operator-(default_sentinel_t,
const _Iterator& __x)
10298 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10299 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10300 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10303 friend constexpr decltype(
auto)
10304 iter_move(
const _Iterator& __it)
10306 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10307 return std::visit([](
const auto& __i) -> _Res {
10308 return ranges::iter_move(__i);
10312 friend constexpr void
10313 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10314 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10315 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10317 std::visit([&]<
typename _Tp,
typename _Up>(
const _Tp& __it1,
const _Up& __it2) {
10318 if constexpr (is_same_v<_Tp, _Up>)
10319 ranges::iter_swap(__it1, __it2);
10321 ranges::swap(*__it1, *__it2);
10322 }, __x._M_it, __y._M_it);
10330 template<
typename... _Ts>
10336 template<
typename... _Ts>
10337 requires __detail::__can_concat_view<_Ts...>
10339 operator() [[nodiscard]] (_Ts&&... __ts)
const
10342 template<input_range _Range>
10344 operator() [[nodiscard]] (_Range&& __t)
const
10348 inline constexpr _Concat concat;
10354#if __cpp_lib_ranges_cache_latest
10357 template<input_range _Vp>
10359 class cache_latest_view :
public view_interface<cache_latest_view<_Vp>>
10361 _Vp _M_base = _Vp();
10363 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10364 add_pointer_t<range_reference_t<_Vp>>,
10365 range_reference_t<_Vp>>;
10366 __detail::__non_propagating_cache<__cache_t> _M_cache;
10372 cache_latest_view()
requires default_initializable<_Vp> = default;
10375 cache_latest_view(_Vp __base)
10376 : _M_base(std::move(__base))
10380 base() const & requires copy_constructible<_Vp>
10381 {
return _M_base; }
10389 {
return _Iterator(*
this); }
10393 {
return _Sentinel(*
this); }
10396 size()
requires sized_range<_Vp>
10397 {
return ranges::size(_M_base); }
10400 size() const requires sized_range<const _Vp>
10401 {
return ranges::size(_M_base); }
10404 template<
typename _Range>
10405 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10407 template<input_range _Vp>
10409 class cache_latest_view<_Vp>::_Iterator
10411 cache_latest_view* _M_parent;
10412 iterator_t<_Vp> _M_current;
10415 _Iterator(cache_latest_view& __parent)
10417 _M_current(ranges::begin(__parent._M_base))
10420 friend class cache_latest_view;
10423 using difference_type = range_difference_t<_Vp>;
10424 using value_type = range_value_t<_Vp>;
10425 using iterator_concept = input_iterator_tag;
10427 _Iterator(_Iterator&&) =
default;
10430 operator=(_Iterator&&) =
default;
10432 constexpr iterator_t<_Vp>
10436 constexpr const iterator_t<_Vp>&
10437 base() const & noexcept
10438 {
return _M_current; }
10440 constexpr range_reference_t<_Vp>&
10443 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10445 if (!_M_parent->_M_cache)
10446 _M_parent->_M_cache =
std::__addressof(__detail::__as_lvalue(*_M_current));
10447 return **_M_parent->_M_cache;
10451 if (!_M_parent->_M_cache)
10452 _M_parent->_M_cache._M_emplace_deref(_M_current);
10453 return *_M_parent->_M_cache;
10457 constexpr _Iterator&
10460 _M_parent->_M_cache._M_reset();
10469 friend constexpr range_rvalue_reference_t<_Vp>
10470 iter_move(
const _Iterator& __i)
10471 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10472 {
return ranges::iter_move(__i._M_current); }
10474 friend constexpr void
10475 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10476 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10477 requires indirectly_swappable<iterator_t<_Vp>>
10478 { ranges::iter_swap(__x._M_current, __y._M_current); }
10481 template<input_range _Vp>
10483 class cache_latest_view<_Vp>::_Sentinel
10485 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10488 _Sentinel(cache_latest_view& __parent)
10489 : _M_end(ranges::end(__parent._M_base))
10492 friend class cache_latest_view;
10495 _Sentinel() =
default;
10497 constexpr sentinel_t<_Vp>
10501 friend constexpr bool
10502 operator==(
const _Iterator& __x,
const _Sentinel& __y)
10503 {
return __x._M_current == __y._M_end; }
10505 friend constexpr range_difference_t<_Vp>
10506 operator-(
const _Iterator& __x,
const _Sentinel& __y)
10507 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10508 {
return __x._M_current - __y._M_end; }
10510 friend constexpr range_difference_t<_Vp>
10511 operator-(
const _Sentinel& __x,
const _Iterator& __y)
10512 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10513 {
return __x._M_end - __y._M_current; }
10520 template<
typename _Tp>
10521 concept __can_cache_latest =
requires { cache_latest_view(
std::declval<_Tp>()); };
10524 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10526 template<viewable_range _Range>
10527 requires __detail::__can_cache_latest<_Range>
10529 operator() [[nodiscard]] (_Range&& __r)
const
10532 static constexpr bool _S_has_simple_call_op =
true;
10535 inline constexpr _CacheLatest cache_latest;
10540#if __cpp_lib_ranges_as_input
10543 template<input_range _Vp>
10545 class as_input_view :
public view_interface<as_input_view<_Vp>>
10547 _Vp _M_base = _Vp();
10549 template<
bool _Const>
10553 as_input_view()
requires default_initializable<_Vp> = default;
10556 as_input_view(_Vp __base)
10557 : _M_base(std::move(__base))
10561 base() const & requires copy_constructible<_Vp>
10562 {
return _M_base; }
10569 begin()
requires (!__detail::__simple_view<_Vp>)
10570 {
return _Iterator<false>(ranges::begin(_M_base)); }
10573 begin() const requires range<const _Vp>
10574 {
return _Iterator<true>(ranges::begin(_M_base)); }
10577 end()
requires (!__detail::__simple_view<_Vp>)
10578 {
return ranges::end(_M_base); }
10581 end() const requires range<const _Vp>
10582 {
return ranges::end(_M_base); }
10585 size()
requires sized_range<_Vp>
10586 {
return ranges::size(_M_base); }
10589 size() const requires sized_range<const _Vp>
10590 {
return ranges::size(_M_base); }
10593 template<
typename _Range>
10594 as_input_view(_Range&&) -> as_input_view<views::all_t<_Range>>;
10596 template<input_range _Vp>
10598 template<
bool _Const>
10599 class as_input_view<_Vp>::_Iterator
10601 using _Base = __maybe_const_t<_Const, _Vp>;
10603 iterator_t<_Base> _M_current = iterator_t<_Base>();
10606 _Iterator(iterator_t<_Base> __current)
10607 : _M_current(std::move(__current))
10610 friend as_input_view;
10611 friend _Iterator<!_Const>;
10614 using difference_type = range_difference_t<_Base>;
10615 using value_type = range_value_t<_Base>;
10616 using iterator_concept = input_iterator_tag;
10618 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
10620 _Iterator(_Iterator&&) = default;
10621 _Iterator& operator=(_Iterator&&) = default;
10624 _Iterator(_Iterator<!_Const> __i)
10625 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10626 : _M_current(std::move(__i._M_current))
10629 constexpr iterator_t<_Base>
10633 constexpr const iterator_t<_Base>&
10634 base() const & noexcept
10635 {
return _M_current; }
10637 constexpr decltype(
auto)
10639 {
return *_M_current; }
10641 constexpr _Iterator&
10652 friend constexpr bool
10653 operator==(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10654 {
return __x._M_current == __y; }
10656 friend constexpr difference_type
10657 operator-(
const sentinel_t<_Base>& __y,
const _Iterator& __x)
10658 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10659 {
return __y - __x._M_current; }
10661 friend constexpr difference_type
10662 operator-(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10663 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10664 {
return __x._M_current - __y; }
10666 friend constexpr range_rvalue_reference_t<_Base>
10667 iter_move(
const _Iterator& __i)
10668 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10669 {
return ranges::iter_move(__i._M_current); }
10671 friend constexpr void
10672 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10673 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10674 requires indirectly_swappable<iterator_t<_Base>>
10675 { ranges::iter_swap(__x._M_current, __y._M_current); }
10682 template<
typename _Tp>
10686 struct _AsInput : __adaptor::_RangeAdaptorClosure<_AsInput>
10688 template<viewable_range _Range>
10689 requires __detail::__can_as_input<_Range>
10691 operator() [[nodiscard]] (_Range&& __r)
const
10693 if constexpr (input_range<_Range>
10694 && !common_range<_Range>
10695 && !forward_range<_Range>)
10701 static constexpr bool _S_has_simple_call_op =
true;
10704 inline constexpr _AsInput as_input;
10709_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.
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
typename remove_reference< _Tp >::type remove_reference_t
Alias template for remove_reference.
typename common_type< _Tp... >::type common_type_t
Alias template for common_type.
typename make_unsigned< _Tp >::type make_unsigned_t
Alias template for make_unsigned.
typename decay< _Tp >::type decay_t
Alias template for decay.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
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.
ISO C++ entities toplevel namespace is std.
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
integer_sequence< size_t, _Idx... > index_sequence
Alias template 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 _Iterator __base(_Iterator __it)
A view that contains no elements.
A view that contains exactly one element.
constexpr reference_wrapper< _Tp > ref(_Tp &__t) noexcept
Denotes a reference should be taken to a variable.
constexpr reference_wrapper< const _Tp > cref(const _Tp &__t) noexcept
Denotes a const reference should be taken to a variable.
The ranges::view_interface class template.
[concept.constructible], concept constructible_from
[concept.defaultinitializable], concept default_initializable
[concept.moveconstructible], concept move_constructible
[concept.copyconstructible], concept copy_constructible
[range.range] The range concept.
[range.sized] The sized_range concept.
[range.view] The ranges::view concept.
A range for which ranges::begin returns an input iterator.
A range for which ranges::begin returns a forward iterator.
A range for which ranges::begin returns a bidirectional iterator.
A range for which ranges::begin returns a random access iterator.
A range for which ranges::begin returns a contiguous iterator.
A range for which ranges::begin and ranges::end return the same type.