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>
905 template<__detail::__can_iota_view _Tp>
906 constexpr iota_view<decay_t<_Tp>>
907 operator() [[nodiscard]] (_Tp&& __e)
const
910 template<
typename _Tp,
typename _Up>
911 requires __detail::__can_iota_view<_Tp, _Up>
913 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
917 inline constexpr _Iota iota{};
919#ifdef __cpp_lib_ranges_indices
922 template<ranges::__detail::__is_
integer_like _Tp>
923 requires __detail::__can_iota_view<_Tp>
924 [[nodiscard]]
constexpr auto
925 operator() (_Tp __e)
const noexcept
926 {
return iota(_Tp{}, __e); }
929 inline constexpr _Indices indices{};
936 template<
typename _Val,
typename _CharT,
typename _Traits>
937 concept __stream_extractable
938 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
941 template<movable _Val,
typename _CharT,
942 typename _Traits = char_traits<_CharT>>
943 requires default_initializable<_Val>
944 && __detail::__stream_extractable<_Val, _CharT, _Traits>
945 class basic_istream_view
946 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
950 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
957 *_M_stream >> _M_object;
958 return _Iterator{
this};
961 constexpr default_sentinel_t
966 basic_istream<_CharT, _Traits>* _M_stream;
967 _Val _M_object = _Val();
972 using iterator_concept = input_iterator_tag;
973 using difference_type = ptrdiff_t;
974 using value_type = _Val;
977 _Iterator(basic_istream_view* __parent) noexcept
978 : _M_parent(__parent)
981 _Iterator(
const _Iterator&) =
delete;
982 _Iterator(_Iterator&&) =
default;
983 _Iterator& operator=(
const _Iterator&) =
delete;
984 _Iterator& operator=(_Iterator&&) =
default;
989 *_M_parent->_M_stream >> _M_parent->_M_object;
999 {
return _M_parent->_M_object; }
1002 operator==(
const _Iterator& __x, default_sentinel_t)
1003 {
return !*__x._M_parent->_M_stream; }
1006 basic_istream_view* _M_parent;
1012 template<
typename _Val>
1013 using istream_view = basic_istream_view<_Val, char>;
1015 template<
typename _Val>
1016 using wistream_view = basic_istream_view<_Val, wchar_t>;
1022 template<
typename _Tp,
typename _Up>
1023 concept __can_istream_view =
requires (_Up __e) {
1024 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
1028 template<
typename _Tp>
1031 template<
typename _CharT,
typename _Traits>
1033 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
1035 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
1038 template<
typename _Tp>
1039 inline constexpr _Istream<_Tp> istream;
1047 template<
typename _Tp,
int _Disc>
1056 template<
bool _Present,
typename _Tp,
int _Disc = 0>
1057 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
1060 template<
bool _Const,
typename _Tp>
1061 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
1066using __detail::__maybe_const_t;
1068namespace views::__adaptor
1071 template<
typename _Adaptor,
typename... _Args>
1072 concept __adaptor_invocable
1077 template<
typename _Adaptor,
typename... _Args>
1078 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
1079 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
1080 && (constructible_from<decay_t<_Args>, _Args> && ...);
1082 template<
typename _Adaptor,
typename... _Args>
1085 template<
typename _Lhs,
typename _Rhs>
1093 template<
typename _Derived>
1094 struct _RangeAdaptorClosure;
1096 template<
typename _Tp,
typename _Up>
1097 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
1098 void __is_range_adaptor_closure_fn
1099 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
1101 template<
typename _Tp>
1102 concept __is_range_adaptor_closure
1103 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
1105#pragma GCC diagnostic push
1106#pragma GCC diagnostic ignored "-Wdangling-reference"
1108 template<
typename _Self,
typename _Range>
1109 requires __is_range_adaptor_closure<_Self>
1110 && __adaptor_invocable<_Self, _Range>
1112 operator|(_Range&& __r, _Self&& __self)
1117 template<
typename _Lhs,
typename _Rhs>
1118 requires __is_range_adaptor_closure<_Lhs>
1119 && __is_range_adaptor_closure<_Rhs>
1121 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
1126#pragma GCC diagnostic pop
1128 template<
typename _Derived>
1129 struct _RangeAdaptorClosure
1135 template<
typename _Self,
typename _Range>
1136 requires __is_range_adaptor_closure<_Self>
1137 && __adaptor_invocable<_Self, _Range>
1138 friend constexpr auto
1139 operator|(_Range&& __r, _Self&& __self);
1141 template<
typename _Lhs,
typename _Rhs>
1142 requires __is_range_adaptor_closure<_Lhs>
1143 && __is_range_adaptor_closure<_Rhs>
1144 friend constexpr auto
1145 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1159 template<
typename _Derived>
1160 struct _RangeAdaptor
1164 template<
typename... _Args>
1165 requires __adaptor_partial_app_viable<_Derived, _Args...>
1167 operator()(_Args&&... __args)
const
1176 template<
typename _Adaptor>
1177 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1181 template<
typename _Adaptor,
typename... _Args>
1182 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1183 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1187 template<
typename _Adaptor,
typename... _Args>
1188 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1190 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1191 [[no_unique_address]] _Binder _M_binder;
1195 template<
typename... _Ts>
1197 _Partial(
int, _Ts&&... __args)
1198 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1203#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1204# pragma GCC diagnostic push
1205# pragma GCC diagnostic ignored "-Wc++23-extensions"
1206 template<
typename _Self,
typename _Range>
1207 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1209 operator()(
this _Self&& __self, _Range&& __r)
1211 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1214# pragma GCC diagnostic pop
1216 template<
typename _Range>
1217 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1219 operator()(_Range&& __r)
const &
1222 template<
typename _Range>
1223 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1225 operator()(_Range&& __r) &&
1228 template<
typename _Range>
1230 operator()(_Range&& __r)
const && =
delete;
1238 template<
typename _Adaptor,
typename... _Args>
1239 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1240 && (is_trivially_copy_constructible_v<_Args> && ...)
1241 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1243 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1244 [[no_unique_address]] _Binder _M_binder;
1246 template<
typename... _Ts>
1248 _Partial(
int, _Ts&&... __args)
1249 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1254 template<
typename _Range>
1255 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1257 operator()(_Range&& __r)
const
1260 static constexpr bool _S_has_simple_call_op =
true;
1263 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1264 concept __pipe_invocable
1269 template<
typename _Lhs,
typename _Rhs>
1270 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1272 [[no_unique_address]] _Lhs _M_lhs;
1273 [[no_unique_address]] _Rhs _M_rhs;
1275 template<
typename _Tp,
typename _Up>
1277 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1278 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1283#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1284# pragma GCC diagnostic push
1285# pragma GCC diagnostic ignored "-Wc++23-extensions"
1286 template<
typename _Self,
typename _Range>
1287 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1289 operator()(
this _Self&& __self, _Range&& __r)
1291 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1292 (__like_t<_Self, _Pipe>(__self)._M_lhs
1295# pragma GCC diagnostic pop
1297 template<
typename _Range>
1298 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1300 operator()(_Range&& __r)
const &
1303 template<
typename _Range>
1304 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1306 operator()(_Range&& __r) &&
1309 template<
typename _Range>
1311 operator()(_Range&& __r)
const && =
delete;
1319 template<
typename _Lhs,
typename _Rhs>
1320 requires __closure_has_simple_call_op<_Lhs>
1321 && __closure_has_simple_call_op<_Rhs>
1322 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1324 [[no_unique_address]] _Lhs _M_lhs;
1325 [[no_unique_address]] _Rhs _M_rhs;
1327 template<
typename _Tp,
typename _Up>
1329 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1330 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1333 template<
typename _Range>
1334 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1336 operator()(_Range&& __r)
const
1339 static constexpr bool _S_has_simple_call_op =
true;
1343#if __cpp_lib_ranges >= 202202L
1345 template<
typename _Derived>
1346 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1347 class range_adaptor_closure
1348 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1352 template<range _Range>
requires is_object_v<_Range>
1358 static void _S_fun(_Range&);
1359 static void _S_fun(_Range&&) =
delete;
1362 template<__detail::__different_from<ref_view> _Tp>
1363 requires convertible_to<_Tp, _Range&>
1375 constexpr iterator_t<_Range>
1377 {
return ranges::begin(*_M_r); }
1379 constexpr sentinel_t<_Range>
1381 {
return ranges::end(*_M_r); }
1384 empty() const requires requires { ranges::empty(*_M_r); }
1385 {
return ranges::empty(*_M_r); }
1388 size() const requires sized_range<_Range>
1389 {
return ranges::size(*_M_r); }
1392 data() const requires contiguous_range<_Range>
1393 {
return ranges::data(*_M_r); }
1396 template<
typename _Range>
1397 ref_view(_Range&) -> ref_view<_Range>;
1399 template<
typename _Tp>
1400 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1402 template<range _Range>
1403 requires movable<_Range>
1404 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1408 _Range _M_r = _Range();
1411 owning_view()
requires default_initializable<_Range> = default;
1414 owning_view(_Range&& __t)
1415 noexcept(is_nothrow_move_constructible_v<_Range>)
1416 : _M_r(std::move(__t))
1419 owning_view(owning_view&&) =
default;
1420 owning_view& operator=(owning_view&&) =
default;
1426 constexpr const _Range&
1427 base() const& noexcept
1434 constexpr const _Range&&
1435 base() const&& noexcept
1438 constexpr iterator_t<_Range>
1440 {
return ranges::begin(_M_r); }
1442 constexpr sentinel_t<_Range>
1444 {
return ranges::end(_M_r); }
1448 {
return ranges::begin(_M_r); }
1451 end() const requires
range<const _Range>
1452 {
return ranges::end(_M_r); }
1455 empty()
requires requires { ranges::empty(_M_r); }
1456 {
return ranges::empty(_M_r); }
1459 empty() const requires requires { ranges::empty(_M_r); }
1460 {
return ranges::empty(_M_r); }
1464 {
return ranges::size(_M_r); }
1468 {
return ranges::size(_M_r); }
1472 {
return ranges::data(_M_r); }
1476 {
return ranges::data(_M_r); }
1479 template<
typename _Tp>
1480 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1481 = enable_borrowed_range<_Tp>;
1487 template<
typename _Range>
1490 template<
typename _Range>
1494 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1496 template<
typename _Range>
1497 static constexpr bool
1500 if constexpr (view<decay_t<_Range>>)
1502 else if constexpr (__detail::__can_ref_view<_Range>)
1508 template<viewable_range _Range>
1509 requires view<decay_t<_Range>>
1510 || __detail::__can_ref_view<_Range>
1511 || __detail::__can_owning_view<_Range>
1513 operator() [[nodiscard]] (_Range&& __r)
const
1514 noexcept(_S_noexcept<_Range>())
1516 if constexpr (view<decay_t<_Range>>)
1518 else if constexpr (__detail::__can_ref_view<_Range>)
1524 static constexpr bool _S_has_simple_call_op =
true;
1527 inline constexpr _All all;
1529 template<viewable_range _Range>
1535 template<
typename _Tp>
1536 struct __non_propagating_cache
1544 template<
typename _Tp>
1545 requires is_object_v<_Tp>
1546 struct __non_propagating_cache<_Tp>
1547 :
protected _Optional_base<_Tp>
1549 __non_propagating_cache() =
default;
1552 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1556 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1557 { __other._M_reset(); }
1559 constexpr __non_propagating_cache&
1560 operator=(
const __non_propagating_cache& __other)
noexcept
1567 constexpr __non_propagating_cache&
1568 operator=(__non_propagating_cache&& __other)
noexcept
1575 constexpr __non_propagating_cache&
1576 operator=(_Tp __val)
1579 this->_M_payload._M_construct(
std::move(__val));
1584 operator bool() const noexcept
1585 {
return this->_M_is_engaged(); }
1589 {
return this->_M_get(); }
1591 constexpr const _Tp&
1593 {
return this->_M_get(); }
1595 template<
typename _Iter>
1597 _M_emplace_deref(
const _Iter& __i)
1600 auto __f = [] (
auto& __x) {
return *__x; };
1601 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1602 return this->_M_get();
1605 using _Optional_base<_Tp>::_M_reset;
1608 template<range _Range>
1609 struct _CachedPosition
1612 _M_has_value()
const
1615 constexpr iterator_t<_Range>
1616 _M_get(
const _Range&)
const
1618 __glibcxx_assert(
false);
1619 __builtin_unreachable();
1623 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1627 template<forward_range _Range>
1628 struct _CachedPosition<_Range>
1629 :
protected __non_propagating_cache<iterator_t<_Range>>
1632 _M_has_value()
const
1633 {
return this->_M_is_engaged(); }
1635 constexpr iterator_t<_Range>
1636 _M_get(
const _Range&)
const
1638 __glibcxx_assert(_M_has_value());
1643 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1645 __glibcxx_assert(!_M_has_value());
1648 this->_M_payload._M_engaged =
true;
1652 template<random_access_range _Range>
1653 struct _CachedPosition<_Range>
1656 range_difference_t<_Range> _M_offset = -1;
1659 _CachedPosition() =
default;
1662 _CachedPosition(
const _CachedPosition&) =
default;
1665 _CachedPosition(_CachedPosition&& __other)
noexcept
1668 constexpr _CachedPosition&
1669 operator=(
const _CachedPosition&) =
default;
1671 constexpr _CachedPosition&
1672 operator=(_CachedPosition&& __other)
noexcept
1675 _M_offset = __other._M_offset;
1676 __other._M_offset = -1;
1681 _M_has_value()
const
1682 {
return _M_offset >= 0; }
1684 constexpr iterator_t<_Range>
1685 _M_get(_Range& __r)
const
1687 __glibcxx_assert(_M_has_value());
1688 return ranges::begin(__r) + _M_offset;
1692 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1694 __glibcxx_assert(!_M_has_value());
1695 _M_offset = __it - ranges::begin(__r);
1702 template<
typename _Base>
1703 struct __filter_view_iter_cat
1706 template<forward_range _Base>
1707 struct __filter_view_iter_cat<_Base>
1713 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1714 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1715 return bidirectional_iterator_tag{};
1716 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1717 return forward_iterator_tag{};
1722 using iterator_category =
decltype(_S_iter_cat());
1727 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1728 requires view<_Vp> && is_object_v<_Pred>
1729 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1732 template<
bool _Const>
1735 template<
bool _Const>
1736 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1739 static constexpr auto
1742 if constexpr (_Const)
1743 return input_iterator_tag{};
1744 else if constexpr (bidirectional_range<_Vp>)
1745 return bidirectional_iterator_tag{};
1746 else if constexpr (forward_range<_Vp>)
1747 return forward_iterator_tag{};
1749 return input_iterator_tag{};
1753 friend _Iterator<!_Const>;
1755 using _Parent = __maybe_const_t<_Const, filter_view>;
1756 using _Base = __maybe_const_t<_Const, _Vp>;
1757 using _Base_iter = iterator_t<_Base>;
1759 _Base_iter _M_current = _Base_iter();
1760 _Parent* _M_parent =
nullptr;
1763 using iterator_concept =
decltype(_S_iter_concept());
1765 using value_type = range_value_t<_Base>;
1766 using difference_type = range_difference_t<_Base>;
1768 _Iterator()
requires default_initializable<_Base_iter> = default;
1771 _Iterator(_Parent* __parent, _Base_iter __current)
1772 : _M_current(std::move(__current)),
1777 _Iterator(_Iterator<!_Const> __i)
1778 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
1779 : _M_current(
std::move(__i._M_current)),
1783 constexpr const _Base_iter&
1784 base() const & noexcept
1785 {
return _M_current; }
1787 constexpr _Base_iter
1791 constexpr range_reference_t<_Base>
1793 {
return *_M_current; }
1795 constexpr _Base_iter
1797 requires __detail::__has_arrow<_Base_iter>
1798 && copyable<_Base_iter>
1799 {
return _M_current; }
1801 constexpr _Iterator&
1804 _M_current = ranges::find_if(
std::move(++_M_current),
1805 ranges::end(_M_parent->_M_base),
1815 operator++(
int)
requires forward_range<_Base>
1822 constexpr _Iterator&
1823 operator--()
requires bidirectional_range<_Base>
1832 operator--(
int)
requires bidirectional_range<_Base>
1839 friend constexpr bool
1840 operator==(
const _Iterator& __x,
const _Iterator& __y)
1841 requires equality_comparable<_Base_iter>
1842 {
return __x._M_current == __y._M_current; }
1844 friend constexpr range_rvalue_reference_t<_Base>
1845 iter_move(
const _Iterator& __i)
1846 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1847 {
return ranges::iter_move(__i._M_current); }
1849 friend constexpr void
1850 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1851 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1852 requires indirectly_swappable<_Base_iter>
1853 { ranges::iter_swap(__x._M_current, __y._M_current); }
1856 template<
bool _Const>
1860 using _Parent = __maybe_const_t<_Const, filter_view>;
1861 using _Base = __maybe_const_t<_Const, _Vp>;
1862 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1864 friend _Sentinel<!_Const>;
1867 _Sentinel() =
default;
1870 _Sentinel(_Parent* __parent)
1871 : _M_end(ranges::end(__parent->_M_base))
1875 _Sentinel(_Sentinel<!_Const> __i)
1876 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1880 constexpr sentinel_t<_Base>
1884 template<
bool _Const2>
1885 requires sentinel_for<sentinel_t<_Base>,
1886 iterator_t<__maybe_const_t<_Const2, _Vp>>>
1887 friend constexpr bool
1888 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
1889 {
return __x._M_current == __y._M_end; }
1892 _Vp _M_base = _Vp();
1893 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1894 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1897 filter_view()
requires (default_initializable<_Vp>
1898 && default_initializable<_Pred>)
1902 filter_view(_Vp __base, _Pred __pred)
1903 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
1907 base() const& requires copy_constructible<_Vp>
1914 constexpr const _Pred&
1916 {
return *_M_pred; }
1918 constexpr _Iterator<false>
1921 if (_M_cached_begin._M_has_value())
1922 return {
this, _M_cached_begin._M_get(_M_base)};
1924 __glibcxx_assert(_M_pred.has_value());
1925 auto __it = ranges::find_if(ranges::begin(_M_base),
1926 ranges::end(_M_base),
1928 _M_cached_begin._M_set(_M_base, __it);
1932 constexpr _Iterator<true>
1934 requires (input_range<const _Vp> && !forward_range<const _Vp>
1935 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1937 __glibcxx_assert(_M_pred.has_value());
1938 auto __it = ranges::find_if(ranges::begin(_M_base),
1939 ranges::end(_M_base),
1947 if constexpr (common_range<_Vp>)
1948 return _Iterator<false>{
this, ranges::end(_M_base)};
1950 return _Sentinel<false>{
this};
1953 constexpr _Sentinel<true>
1955 requires (input_range<const _Vp> && !forward_range<const _Vp>
1956 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1957 {
return _Sentinel<true>{
this}; }
1960 template<
typename _Range,
typename _Pred>
1961 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1967 template<
typename _Range,
typename _Pred>
1968 concept __can_filter_view
1972 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1974 template<viewable_range _Range,
typename _Pred>
1975 requires __detail::__can_filter_view<_Range, _Pred>
1977 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1982 using _RangeAdaptor<_Filter>::operator();
1983 static constexpr int _S_arity = 2;
1984 static constexpr bool _S_has_simple_extra_args =
true;
1987 inline constexpr _Filter filter;
1990#if __cpp_lib_ranges >= 202207L
1991 template<input_range _Vp, move_constructible _Fp>
1993 template<input_range _Vp, copy_constructible _Fp>
1996 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1997 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1998 range_reference_t<_Vp>>>
1999 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
2002 template<
bool _Const>
2003 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2005 template<
bool _Const>
2009 template<
bool _Const>
2010 requires forward_range<_Base<_Const>>
2011 struct __iter_cat<_Const>
2020 using _Base = transform_view::_Base<_Const>;
2021 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2022 range_reference_t<_Base>>;
2025 if constexpr (is_reference_v<_Res>)
2028 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
2029 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
2030 return random_access_iterator_tag{};
2035 return input_iterator_tag{};
2038 using iterator_category =
decltype(_S_iter_cat());
2041 template<
bool _Const>
2044 template<
bool _Const>
2045 struct _Iterator : __iter_cat<_Const>
2048 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2049 using _Base = transform_view::_Base<_Const>;
2050 using _Base_iter = iterator_t<_Base>;
2051 using _Func_handle = __detail::__func_handle_t<
2052 __detail::__maybe_const_t<_Const, _Fp>,
2058 if constexpr (random_access_range<_Base>)
2059 return random_access_iterator_tag{};
2060 else if constexpr (bidirectional_range<_Base>)
2061 return bidirectional_iterator_tag{};
2062 else if constexpr (forward_range<_Base>)
2063 return forward_iterator_tag{};
2065 return input_iterator_tag{};
2068 _Base_iter _M_current = _Base_iter();
2069 [[no_unique_address]] _Func_handle _M_fun;
2072 using iterator_concept =
decltype(_S_iter_concept());
2075 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2076 range_reference_t<_Base>>>;
2077 using difference_type = range_difference_t<_Base>;
2079 _Iterator()
requires default_initializable<_Base_iter> = default;
2082 _Iterator(_Func_handle __fun, _Base_iter __current)
2083 : _M_current(std::move(__current)), _M_fun(__fun)
2087 _Iterator(_Parent* __parent, _Base_iter __current)
2088 : _M_current(std::move(__current)), _M_fun(*__parent->_M_fun)
2092 _Iterator(_Iterator<!_Const> __i)
2094 && convertible_to<iterator_t<_Vp>, _Base_iter>
2095 : _M_current(
std::move(__i._M_current)), _M_fun(__i._M_fun)
2098 constexpr const _Base_iter&
2099 base() const & noexcept
2100 {
return _M_current; }
2102 constexpr _Base_iter
2106 constexpr decltype(
auto)
2108 noexcept(
noexcept(_M_fun._M_call_deref(_M_current)))
2109 {
return _M_fun._M_call_deref(_M_current); }
2111 constexpr _Iterator&
2123 operator++(
int)
requires forward_range<_Base>
2130 constexpr _Iterator&
2131 operator--()
requires bidirectional_range<_Base>
2138 operator--(
int)
requires bidirectional_range<_Base>
2145 constexpr _Iterator&
2146 operator+=(difference_type __n)
requires random_access_range<_Base>
2152 constexpr _Iterator&
2153 operator-=(difference_type __n)
requires random_access_range<_Base>
2159 constexpr decltype(
auto)
2160 operator[](difference_type __n)
const
2161 requires random_access_range<_Base>
2162 {
return _M_fun._M_call_subscript(__n, _M_current); }
2164 friend constexpr bool
2165 operator==(
const _Iterator& __x,
const _Iterator& __y)
2166 requires equality_comparable<_Base_iter>
2167 {
return __x._M_current == __y._M_current; }
2169 friend constexpr bool
2170 operator<(
const _Iterator& __x,
const _Iterator& __y)
2171 requires random_access_range<_Base>
2172 {
return __x._M_current < __y._M_current; }
2174 friend constexpr bool
2175 operator>(
const _Iterator& __x,
const _Iterator& __y)
2176 requires random_access_range<_Base>
2177 {
return __y < __x; }
2179 friend constexpr bool
2180 operator<=(
const _Iterator& __x,
const _Iterator& __y)
2181 requires random_access_range<_Base>
2182 {
return !(__y < __x); }
2184 friend constexpr bool
2185 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2186 requires random_access_range<_Base>
2187 {
return !(__x < __y); }
2189#ifdef __cpp_lib_three_way_comparison
2190 friend constexpr auto
2191 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2192 requires random_access_range<_Base>
2193 && three_way_comparable<_Base_iter>
2194 {
return __x._M_current <=> __y._M_current; }
2197 friend constexpr _Iterator
2198 operator+(_Iterator __i, difference_type __n)
2199 requires random_access_range<_Base>
2200 {
return {__i._M_fun, __i._M_current + __n}; }
2202 friend constexpr _Iterator
2203 operator+(difference_type __n, _Iterator __i)
2204 requires random_access_range<_Base>
2205 {
return {__i._M_fun, __i._M_current + __n}; }
2207 friend constexpr _Iterator
2208 operator-(_Iterator __i, difference_type __n)
2209 requires random_access_range<_Base>
2210 {
return {__i._M_fun, __i._M_current - __n}; }
2214 friend constexpr difference_type
2215 operator-(
const _Iterator& __x,
const _Iterator& __y)
2216 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2217 {
return __x._M_current - __y._M_current; }
2219 friend constexpr decltype(
auto)
2220 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2222 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2228 friend _Iterator<!_Const>;
2229 template<
bool>
friend struct _Sentinel;
2232 template<
bool _Const>
2236 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2237 using _Base = transform_view::_Base<_Const>;
2239 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2242 _Sentinel() =
default;
2245 _Sentinel(sentinel_t<_Base> __end)
2250 _Sentinel(_Sentinel<!_Const> __i)
2252 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2256 constexpr sentinel_t<_Base>
2260 template<
bool _Const2>
2261 requires sentinel_for<sentinel_t<_Base>,
2262 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2263 friend constexpr bool
2264 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2265 {
return __x._M_current == __y._M_end; }
2267 template<
bool _Const2,
2268 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2269 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2270 friend constexpr range_difference_t<_Base2>
2271 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2272 {
return -(__y._M_end - __x._M_current); }
2274 template<
bool _Const2,
2275 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2276 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2277 friend constexpr range_difference_t<_Base2>
2278 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2279 {
return __y._M_end - __x._M_current; }
2281 friend _Sentinel<!_Const>;
2284 _Vp _M_base = _Vp();
2285 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2288 transform_view()
requires (default_initializable<_Vp>
2289 && default_initializable<_Fp>)
2293 transform_view(_Vp __base, _Fp __fun)
2294 : _M_base(std::move(
__base)), _M_fun(std::move(__fun))
2298 base() const& requires copy_constructible<_Vp>
2299 {
return _M_base ; }
2305 constexpr _Iterator<false>
2307 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2309 constexpr _Iterator<true>
2311 requires range<const _Vp>
2312 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2313 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2315 constexpr _Sentinel<false>
2317 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2319 constexpr _Iterator<false>
2320 end()
requires common_range<_Vp>
2321 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2323 constexpr _Sentinel<true>
2325 requires range<const _Vp>
2326 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2327 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2329 constexpr _Iterator<true>
2331 requires common_range<const _Vp>
2332 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2333 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2336 size()
requires sized_range<_Vp>
2337 {
return ranges::size(_M_base); }
2340 size() const requires sized_range<const _Vp>
2341 {
return ranges::size(_M_base); }
2344 template<
typename _Range,
typename _Fp>
2345 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2351 template<
typename _Range,
typename _Fp>
2352 concept __can_transform_view
2356 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2358 template<viewable_range _Range,
typename _Fp>
2359 requires __detail::__can_transform_view<_Range, _Fp>
2361 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2366 using _RangeAdaptor<_Transform>::operator();
2367 static constexpr int _S_arity = 2;
2368 static constexpr bool _S_has_simple_extra_args =
true;
2371 inline constexpr _Transform transform;
2378 template<
bool _Const>
2379 using _CI = counted_iterator<
2380 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2382 template<
bool _Const>
2386 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2387 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2390 _Sentinel() =
default;
2393 _Sentinel(sentinel_t<_Base> __end)
2398 _Sentinel(_Sentinel<!_Const> __s)
2399 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2403 constexpr sentinel_t<_Base>
2407 friend constexpr bool
2408 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2409 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2411 template<
bool _OtherConst = !_Const,
2412 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2413 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2414 friend constexpr bool
2415 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2416 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2418 friend _Sentinel<!_Const>;
2421 _Vp _M_base = _Vp();
2422 range_difference_t<_Vp> _M_count = 0;
2425 take_view()
requires default_initializable<_Vp> = default;
2428 take_view(_Vp __base, range_difference_t<_Vp> __count)
2429 : _M_base(std::move(__base)), _M_count(std::move(__count))
2433 base() const& requires copy_constructible<_Vp>
2441 begin()
requires (!__detail::__simple_view<_Vp>)
2443 if constexpr (sized_range<_Vp>)
2445 if constexpr (random_access_range<_Vp>)
2446 return ranges::begin(_M_base);
2450 return counted_iterator(ranges::begin(_M_base), __sz);
2454 return counted_iterator(ranges::begin(_M_base), _M_count);
2458 begin() const requires range<const _Vp>
2460 if constexpr (sized_range<const _Vp>)
2462 if constexpr (random_access_range<const _Vp>)
2463 return ranges::begin(_M_base);
2467 return counted_iterator(ranges::begin(_M_base), __sz);
2471 return counted_iterator(ranges::begin(_M_base), _M_count);
2475 end()
requires (!__detail::__simple_view<_Vp>)
2477 if constexpr (sized_range<_Vp>)
2479 if constexpr (random_access_range<_Vp>)
2480 return ranges::begin(_M_base) + size();
2485 return _Sentinel<false>{ranges::end(_M_base)};
2489 end() const requires range<const _Vp>
2491 if constexpr (sized_range<const _Vp>)
2493 if constexpr (random_access_range<const _Vp>)
2494 return ranges::begin(_M_base) + size();
2499 return _Sentinel<true>{ranges::end(_M_base)};
2503 size()
requires sized_range<_Vp>
2505 auto __n = ranges::size(_M_base);
2506 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2510 size() const requires sized_range<const _Vp>
2512 auto __n = ranges::size(_M_base);
2513 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2520 template<
typename _Range>
2521 take_view(_Range&&, range_difference_t<_Range>)
2522 -> take_view<views::all_t<_Range>>;
2524 template<
typename _Tp>
2525 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2526 = enable_borrowed_range<_Tp>;
2532 template<
typename _Range>
2533 inline constexpr bool __is_empty_view =
false;
2535 template<
typename _Tp>
2536 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2538 template<
typename _Range>
2539 inline constexpr bool __is_basic_string_view =
false;
2541 template<
typename _CharT,
typename _Traits>
2542 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2545 using ranges::__detail::__is_subrange;
2547 template<
typename _Range>
2548 inline constexpr bool __is_iota_view =
false;
2550 template<
typename _Winc,
typename _Bound>
2551 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2553 template<
typename _Range>
2554 inline constexpr bool __is_repeat_view =
false;
2556 template<
typename _Range>
2558 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2560 template<
typename _Range,
typename _Dp>
2561 concept __can_take_view
2565 struct _Take : __adaptor::_RangeAdaptor<_Take>
2567 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2568 requires __detail::__can_take_view<_Range, _Dp>
2570 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2572 using _Tp = remove_cvref_t<_Range>;
2573 if constexpr (__detail::__is_empty_view<_Tp>)
2575#ifdef __cpp_lib_optional_range_support
2576 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2579 else if constexpr (random_access_range<_Tp>
2581 && (std::__detail::__is_span<_Tp>
2582 || __detail::__is_basic_string_view<_Tp>
2583 || __detail::__is_subrange<_Tp>
2584 || __detail::__is_iota_view<_Tp>))
2587 auto __begin = ranges::begin(__r);
2588 auto __end = __begin + __n;
2589 if constexpr (std::__detail::__is_span<_Tp>)
2590 return span<typename _Tp::element_type>(__begin, __end);
2591 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2592 return _Tp(__begin, __end);
2593 else if constexpr (__detail::__is_subrange<_Tp>)
2594 return subrange<iterator_t<_Tp>>(__begin, __end);
2596 return iota_view(*__begin, *__end);
2598 else if constexpr (__detail::__is_repeat_view<_Tp>)
2604 using _RangeAdaptor<_Take>::operator();
2605 static constexpr int _S_arity = 2;
2609 template<
typename _Tp>
2610 static constexpr bool _S_has_simple_extra_args
2611 = ranges::__detail::__is_integer_like<_Tp>;
2614 inline constexpr _Take take;
2617 template<view _Vp,
typename _Pred>
2619 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2620 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2622 template<
bool _Const>
2626 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2628 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2629 const _Pred* _M_pred =
nullptr;
2632 _Sentinel() =
default;
2635 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2636 : _M_end(__end), _M_pred(__pred)
2640 _Sentinel(_Sentinel<!_Const> __s)
2641 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2642 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2645 constexpr sentinel_t<_Base>
2646 base()
const {
return _M_end; }
2648 friend constexpr bool
2649 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2650 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2652 template<
bool _OtherConst = !_Const,
2653 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2654 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2655 friend constexpr bool
2656 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2657 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2659 friend _Sentinel<!_Const>;
2662 _Vp _M_base = _Vp();
2663 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2666 take_while_view()
requires (default_initializable<_Vp>
2667 && default_initializable<_Pred>)
2671 take_while_view(_Vp __base, _Pred __pred)
2672 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2676 base() const& requires copy_constructible<_Vp>
2683 constexpr const _Pred&
2685 {
return *_M_pred; }
2688 begin()
requires (!__detail::__simple_view<_Vp>)
2689 {
return ranges::begin(_M_base); }
2692 begin() const requires range<const _Vp>
2693 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2694 {
return ranges::begin(_M_base); }
2697 end()
requires (!__detail::__simple_view<_Vp>)
2698 {
return _Sentinel<false>(ranges::end(_M_base),
2702 end() const requires range<const _Vp>
2703 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2704 {
return _Sentinel<true>(ranges::end(_M_base),
2708 template<
typename _Range,
typename _Pred>
2709 take_while_view(_Range&&, _Pred)
2710 -> take_while_view<views::all_t<_Range>, _Pred>;
2716 template<
typename _Range,
typename _Pred>
2717 concept __can_take_while_view
2721 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2723 template<viewable_range _Range,
typename _Pred>
2724 requires __detail::__can_take_while_view<_Range, _Pred>
2726 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2731 using _RangeAdaptor<_TakeWhile>::operator();
2732 static constexpr int _S_arity = 2;
2733 static constexpr bool _S_has_simple_extra_args =
true;
2736 inline constexpr _TakeWhile take_while;
2743 _Vp _M_base = _Vp();
2744 range_difference_t<_Vp> _M_count = 0;
2748 static constexpr bool _S_needs_cached_begin
2749 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2750 [[no_unique_address]]
2751 __detail::__maybe_present_t<_S_needs_cached_begin,
2752 __detail::_CachedPosition<_Vp>>
2756 drop_view()
requires default_initializable<_Vp> = default;
2759 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2760 : _M_base(std::move(__base)), _M_count(__count)
2761 { __glibcxx_assert(__count >= 0); }
2764 base() const& requires copy_constructible<_Vp>
2774 requires (!(__detail::__simple_view<_Vp>
2775 && random_access_range<const _Vp>
2776 && sized_range<const _Vp>))
2778 if constexpr (_S_needs_cached_begin)
2779 if (_M_cached_begin._M_has_value())
2780 return _M_cached_begin._M_get(_M_base);
2782 auto __it = ranges::next(ranges::begin(_M_base),
2783 _M_count, ranges::end(_M_base));
2784 if constexpr (_S_needs_cached_begin)
2785 _M_cached_begin._M_set(_M_base, __it);
2793 requires random_access_range<const _Vp> && sized_range<const _Vp>
2795 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2800 end()
requires (!__detail::__simple_view<_Vp>)
2801 {
return ranges::end(_M_base); }
2804 end() const requires range<const _Vp>
2805 {
return ranges::end(_M_base); }
2808 size()
requires sized_range<_Vp>
2810 const auto __s = ranges::size(_M_base);
2811 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2812 return __s < __c ? 0 : __s - __c;
2816 size() const requires sized_range<const _Vp>
2818 const auto __s = ranges::size(_M_base);
2819 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2820 return __s < __c ? 0 : __s - __c;
2824 template<
typename _Range>
2825 drop_view(_Range&&, range_difference_t<_Range>)
2826 -> drop_view<views::all_t<_Range>>;
2828 template<
typename _Tp>
2829 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2830 = enable_borrowed_range<_Tp>;
2836 template<
typename _Range>
2838 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2840 template<
typename _Range,
typename _Dp>
2841 concept __can_drop_view
2845 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2847 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2848 requires __detail::__can_drop_view<_Range, _Dp>
2850 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2852 using _Tp = remove_cvref_t<_Range>;
2853 if constexpr (__detail::__is_empty_view<_Tp>)
2855#ifdef __cpp_lib_optional_range_support
2856 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2859 else if constexpr (random_access_range<_Tp>
2861 && (std::__detail::__is_span<_Tp>
2862 || __detail::__is_basic_string_view<_Tp>
2863 || __detail::__is_iota_view<_Tp>
2864 || __detail::__is_subrange<_Tp>))
2867 auto __begin = ranges::begin(__r) + __n;
2868 auto __end = ranges::end(__r);
2869 if constexpr (std::__detail::__is_span<_Tp>)
2870 return span<typename _Tp::element_type>(__begin, __end);
2871 else if constexpr (__detail::__is_subrange<_Tp>)
2873 if constexpr (_Tp::_S_store_size)
2875 using ranges::__detail::__to_unsigned_like;
2876 auto __m = ranges::distance(__r) - __n;
2877 return _Tp(__begin, __end, __to_unsigned_like(__m));
2880 return _Tp(__begin, __end);
2883 return _Tp(__begin, __end);
2885 else if constexpr (__detail::__is_repeat_view<_Tp>)
2891 using _RangeAdaptor<_Drop>::operator();
2892 static constexpr int _S_arity = 2;
2893 template<
typename _Tp>
2894 static constexpr bool _S_has_simple_extra_args
2895 = _Take::_S_has_simple_extra_args<_Tp>;
2898 inline constexpr _Drop drop;
2901 template<view _Vp,
typename _Pred>
2903 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2904 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2907 _Vp _M_base = _Vp();
2908 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2909 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2912 drop_while_view()
requires (default_initializable<_Vp>
2913 && default_initializable<_Pred>)
2917 drop_while_view(_Vp __base, _Pred __pred)
2918 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2922 base() const& requires copy_constructible<_Vp>
2929 constexpr const _Pred&
2931 {
return *_M_pred; }
2936 if (_M_cached_begin._M_has_value())
2937 return _M_cached_begin._M_get(_M_base);
2939 __glibcxx_assert(_M_pred.has_value());
2940 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2941 ranges::end(_M_base),
2943 _M_cached_begin._M_set(_M_base, __it);
2949 {
return ranges::end(_M_base); }
2952 template<
typename _Range,
typename _Pred>
2953 drop_while_view(_Range&&, _Pred)
2954 -> drop_while_view<views::all_t<_Range>, _Pred>;
2956 template<
typename _Tp,
typename _Pred>
2957 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2958 = enable_borrowed_range<_Tp>;
2964 template<
typename _Range,
typename _Pred>
2965 concept __can_drop_while_view
2969 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2971 template<viewable_range _Range,
typename _Pred>
2972 requires __detail::__can_drop_while_view<_Range, _Pred>
2974 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2980 using _RangeAdaptor<_DropWhile>::operator();
2981 static constexpr int _S_arity = 2;
2982 static constexpr bool _S_has_simple_extra_args =
true;
2985 inline constexpr _DropWhile drop_while;
2990 template<
typename _Tp>
2992 __as_lvalue(_Tp&& __t)
2993 {
return static_cast<_Tp&
>(__t); }
2996 template<input_range _Vp>
3001 using _InnerRange = range_reference_t<_Vp>;
3003 template<
bool _Const>
3004 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3006 template<
bool _Const>
3007 using _Outer_iter = iterator_t<_Base<_Const>>;
3009 template<
bool _Const>
3010 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
3012 template<
bool _Const>
3013 static constexpr bool _S_ref_is_glvalue
3014 = is_reference_v<range_reference_t<_Base<_Const>>>;
3016 template<
bool _Const>
3020 template<
bool _Const>
3021 requires _S_ref_is_glvalue<_Const>
3022 && forward_range<_Base<_Const>>
3023 && forward_range<range_reference_t<_Base<_Const>>>
3024 struct __iter_cat<_Const>
3027 static constexpr auto
3030 using _Outer_iter = join_view::_Outer_iter<_Const>;
3031 using _Inner_iter = join_view::_Inner_iter<_Const>;
3032 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
3033 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
3034 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
3035 && derived_from<_InnerCat, bidirectional_iterator_tag>
3036 && common_range<range_reference_t<_Base<_Const>>>)
3037 return bidirectional_iterator_tag{};
3038 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
3039 && derived_from<_InnerCat, forward_iterator_tag>)
3040 return forward_iterator_tag{};
3042 return input_iterator_tag{};
3045 using iterator_category =
decltype(_S_iter_cat());
3048 template<
bool _Const>
3051 template<
bool _Const>
3052 struct _Iterator : __iter_cat<_Const>
3055 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3056 using _Base = join_view::_Base<_Const>;
3060 static constexpr bool _S_ref_is_glvalue
3061 = join_view::_S_ref_is_glvalue<_Const>;
3066 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
3067 if constexpr (_S_ref_is_glvalue)
3070 return _M_parent->_M_inner._M_emplace_deref(__x);
3073 _Outer_iter& __outer = _M_get_outer();
3074 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
3076 auto&& __inner = __update_inner(__outer);
3077 _M_inner = ranges::begin(__inner);
3078 if (_M_inner != ranges::end(__inner))
3082 if constexpr (_S_ref_is_glvalue)
3084 if constexpr (forward_iterator<_Inner_iter>)
3085 _M_inner = _Inner_iter();
3091 static constexpr auto
3094 if constexpr (_S_ref_is_glvalue
3095 && bidirectional_range<_Base>
3096 && bidirectional_range<range_reference_t<_Base>>
3097 && common_range<range_reference_t<_Base>>)
3098 return bidirectional_iterator_tag{};
3099 else if constexpr (_S_ref_is_glvalue
3100 && forward_range<_Base>
3101 && forward_range<range_reference_t<_Base>>)
3102 return forward_iterator_tag{};
3104 return input_iterator_tag{};
3107 using _Outer_iter = join_view::_Outer_iter<_Const>;
3108 using _Inner_iter = join_view::_Inner_iter<_Const>;
3110 constexpr _Outer_iter&
3113 if constexpr (forward_range<_Base>)
3116 return *_M_parent->_M_outer;
3119 constexpr const _Outer_iter&
3120 _M_get_outer()
const
3122 if constexpr (forward_range<_Base>)
3125 return *_M_parent->_M_outer;
3128 constexpr _Inner_iter&
3129 _M_get_inner() noexcept
3131 if constexpr (forward_iterator<_Inner_iter>)
3137 constexpr const _Inner_iter&
3138 _M_get_inner() const noexcept
3140 if constexpr (forward_iterator<_Inner_iter>)
3147 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
3148 : _M_outer(
std::move(__outer)), _M_parent(__parent)
3152 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
3153 : _M_parent(__parent)
3156 [[no_unique_address]]
3157 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
3158 =
decltype(_M_outer)();
3159 __conditional_t<forward_iterator<_Inner_iter>,
3160 _Inner_iter, optional<_Inner_iter>> _M_inner
3161 =
decltype(_M_inner)();
3162 _Parent* _M_parent =
nullptr;
3165 using iterator_concept =
decltype(_S_iter_concept());
3167 using value_type = range_value_t<range_reference_t<_Base>>;
3168 using difference_type
3170 range_difference_t<range_reference_t<_Base>>>;
3172 _Iterator() =
default;
3175 _Iterator(_Iterator<!_Const> __i)
3177 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3178 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3180 _M_parent(__i._M_parent)
3183 constexpr decltype(
auto)
3185 {
return *_M_get_inner(); }
3189 constexpr _Inner_iter
3191 requires __detail::__has_arrow<_Inner_iter>
3192 && copyable<_Inner_iter>
3193 {
return _M_get_inner(); }
3195 constexpr _Iterator&
3198 auto&& __inner_range = [
this] () ->
auto&& {
3199 if constexpr (_S_ref_is_glvalue)
3200 return *_M_get_outer();
3202 return *_M_parent->_M_inner;
3204 if (++_M_get_inner() == ranges::end(__inner_range))
3218 requires _S_ref_is_glvalue && forward_range<_Base>
3219 && forward_range<range_reference_t<_Base>>
3226 constexpr _Iterator&
3228 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3229 && bidirectional_range<range_reference_t<_Base>>
3230 && common_range<range_reference_t<_Base>>
3232 if (_M_outer == ranges::end(_M_parent->_M_base))
3233 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3234 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3235 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3242 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3243 && bidirectional_range<range_reference_t<_Base>>
3244 && common_range<range_reference_t<_Base>>
3251 friend constexpr bool
3252 operator==(
const _Iterator& __x,
const _Iterator& __y)
3253 requires _S_ref_is_glvalue
3254 && forward_range<_Base>
3255 && equality_comparable<_Inner_iter>
3257 return (__x._M_outer == __y._M_outer
3258 && __x._M_inner == __y._M_inner);
3261 friend constexpr decltype(
auto)
3262 iter_move(
const _Iterator& __i)
3263 noexcept(
noexcept(ranges::iter_move(__i._M_get_inner())))
3264 {
return ranges::iter_move(__i._M_get_inner()); }
3266 friend constexpr void
3267 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3268 noexcept(
noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3269 requires indirectly_swappable<_Inner_iter>
3270 {
return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3272 friend _Iterator<!_Const>;
3273 template<
bool>
friend struct _Sentinel;
3276 template<
bool _Const>
3280 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3281 using _Base = join_view::_Base<_Const>;
3283 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3286 _Sentinel() =
default;
3289 _Sentinel(_Parent* __parent)
3290 : _M_end(ranges::end(__parent->_M_base))
3294 _Sentinel(_Sentinel<!_Const> __s)
3295 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3299 template<
bool _Const2>
3300 requires sentinel_for<sentinel_t<_Base>,
3301 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3302 friend constexpr bool
3303 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3304 {
return __x._M_get_outer() == __y._M_end; }
3306 friend _Sentinel<!_Const>;
3309 _Vp _M_base = _Vp();
3310 [[no_unique_address]]
3311 __detail::__maybe_present_t<!forward_range<_Vp>,
3312 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3313 [[no_unique_address]]
3314 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3317 join_view()
requires default_initializable<_Vp> = default;
3320 join_view(_Vp __base)
3321 : _M_base(std::move(__base))
3325 base() const& requires copy_constructible<_Vp>
3335 if constexpr (forward_range<_Vp>)
3337 constexpr bool __use_const
3338 = (__detail::__simple_view<_Vp>
3339 && is_reference_v<range_reference_t<_Vp>>);
3340 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3344 _M_outer = ranges::begin(_M_base);
3345 return _Iterator<false>{
this};
3351 requires forward_range<const _Vp>
3352 && is_reference_v<range_reference_t<const _Vp>>
3353 && input_range<range_reference_t<const _Vp>>
3355 return _Iterator<true>{
this, ranges::begin(_M_base)};
3361 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3362 && forward_range<_InnerRange>
3363 && common_range<_Vp> && common_range<_InnerRange>)
3364 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3365 ranges::end(_M_base)};
3367 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3372 requires forward_range<const _Vp>
3373 && is_reference_v<range_reference_t<const _Vp>>
3374 && input_range<range_reference_t<const _Vp>>
3376 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3377 && forward_range<range_reference_t<const _Vp>>
3378 && common_range<const _Vp>
3379 && common_range<range_reference_t<const _Vp>>)
3380 return _Iterator<true>{
this, ranges::end(_M_base)};
3382 return _Sentinel<true>{
this};
3386 template<
typename _Range>
3387 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3393 template<
typename _Range>
3394 concept __can_join_view
3398 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3400 template<viewable_range _Range>
3401 requires __detail::__can_join_view<_Range>
3403 operator() [[nodiscard]] (_Range&& __r)
const
3410 static constexpr bool _S_has_simple_call_op =
true;
3413 inline constexpr _Join join;
3419 struct __require_constant;
3421 template<
typename _Range>
3422 concept __tiny_range = sized_range<_Range>
3424 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3425 && (remove_reference_t<_Range>::size() <= 1);
3427 template<
typename _Base>
3428 struct __lazy_split_view_outer_iter_cat
3431 template<forward_range _Base>
3432 struct __lazy_split_view_outer_iter_cat<_Base>
3433 {
using iterator_category = input_iterator_tag; };
3435 template<
typename _Base>
3436 struct __lazy_split_view_inner_iter_cat
3439 template<forward_range _Base>
3440 struct __lazy_split_view_inner_iter_cat<_Base>
3443 static constexpr auto
3446 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3447 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3448 return forward_iterator_tag{};
3453 using iterator_category =
decltype(_S_iter_cat());
3457 template<input_range _Vp, forward_range _Pattern>
3459 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3462 class lazy_split_view : public
view_interface<lazy_split_view<_Vp, _Pattern>>
3465 template<
bool _Const>
3466 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3468 template<
bool _Const>
3471 template<
bool _Const>
3473 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3476 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3477 using _Base = lazy_split_view::_Base<_Const>;
3484 __current() noexcept
3486 if constexpr (forward_range<_Vp>)
3489 return *_M_parent->_M_current;
3493 __current() const noexcept
3495 if constexpr (forward_range<_Vp>)
3498 return *_M_parent->_M_current;
3501 _Parent* _M_parent =
nullptr;
3503 [[no_unique_address]]
3504 __detail::__maybe_present_t<forward_range<_Vp>,
3505 iterator_t<_Base>> _M_current
3506 =
decltype(_M_current)();
3507 bool _M_trailing_empty =
false;
3510 using iterator_concept = __conditional_t<forward_range<_Base>,
3511 forward_iterator_tag,
3512 input_iterator_tag>;
3514 using difference_type = range_difference_t<_Base>;
3516 struct value_type : view_interface<value_type>
3519 _OuterIter _M_i = _OuterIter();
3525 value_type(_OuterIter __i)
3526 : _M_i(std::move(__i))
3532 constexpr _InnerIter<_Const>
3534 {
return _InnerIter<_Const>{_M_i}; }
3536 constexpr default_sentinel_t
3537 end() const noexcept
3541 _OuterIter() =
default;
3544 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3545 : _M_parent(__parent)
3549 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3550 requires forward_range<_Base>
3551 : _M_parent(__parent),
3556 _OuterIter(_OuterIter<!_Const> __i)
3558 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3559 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3560 _M_trailing_empty(__i._M_trailing_empty)
3563 constexpr value_type
3565 {
return value_type{*
this}; }
3567 constexpr _OuterIter&
3572 const auto __end = ranges::end(_M_parent->_M_base);
3573 if (__current() == __end)
3575 _M_trailing_empty =
false;
3578 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3579 if (__pbegin == __pend)
3581 else if constexpr (__detail::__tiny_range<_Pattern>)
3583 __current() = ranges::find(
std::move(__current()), __end,
3585 if (__current() != __end)
3588 if (__current() == __end)
3589 _M_trailing_empty =
true;
3596 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3600 if (__current() == __end)
3601 _M_trailing_empty =
true;
3604 }
while (++__current() != __end);
3608 constexpr decltype(
auto)
3611 if constexpr (forward_range<_Base>)
3621 friend constexpr bool
3622 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3623 requires forward_range<_Base>
3625 return __x._M_current == __y._M_current
3626 && __x._M_trailing_empty == __y._M_trailing_empty;
3629 friend constexpr bool
3630 operator==(
const _OuterIter& __x, default_sentinel_t)
3632 return __x.__current() == ranges::end(__x._M_parent->_M_base)
3633 && !__x._M_trailing_empty;
3636 friend _OuterIter<!_Const>;
3637 friend _InnerIter<_Const>;
3640 template<
bool _Const>
3642 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3645 using _Base = lazy_split_view::_Base<_Const>;
3650 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3651 auto __end = ranges::end(_M_i._M_parent->_M_base);
3652 if constexpr (__detail::__tiny_range<_Pattern>)
3654 const auto& __cur = _M_i_current();
3657 if (__pcur == __pend)
3658 return _M_incremented;
3659 return *__cur == *__pcur;
3663 auto __cur = _M_i_current();
3666 if (__pcur == __pend)
3667 return _M_incremented;
3670 if (*__cur != *__pcur)
3672 if (++__pcur == __pend)
3674 }
while (++__cur != __end);
3680 _M_i_current() noexcept
3681 {
return _M_i.__current(); }
3684 _M_i_current() const noexcept
3685 {
return _M_i.__current(); }
3687 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3688 bool _M_incremented =
false;
3691 using iterator_concept
3692 =
typename _OuterIter<_Const>::iterator_concept;
3694 using value_type = range_value_t<_Base>;
3695 using difference_type = range_difference_t<_Base>;
3697 _InnerIter() =
default;
3700 _InnerIter(_OuterIter<_Const> __i)
3701 : _M_i(std::move(__i))
3704 constexpr const iterator_t<_Base>&
3705 base() const& noexcept
3706 {
return _M_i_current(); }
3708 constexpr iterator_t<_Base>
3709 base() &&
requires forward_range<_Vp>
3712 constexpr decltype(
auto)
3714 {
return *_M_i_current(); }
3716 constexpr _InnerIter&
3719 _M_incremented =
true;
3720 if constexpr (!forward_range<_Base>)
3721 if constexpr (_Pattern::size() == 0)
3727 constexpr decltype(
auto)
3730 if constexpr (forward_range<_Base>)
3740 friend constexpr bool
3741 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3742 requires forward_range<_Base>
3743 {
return __x._M_i == __y._M_i; }
3745 friend constexpr bool
3746 operator==(
const _InnerIter& __x, default_sentinel_t)
3747 {
return __x.__at_end(); }
3749 friend constexpr decltype(
auto)
3750 iter_move(
const _InnerIter& __i)
3751 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3752 {
return ranges::iter_move(__i._M_i_current()); }
3754 friend constexpr void
3755 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3756 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3757 __y._M_i_current())))
3758 requires indirectly_swappable<iterator_t<_Base>>
3759 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3762 _Vp _M_base = _Vp();
3763 _Pattern _M_pattern = _Pattern();
3764 [[no_unique_address]]
3765 __detail::__maybe_present_t<!forward_range<_Vp>,
3766 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3770 lazy_split_view()
requires (default_initializable<_Vp>
3771 && default_initializable<_Pattern>)
3775 lazy_split_view(_Vp __base, _Pattern __pattern)
3776 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3779 template<input_range _Range>
3780 requires constructible_from<_Vp, views::all_t<_Range>>
3781 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3783 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3784 : _M_base(views::all(std::
forward<_Range>(__r))),
3785 _M_pattern(views::single(std::move(__e)))
3789 base() const& requires copy_constructible<_Vp>
3799 if constexpr (forward_range<_Vp>)
3801 constexpr bool __simple
3802 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3803 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3807 _M_current = ranges::begin(_M_base);
3808 return _OuterIter<false>{
this};
3816 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3817 && forward_range<const _Pattern>
3819 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3823 end()
requires forward_range<_Vp> && common_range<_Vp>
3825 constexpr bool __simple
3826 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3827 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3833 if constexpr (forward_range<_Vp>
3834 && forward_range<const _Vp>
3835 && common_range<const _Vp>
3836 && forward_range<const _Pattern>)
3837 return _OuterIter<true>{
this, ranges::end(_M_base)};
3843 template<
typename _Range,
typename _Pattern>
3844 lazy_split_view(_Range&&, _Pattern&&)
3845 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3847 template<input_range _Range>
3848 lazy_split_view(_Range&&, range_value_t<_Range>)
3855 template<
typename _Range,
typename _Pattern>
3856 concept __can_lazy_split_view
3860 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3862 template<viewable_range _Range,
typename _Pattern>
3863 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3865 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3870 using _RangeAdaptor<_LazySplit>::operator();
3871 static constexpr int _S_arity = 2;
3876 template<
typename _Pattern>
3877 static constexpr bool _S_has_simple_extra_args
3878 = is_scalar_v<_Pattern> || (view<_Pattern>
3879 && copy_constructible<_Pattern>);
3882 inline constexpr _LazySplit lazy_split;
3885 template<forward_range _Vp, forward_range _Pattern>
3887 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3889 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3892 _Vp _M_base = _Vp();
3893 _Pattern _M_pattern = _Pattern();
3894 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3900 split_view()
requires (default_initializable<_Vp>
3901 && default_initializable<_Pattern>)
3905 split_view(_Vp __base, _Pattern __pattern)
3906 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3909 template<forward_range _Range>
3910 requires constructible_from<_Vp, views::all_t<_Range>>
3911 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3913 split_view(_Range&& __r, range_value_t<_Range> __e)
3914 : _M_base(views::all(std::
forward<_Range>(__r))),
3915 _M_pattern(views::single(std::move(__e)))
3919 base() const& requires copy_constructible<_Vp>
3929 if (!_M_cached_begin)
3930 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3931 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3937 if constexpr (common_range<_Vp>)
3938 return _Iterator{
this, ranges::end(_M_base), {}};
3940 return _Sentinel{
this};
3943 constexpr subrange<iterator_t<_Vp>>
3944 _M_find_next(iterator_t<_Vp> __it)
3946 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3947 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3959 split_view* _M_parent =
nullptr;
3960 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3961 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3962 bool _M_trailing_empty =
false;
3964 friend struct _Sentinel;
3967 using iterator_concept = forward_iterator_tag;
3968 using iterator_category = input_iterator_tag;
3969 using value_type = subrange<iterator_t<_Vp>>;
3970 using difference_type = range_difference_t<_Vp>;
3972 _Iterator() =
default;
3975 _Iterator(split_view* __parent,
3976 iterator_t<_Vp> __current,
3977 subrange<iterator_t<_Vp>> __next)
3978 : _M_parent(__parent),
3979 _M_cur(std::move(__current)),
3980 _M_next(std::move(__next))
3983 constexpr iterator_t<_Vp>
3987 constexpr value_type
3989 {
return {_M_cur, _M_next.begin()}; }
3991 constexpr _Iterator&
3994 _M_cur = _M_next.begin();
3995 if (_M_cur != ranges::end(_M_parent->_M_base))
3997 _M_cur = _M_next.end();
3998 if (_M_cur == ranges::end(_M_parent->_M_base))
4000 _M_trailing_empty =
true;
4001 _M_next = {_M_cur, _M_cur};
4004 _M_next = _M_parent->_M_find_next(_M_cur);
4007 _M_trailing_empty =
false;
4019 friend constexpr bool
4020 operator==(
const _Iterator& __x,
const _Iterator& __y)
4022 return __x._M_cur == __y._M_cur
4023 && __x._M_trailing_empty == __y._M_trailing_empty;
4030 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
4033 _Sentinel() =
default;
4036 _Sentinel(split_view* __parent)
4037 : _M_end(ranges::end(__parent->_M_base))
4040 friend constexpr bool
4041 operator==(
const _Iterator& __x,
const _Sentinel& __y)
4042 {
return __x._M_cur == __y._M_end && !__x._M_trailing_empty; }
4046 template<
typename _Range,
typename _Pattern>
4047 split_view(_Range&&, _Pattern&&)
4048 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
4050 template<forward_range _Range>
4051 split_view(_Range&&, range_value_t<_Range>)
4058 template<
typename _Range,
typename _Pattern>
4059 concept __can_split_view
4063 struct _Split : __adaptor::_RangeAdaptor<_Split>
4065 template<viewable_range _Range,
typename _Pattern>
4066 requires __detail::__can_split_view<_Range, _Pattern>
4068 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
4073 using _RangeAdaptor<_Split>::operator();
4074 static constexpr int _S_arity = 2;
4075 template<
typename _Pattern>
4076 static constexpr bool _S_has_simple_extra_args
4077 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
4080 inline constexpr _Split split;
4087 template<input_or_output_iterator _Iter>
4089 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
4091 if constexpr (contiguous_iterator<_Iter>)
4093 else if constexpr (random_access_iterator<_Iter>)
4094 return subrange(__i, __i + __n);
4096 return subrange(counted_iterator(
std::move(__i), __n),
4101 inline constexpr _Counted counted{};
4109 _Vp _M_base = _Vp();
4112 common_view()
requires default_initializable<_Vp> = default;
4115 common_view(_Vp __r)
4116 : _M_base(std::move(__r))
4120 base() const& requires copy_constructible<_Vp>
4130 begin()
requires (!__detail::__simple_view<_Vp>)
4133 return ranges::begin(_M_base);
4135 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4136 (ranges::begin(_M_base));
4143 return ranges::begin(_M_base);
4145 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4146 (ranges::begin(_M_base));
4150 end()
requires (!__detail::__simple_view<_Vp>)
4153 return ranges::begin(_M_base) + ranges::size(_M_base);
4155 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4156 (ranges::end(_M_base));
4160 end() const requires
range<const _Vp>
4163 return ranges::begin(_M_base) + ranges::size(_M_base);
4165 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4166 (ranges::end(_M_base));
4171 {
return ranges::size(_M_base); }
4175 {
return ranges::size(_M_base); }
4178 template<
typename _Range>
4179 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4181 template<
typename _Tp>
4182 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4183 = enable_borrowed_range<_Tp>;
4189 template<
typename _Range>
4190 concept __already_common = common_range<_Range>
4193 template<
typename _Range>
4194 concept __can_common_view
4198 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4200 template<viewable_range _Range>
4201 requires __detail::__already_common<_Range>
4202 || __detail::__can_common_view<_Range>
4204 operator() [[nodiscard]] (_Range&& __r)
const
4206 if constexpr (__detail::__already_common<_Range>)
4212 static constexpr bool _S_has_simple_call_op =
true;
4215 inline constexpr _Common common;
4223 static constexpr bool _S_needs_cached_begin
4224 = !common_range<_Vp> && !(random_access_range<_Vp>
4225 && sized_sentinel_for<sentinel_t<_Vp>,
4228 _Vp _M_base = _Vp();
4229 [[no_unique_address]]
4230 __detail::__maybe_present_t<_S_needs_cached_begin,
4231 __detail::_CachedPosition<_Vp>>
4235 reverse_view()
requires default_initializable<_Vp> = default;
4238 reverse_view(_Vp __r)
4239 : _M_base(std::move(__r))
4243 base() const& requires copy_constructible<_Vp>
4250 constexpr reverse_iterator<iterator_t<_Vp>>
4253 if constexpr (_S_needs_cached_begin)
4254 if (_M_cached_begin._M_has_value())
4257 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4258 if constexpr (_S_needs_cached_begin)
4259 _M_cached_begin._M_set(_M_base, __it);
4264 begin()
requires common_range<_Vp>
4268 begin() const requires common_range<const _Vp>
4271 constexpr reverse_iterator<iterator_t<_Vp>>
4276 end() const requires common_range<const _Vp>
4280 size()
requires sized_range<_Vp>
4281 {
return ranges::size(_M_base); }
4284 size() const requires sized_range<const _Vp>
4285 {
return ranges::size(_M_base); }
4288 template<
typename _Range>
4289 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4291 template<
typename _Tp>
4292 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4293 = enable_borrowed_range<_Tp>;
4300 inline constexpr bool __is_reversible_subrange =
false;
4302 template<
typename _Iter, subrange_kind _Kind>
4303 inline constexpr bool
4304 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4305 reverse_iterator<_Iter>,
4309 inline constexpr bool __is_reverse_view =
false;
4311 template<
typename _Vp>
4312 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4314 template<
typename _Range>
4315 concept __can_reverse_view
4319 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4321 template<viewable_range _Range>
4322 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4323 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4324 || __detail::__can_reverse_view<_Range>
4326 operator() [[nodiscard]] (_Range&& __r)
const
4328 using _Tp = remove_cvref_t<_Range>;
4329 if constexpr (__detail::__is_reverse_view<_Tp>)
4331#ifdef __cpp_lib_optional_range_support
4332 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
4335 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4337 using _Iter =
decltype(ranges::begin(__r).base());
4338 if constexpr (sized_range<_Tp>)
4339 return subrange<_Iter, _Iter, subrange_kind::sized>
4340 {__r.end().base(), __r.begin().base(), __r.size()};
4342 return subrange<_Iter, _Iter, subrange_kind::unsized>
4343 {__r.end().base(), __r.begin().base()};
4349 static constexpr bool _S_has_simple_call_op =
true;
4352 inline constexpr _Reverse reverse;
4357#if __cpp_lib_tuple_like
4360 template<
typename _Tp,
size_t _Nm>
4361 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>
4362 &&
requires(_Tp __t)
4364 { std::get<_Nm>(__t) }
4365 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4368 template<
typename _Tp,
size_t _Nm>
4369 concept __has_tuple_element =
requires(_Tp __t)
4371 typename tuple_size<_Tp>::type;
4372 requires _Nm < tuple_size_v<_Tp>;
4373 typename tuple_element_t<_Nm, _Tp>;
4374 { std::get<_Nm>(__t) }
4375 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4379 template<
typename _Tp,
size_t _Nm>
4380 concept __returnable_element
4381 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4384 template<input_range _Vp,
size_t _Nm>
4386 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4387 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4389 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4390 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4393 elements_view()
requires default_initializable<_Vp> = default;
4396 elements_view(_Vp __base)
4397 : _M_base(std::move(__base))
4401 base() const& requires copy_constructible<_Vp>
4409 begin()
requires (!__detail::__simple_view<_Vp>)
4410 {
return _Iterator<false>(ranges::begin(_M_base)); }
4413 begin() const requires range<const _Vp>
4414 {
return _Iterator<true>(ranges::begin(_M_base)); }
4417 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4418 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4421 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4422 {
return _Iterator<false>{ranges::end(_M_base)}; }
4425 end() const requires range<const _Vp>
4426 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4429 end() const requires common_range<const _Vp>
4430 {
return _Iterator<true>{ranges::end(_M_base)}; }
4433 size()
requires sized_range<_Vp>
4434 {
return ranges::size(_M_base); }
4437 size() const requires sized_range<const _Vp>
4438 {
return ranges::size(_M_base); }
4441 template<
bool _Const>
4442 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4444 template<
bool _Const>
4448 template<
bool _Const>
4449 requires forward_range<_Base<_Const>>
4450 struct __iter_cat<_Const>
4453 static auto _S_iter_cat()
4455 using _Base = elements_view::_Base<_Const>;
4456 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4457 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4458 if constexpr (!is_lvalue_reference_v<_Res>)
4459 return input_iterator_tag{};
4460 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4461 return random_access_iterator_tag{};
4466 using iterator_category =
decltype(_S_iter_cat());
4469 template<
bool _Const>
4472 template<
bool _Const>
4473 struct _Iterator : __iter_cat<_Const>
4476 using _Base = elements_view::_Base<_Const>;
4478 iterator_t<_Base> _M_current = iterator_t<_Base>();
4480 static constexpr decltype(
auto)
4481 _S_get_element(
const iterator_t<_Base>& __i)
4483 if constexpr (is_reference_v<range_reference_t<_Base>>)
4484 return std::get<_Nm>(*__i);
4487 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4488 return static_cast<_Et
>(std::get<_Nm>(*__i));
4495 if constexpr (random_access_range<_Base>)
4496 return random_access_iterator_tag{};
4497 else if constexpr (bidirectional_range<_Base>)
4498 return bidirectional_iterator_tag{};
4499 else if constexpr (forward_range<_Base>)
4500 return forward_iterator_tag{};
4502 return input_iterator_tag{};
4505 friend _Iterator<!_Const>;
4508 using iterator_concept =
decltype(_S_iter_concept());
4511 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4512 using difference_type = range_difference_t<_Base>;
4514 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4517 _Iterator(iterator_t<_Base> __current)
4518 : _M_current(std::move(__current))
4522 _Iterator(_Iterator<!_Const> __i)
4523 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4527 constexpr const iterator_t<_Base>&
4528 base() const& noexcept
4529 {
return _M_current; }
4531 constexpr iterator_t<_Base>
4535 constexpr decltype(
auto)
4537 {
return _S_get_element(_M_current); }
4539 constexpr _Iterator&
4551 operator++(
int)
requires forward_range<_Base>
4558 constexpr _Iterator&
4559 operator--()
requires bidirectional_range<_Base>
4566 operator--(
int)
requires bidirectional_range<_Base>
4573 constexpr _Iterator&
4574 operator+=(difference_type __n)
4575 requires random_access_range<_Base>
4581 constexpr _Iterator&
4582 operator-=(difference_type __n)
4583 requires random_access_range<_Base>
4589 constexpr decltype(
auto)
4590 operator[](difference_type __n)
const
4591 requires random_access_range<_Base>
4592 {
return _S_get_element(_M_current + __n); }
4594 friend constexpr bool
4595 operator==(
const _Iterator& __x,
const _Iterator& __y)
4596 requires equality_comparable<iterator_t<_Base>>
4597 {
return __x._M_current == __y._M_current; }
4599 friend constexpr bool
4600 operator<(
const _Iterator& __x,
const _Iterator& __y)
4601 requires random_access_range<_Base>
4602 {
return __x._M_current < __y._M_current; }
4604 friend constexpr bool
4605 operator>(
const _Iterator& __x,
const _Iterator& __y)
4606 requires random_access_range<_Base>
4607 {
return __y._M_current < __x._M_current; }
4609 friend constexpr bool
4610 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4611 requires random_access_range<_Base>
4612 {
return !(__y._M_current > __x._M_current); }
4614 friend constexpr bool
4615 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4616 requires random_access_range<_Base>
4617 {
return !(__x._M_current > __y._M_current); }
4619#ifdef __cpp_lib_three_way_comparison
4620 friend constexpr auto
4621 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4622 requires random_access_range<_Base>
4623 && three_way_comparable<iterator_t<_Base>>
4624 {
return __x._M_current <=> __y._M_current; }
4627 friend constexpr _Iterator
4628 operator+(
const _Iterator& __x, difference_type __y)
4629 requires random_access_range<_Base>
4630 {
return _Iterator{__x} += __y; }
4632 friend constexpr _Iterator
4633 operator+(difference_type __x,
const _Iterator& __y)
4634 requires random_access_range<_Base>
4635 {
return __y + __x; }
4637 friend constexpr _Iterator
4638 operator-(
const _Iterator& __x, difference_type __y)
4639 requires random_access_range<_Base>
4640 {
return _Iterator{__x} -= __y; }
4644 friend constexpr difference_type
4645 operator-(
const _Iterator& __x,
const _Iterator& __y)
4646 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4647 {
return __x._M_current - __y._M_current; }
4649 template <
bool>
friend struct _Sentinel;
4652 template<
bool _Const>
4656 using _Base = elements_view::_Base<_Const>;
4657 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4660 _Sentinel() =
default;
4663 _Sentinel(sentinel_t<_Base> __end)
4664 : _M_end(std::move(__end))
4668 _Sentinel(_Sentinel<!_Const> __other)
4670 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4674 constexpr sentinel_t<_Base>
4678 template<
bool _Const2>
4679 requires sentinel_for<sentinel_t<_Base>,
4680 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4681 friend constexpr bool
4682 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4683 {
return __x._M_current == __y._M_end; }
4685 template<
bool _Const2,
4686 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4687 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4688 friend constexpr range_difference_t<_Base2>
4689 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4690 {
return -(__y._M_end - __x._M_current); }
4692 template<
bool _Const2,
4693 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4694 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4695 friend constexpr range_difference_t<_Base2>
4696 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4697 {
return __x._M_end - __y._M_current; }
4699 friend _Sentinel<!_Const>;
4702 _Vp _M_base = _Vp();
4705 template<
typename _Tp,
size_t _Nm>
4706 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4707 = enable_borrowed_range<_Tp>;
4711 template<
typename _Range>
4712 using keys_view = elements_view<_Range, 0>;
4714 template<
typename _Range>
4715 using values_view = elements_view<_Range, 1>;
4721 template<
size_t _Nm,
typename _Range>
4722 concept __can_elements_view
4726 template<
size_t _Nm>
4727 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4729 template<viewable_range _Range>
4730 requires __detail::__can_elements_view<_Nm, _Range>
4732 operator() [[nodiscard]] (_Range&& __r)
const
4737 static constexpr bool _S_has_simple_call_op =
true;
4740 template<
size_t _Nm>
4741 inline constexpr _Elements<_Nm> elements;
4742 inline constexpr auto keys = elements<0>;
4743 inline constexpr auto values = elements<1>;
4746#ifdef __cpp_lib_ranges_zip
4749 template<
typename... _Rs>
4750 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4751 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4752 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4754 template<
typename _Fp,
typename _Tuple>
4756 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4758 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4759 return tuple<invoke_result_t<_Fp&, _Ts>...>
4764 template<
typename _Fp,
typename _Tuple>
4766 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4768 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4775 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4778 tuple<_Vs...> _M_views;
4780 template<
bool>
class _Iterator;
4781 template<
bool>
class _Sentinel;
4784 zip_view() =
default;
4787 zip_view(_Vs... __views)
4788 : _M_views(std::move(__views)...)
4792 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4793 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4796 begin() const requires (
range<const _Vs> && ...)
4797 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4800 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4802 if constexpr (!__detail::__zip_is_common<_Vs...>)
4803 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4805 return begin() + iter_difference_t<_Iterator<false>>(
size());
4807 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4811 end() const requires (
range<const _Vs> && ...)
4813 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4814 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4816 return begin() + iter_difference_t<_Iterator<true>>(
size());
4818 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4824 return std::apply([](
auto... __sizes) {
4825 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4826 return ranges::min({_CT(__sizes)...});
4827 }, __detail::__tuple_transform(ranges::size, _M_views));
4833 return std::apply([](
auto... __sizes) {
4834 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4835 return ranges::min({_CT(__sizes)...});
4836 }, __detail::__tuple_transform(ranges::size, _M_views));
4840 template<
typename... _Rs>
4841 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4843 template<
typename... _Views>
4844 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4845 = (enable_borrowed_range<_Views> && ...);
4849 template<
bool _Const,
typename... _Vs>
4850 concept __all_random_access
4851 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4853 template<
bool _Const,
typename... _Vs>
4854 concept __all_bidirectional
4855 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4857 template<
bool _Const,
typename... _Vs>
4858 concept __all_forward
4859 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4861 template<
bool _Const,
typename... _Views>
4862 struct __zip_view_iter_cat
4865 template<
bool _Const,
typename... _Views>
4866 requires __all_forward<_Const, _Views...>
4867 struct __zip_view_iter_cat<_Const, _Views...>
4868 {
using iterator_category = input_iterator_tag; };
4872 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4873 template<bool _Const>
4874 class zip_view<_Vs...>::_Iterator
4875 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4877#ifdef _GLIBCXX_CLANG
4880 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4883 _Iterator(
decltype(_M_current) __current)
4884 : _M_current(std::move(__current))
4890 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4891 return random_access_iterator_tag{};
4892 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4893 return bidirectional_iterator_tag{};
4894 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4895 return forward_iterator_tag{};
4897 return input_iterator_tag{};
4900#ifndef _GLIBCXX_CLANG
4901 template<move_constructible _Fp,
input_range... _Ws>
4902 requires (
view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4903 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4904 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4905 friend class zip_transform_view;
4910 using iterator_concept =
decltype(_S_iter_concept());
4912 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4913 using difference_type
4916 _Iterator() =
default;
4919 _Iterator(_Iterator<!_Const> __i)
4921 && (convertible_to<iterator_t<_Vs>,
4922 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4923 : _M_current(std::move(__i._M_current))
4929 auto __f = [](
auto& __i) ->
decltype(
auto) {
4932 return __detail::__tuple_transform(__f, _M_current);
4935 constexpr _Iterator&
4938 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4948 requires __detail::__all_forward<_Const, _Vs...>
4955 constexpr _Iterator&
4957 requires __detail::__all_bidirectional<_Const, _Vs...>
4959 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4965 requires __detail::__all_bidirectional<_Const, _Vs...>
4972 constexpr _Iterator&
4973 operator+=(difference_type __x)
4974 requires __detail::__all_random_access<_Const, _Vs...>
4976 auto __f = [&]<
typename _It>(_It& __i) {
4977 __i += iter_difference_t<_It>(__x);
4979 __detail::__tuple_for_each(__f, _M_current);
4983 constexpr _Iterator&
4984 operator-=(difference_type __x)
4985 requires __detail::__all_random_access<_Const, _Vs...>
4987 auto __f = [&]<
typename _It>(_It& __i) {
4988 __i -= iter_difference_t<_It>(__x);
4990 __detail::__tuple_for_each(__f, _M_current);
4995 operator[](difference_type __n)
const
4996 requires __detail::__all_random_access<_Const, _Vs...>
4998 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
4999 return __i[iter_difference_t<_It>(__n)];
5001 return __detail::__tuple_transform(__f, _M_current);
5004 friend constexpr bool
5005 operator==(
const _Iterator& __x,
const _Iterator& __y)
5006 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5008 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
5009 return __x._M_current == __y._M_current;
5012 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
5016 friend constexpr auto
5017 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5018 requires __detail::__all_random_access<_Const, _Vs...>
5019 {
return __x._M_current <=> __y._M_current; }
5021 friend constexpr _Iterator
5022 operator+(
const _Iterator& __i, difference_type __n)
5023 requires __detail::__all_random_access<_Const, _Vs...>
5030 friend constexpr _Iterator
5031 operator+(difference_type __n,
const _Iterator& __i)
5032 requires __detail::__all_random_access<_Const, _Vs...>
5039 friend constexpr _Iterator
5040 operator-(
const _Iterator& __i, difference_type __n)
5041 requires __detail::__all_random_access<_Const, _Vs...>
5048 friend constexpr difference_type
5049 operator-(
const _Iterator& __x,
const _Iterator& __y)
5050 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
5051 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5054 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
5055 - std::get<_Is>(__y._M_current))...},
5057 [](difference_type __i) {
5058 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5063 friend constexpr auto
5064 iter_move(
const _Iterator& __i)
5065 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5067 friend constexpr void
5068 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5069 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5072 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
5076 friend class zip_view;
5080 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
5081 template<bool _Const>
5082 class zip_view<_Vs...>::_Sentinel
5084 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
5087 _Sentinel(
decltype(_M_end) __end)
5091 friend class zip_view;
5094 _Sentinel() =
default;
5097 _Sentinel(_Sentinel<!_Const> __i)
5099 && (convertible_to<sentinel_t<_Vs>,
5100 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5101 : _M_end(std::move(__i._M_end))
5104 template<
bool _OtherConst>
5105 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5106 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5107 friend constexpr bool
5108 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5111 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
5115 template<
bool _OtherConst>
5116 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5117 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5118 friend constexpr auto
5119 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5124 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
5127 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5132 template<
bool _OtherConst>
5133 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5134 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5135 friend constexpr auto
5136 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5137 {
return -(__x - __y); }
5144 template<
typename... _Ts>
5145 concept __can_zip_view
5151 template<
typename... _Ts>
5152 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5154 operator() [[nodiscard]] (_Ts&&... __ts)
const
5156 if constexpr (
sizeof...(_Ts) == 0)
5157 return views::empty<tuple<>>;
5163 inline constexpr _Zip zip;
5168 template<
typename _Range,
bool _Const>
5169 using __range_iter_cat
5170 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5173 template<move_constructible _Fp,
input_range... _Vs>
5174 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5175 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5176 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5177 class zip_transform_view : public
view_interface<zip_transform_view<_Fp, _Vs...>>
5179 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5180 zip_view<_Vs...> _M_zip;
5182 using _InnerView = zip_view<_Vs...>;
5184 template<
bool _Const>
5185 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5187 template<
bool _Const>
5188 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5190 template<
bool _Const>
5191 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5193 template<
bool _Const>
5197 template<
bool _Const>
5199 struct __iter_cat<_Const>
5205 using __detail::__maybe_const_t;
5206 using __detail::__range_iter_cat;
5207 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5208 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5211 if constexpr (!is_reference_v<_Res>)
5212 return input_iterator_tag{};
5213 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5214 random_access_iterator_tag> && ...))
5215 return random_access_iterator_tag{};
5216 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5217 bidirectional_iterator_tag> && ...))
5218 return bidirectional_iterator_tag{};
5219 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5220 forward_iterator_tag> && ...))
5221 return forward_iterator_tag{};
5223 return input_iterator_tag{};
5226 using iterator_category =
decltype(_S_iter_cat());
5229 template<
bool>
class _Iterator;
5230 template<
bool>
class _Sentinel;
5233 zip_transform_view() =
default;
5236 zip_transform_view(_Fp __fun, _Vs... __views)
5237 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5242 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5246 requires
range<const _InnerView>
5247 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5248 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5254 return _Iterator<false>(*
this, _M_zip.end());
5256 return _Sentinel<false>(_M_zip.end());
5261 requires
range<const _InnerView>
5262 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5265 return _Iterator<true>(*
this, _M_zip.end());
5267 return _Sentinel<true>(_M_zip.end());
5272 {
return _M_zip.size(); }
5276 {
return _M_zip.size(); }
5279 template<
class _Fp,
class... _Rs>
5280 zip_transform_view(_Fp, _Rs&&...)
5281 -> zip_transform_view<_Fp, views::all_t<_Rs>...>;
5283 template<move_constructible _Fp,
input_range... _Vs>
5284 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5285 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5286 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5287 template<bool _Const>
5288 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5290 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5291 using _Fun_handle = __detail::__func_handle_t<
5292 __detail::__maybe_const_t<_Const, _Fp>,
5293 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
5295 [[no_unique_address]] _Fun_handle _M_fun;
5296 __ziperator<_Const> _M_inner;
5299 _Iterator(_Fun_handle __fun, __ziperator<_Const> __inner)
5300 : _M_fun(__fun), _M_inner(std::move(__inner))
5304 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5305 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
5308 friend class zip_transform_view;
5312 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5314 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5315 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5316 using difference_type = range_difference_t<_Base<_Const>>;
5318 _Iterator() =
default;
5321 _Iterator(_Iterator<!_Const> __i)
5322 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5323 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
5326 constexpr decltype(
auto)
5329 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5330 return _M_fun._M_call_deref(__iters...);
5331 }, _M_inner._M_current);
5334 constexpr _Iterator&
5353 constexpr _Iterator&
5368 constexpr _Iterator&
5375 constexpr _Iterator&
5382 constexpr decltype(
auto)
5385 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5386 return _M_fun._M_call_subscript(__n, __iters...);
5387 }, _M_inner._M_current);
5390 friend constexpr bool
5391 operator==(
const _Iterator& __x,
const _Iterator& __y)
5392 requires equality_comparable<__ziperator<_Const>>
5393 {
return __x._M_inner == __y._M_inner; }
5395 friend constexpr auto
5396 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5398 {
return __x._M_inner <=> __y._M_inner; }
5400 friend constexpr _Iterator
5401 operator+(
const _Iterator& __i, difference_type __n)
5403 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5405 friend constexpr _Iterator
5406 operator+(difference_type __n,
const _Iterator& __i)
5408 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5410 friend constexpr _Iterator
5411 operator-(
const _Iterator& __i, difference_type __n)
5413 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
5415 friend constexpr difference_type
5416 operator-(
const _Iterator& __x,
const _Iterator& __y)
5417 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5418 {
return __x._M_inner - __y._M_inner; }
5421 template<move_constructible _Fp,
input_range... _Vs>
5422 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5423 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5424 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5425 template<bool _Const>
5426 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5428 __zentinel<_Const> _M_inner;
5431 _Sentinel(__zentinel<_Const> __inner)
5435 friend class zip_transform_view;
5438 _Sentinel() =
default;
5441 _Sentinel(_Sentinel<!_Const> __i)
5442 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5446 template<
bool _OtherConst>
5447 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5448 friend constexpr bool
5449 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5450 {
return __x._M_inner == __y._M_inner; }
5452 template<
bool _OtherConst>
5453 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5454 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5455 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5456 {
return __x._M_inner - __y._M_inner; }
5458 template<
bool _OtherConst>
5459 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5460 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5461 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5462 {
return __x._M_inner - __y._M_inner; }
5469 template<
typename _Fp,
typename... _Ts>
5470 concept __can_zip_transform_view
5474 struct _ZipTransform
5476 template<
typename _Fp>
5477 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5478 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5480 operator() [[nodiscard]] (_Fp&&)
const
5482 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5485 template<
typename _Fp,
typename... _Ts>
5486 requires (
sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5488 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5494 inline constexpr _ZipTransform zip_transform;
5497 template<forward_range _Vp,
size_t _Nm>
5499 class adjacent_view : public
view_interface<adjacent_view<_Vp, _Nm>>
5501 _Vp _M_base = _Vp();
5503 template<
bool>
class _Iterator;
5504 template<
bool>
class _Sentinel;
5506 struct __as_sentinel
5510 adjacent_view()
requires default_initializable<_Vp> = default;
5513 adjacent_view(_Vp __base)
5514 : _M_base(std::move(__base))
5520 base() const & requires copy_constructible<_Vp>
5528 begin()
requires (!__detail::__simple_view<_Vp>)
5529 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5533 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5536 end()
requires (!__detail::__simple_view<_Vp>)
5539 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5541 return _Sentinel<false>(ranges::end(_M_base));
5545 end() const requires
range<const _Vp>
5548 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5550 return _Sentinel<true>(ranges::end(_M_base));
5556 using _ST =
decltype(ranges::size(_M_base));
5558 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5560 return static_cast<_ST
>(__sz);
5566 using _ST =
decltype(ranges::size(_M_base));
5568 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5570 return static_cast<_ST
>(__sz);
5574 template<
typename _Vp,
size_t _Nm>
5575 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5576 = enable_borrowed_range<_Vp>;
5581 template<
typename _Tp,
size_t _Nm>
5582 using __repeated_tuple =
typename __make_tuple<array<_Tp, _Nm>>::__type;
5586 template<
typename _Fp,
size_t _Nm>
5589 template<
typename... _Ts>
5590 static invoke_result_t<_Fp, _Ts...>
5591 __tuple_apply(
const tuple<_Ts...>&);
5593 template<
typename _Tp>
5594 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5599 template<forward_range _Vp,
size_t _Nm>
5601 template<bool _Const>
5602 class adjacent_view<_Vp, _Nm>::_Iterator
5604#ifdef _GLIBCXX_CLANG
5607 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5608 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5611 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5613 for (
auto& __i : _M_current)
5616 ranges::advance(__first, 1, __last);
5621 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5624 for (
auto& __it : _M_current)
5627 for (
size_t __i = 0; __i < _Nm; ++__i)
5629 _M_current[_Nm - 1 - __i] = __last;
5630 ranges::advance(__last, -1, __first);
5638 return random_access_iterator_tag{};
5640 return bidirectional_iterator_tag{};
5642 return forward_iterator_tag{};
5645 friend class adjacent_view;
5647#ifndef _GLIBCXX_CLANG
5648 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5649 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5650 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5651 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5652 range_reference_t<_Wp>>>
5653 friend class adjacent_transform_view;
5657 using iterator_category = input_iterator_tag;
5658 using iterator_concept =
decltype(_S_iter_concept());
5659 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5660 using difference_type = range_difference_t<_Base>;
5662 _Iterator() =
default;
5665 _Iterator(_Iterator<!_Const> __i)
5666 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5668 for (
size_t __j = 0; __j < _Nm; ++__j)
5669 _M_current[__j] =
std::move(__i._M_current[__j]);
5675 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5676 return __detail::__tuple_transform(__f, _M_current);
5679 constexpr _Iterator&
5682 for (
auto& __i : _M_current)
5695 constexpr _Iterator&
5698 for (
auto& __i : _M_current)
5711 constexpr _Iterator&
5712 operator+=(difference_type __x)
5715 for (
auto& __i : _M_current)
5720 constexpr _Iterator&
5721 operator-=(difference_type __x)
5724 for (
auto& __i : _M_current)
5730 operator[](difference_type __n)
const
5733 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5734 return __detail::__tuple_transform(__f, _M_current);
5737 friend constexpr bool
5738 operator==(
const _Iterator& __x,
const _Iterator& __y)
5739 {
return __x._M_current.back() == __y._M_current.back(); }
5741 friend constexpr bool
5742 operator<(
const _Iterator& __x,
const _Iterator& __y)
5744 {
return __x._M_current.back() < __y._M_current.back(); }
5746 friend constexpr bool
5747 operator>(
const _Iterator& __x,
const _Iterator& __y)
5749 {
return __y < __x; }
5751 friend constexpr bool
5752 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5754 {
return !(__y < __x); }
5756 friend constexpr bool
5757 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5759 {
return !(__x < __y); }
5761 friend constexpr auto
5762 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5764 && three_way_comparable<iterator_t<_Base>>
5765 {
return __x._M_current.back() <=> __y._M_current.back(); }
5767 friend constexpr _Iterator
5768 operator+(
const _Iterator& __i, difference_type __n)
5776 friend constexpr _Iterator
5777 operator+(difference_type __n,
const _Iterator& __i)
5785 friend constexpr _Iterator
5786 operator-(
const _Iterator& __i, difference_type __n)
5794 friend constexpr difference_type
5795 operator-(
const _Iterator& __x,
const _Iterator& __y)
5796 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5797 {
return __x._M_current.back() - __y._M_current.back(); }
5799 friend constexpr auto
5800 iter_move(
const _Iterator& __i)
5801 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5803 friend constexpr void
5804 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5805 requires indirectly_swappable<iterator_t<_Base>>
5807 for (
size_t __i = 0; __i < _Nm; __i++)
5808 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5812 template<forward_range _Vp,
size_t _Nm>
5814 template<bool _Const>
5815 class adjacent_view<_Vp, _Nm>::_Sentinel
5817 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5819 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5822 _Sentinel(sentinel_t<_Base> __end)
5826 friend class adjacent_view;
5829 _Sentinel() =
default;
5832 _Sentinel(_Sentinel<!_Const> __i)
5833 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5837 template<
bool _OtherConst>
5838 requires sentinel_for<sentinel_t<_Base>,
5839 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5840 friend constexpr bool
5841 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5842 {
return __x._M_current.back() == __y._M_end; }
5844 template<
bool _OtherConst>
5845 requires sized_sentinel_for<sentinel_t<_Base>,
5846 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5847 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5848 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5849 {
return __x._M_current.back() - __y._M_end; }
5851 template<
bool _OtherConst>
5852 requires sized_sentinel_for<sentinel_t<_Base>,
5853 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5854 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5855 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5856 {
return __y._M_end - __x._M_current.back(); }
5863 template<
size_t _Nm,
typename _Range>
5864 concept __can_adjacent_view
5868 template<
size_t _Nm>
5869 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5873 template<viewable_range _Range>
5874 requires ((_Nm == 0) && forward_range<_Range>)
5875 || __detail::__can_adjacent_view<_Nm, _Range>
5877 operator() [[nodiscard]] (_Range&& __r)
const
5879 if constexpr (_Nm == 0)
5880 return views::empty<tuple<>>;
5886 template<
size_t _Nm>
5887 inline constexpr _Adjacent<_Nm> adjacent;
5889 inline constexpr auto pairwise = adjacent<2>;
5892 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5893 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5894 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5895 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5896 range_reference_t<_Vp>>>
5897 class adjacent_transform_view : public
view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5899 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5900 adjacent_view<_Vp, _Nm> _M_inner;
5902 using _InnerView = adjacent_view<_Vp, _Nm>;
5904 template<
bool _Const>
5905 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5907 template<
bool _Const>
5908 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5910 template<
bool>
class _Iterator;
5911 template<
bool>
class _Sentinel;
5914 adjacent_transform_view() =
default;
5917 adjacent_transform_view(_Vp __base, _Fp __fun)
5918 : _M_fun(std::move(__fun)), _M_inner(std::move(
__base))
5925 base() const & requires copy_constructible<_Vp>
5926 {
return _M_inner.base(); }
5934 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5938 requires
range<const _InnerView>
5939 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5940 range_reference_t<const _Vp>>
5941 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5947 return _Iterator<false>(*
this, _M_inner.end());
5949 return _Sentinel<false>(_M_inner.end());
5954 requires
range<const _InnerView>
5955 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5956 range_reference_t<const _Vp>>
5959 return _Iterator<true>(*
this, _M_inner.end());
5961 return _Sentinel<true>(_M_inner.end());
5966 {
return _M_inner.size(); }
5970 {
return _M_inner.size(); }
5973 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5974 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5975 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5976 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5977 range_reference_t<_Vp>>>
5978 template<bool _Const>
5979 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5981 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5982 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5984 return __detail::__func_handle_t<
5985 __detail::__maybe_const_t<_Const, _Fp>,
5986 iterator_t<__detail::__maybe_const_t<(_Ids, _Const), _Vp>>...>();
5989 [[no_unique_address]] _Fun_handle _M_fun;
5990 _InnerIter<_Const> _M_inner;
5993 _Iterator(_Fun_handle __fun, _InnerIter<_Const> __inner)
5994 : _M_fun(__fun), _M_inner(std::move(__inner))
5998 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5999 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
6005 using __detail::__maybe_const_t;
6006 using __detail::__unarize;
6007 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
6008 range_reference_t<_Base>>;
6009 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
6012 if constexpr (!is_reference_v<_Res>)
6013 return input_iterator_tag{};
6014 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
6015 return random_access_iterator_tag{};
6016 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
6017 return bidirectional_iterator_tag{};
6018 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
6019 return forward_iterator_tag{};
6021 return input_iterator_tag{};
6024 friend class adjacent_transform_view;
6027 using iterator_category =
decltype(_S_iter_cat());
6028 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
6030 = remove_cvref_t<invoke_result_t
6031 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
6032 range_reference_t<_Base>>>;
6033 using difference_type = range_difference_t<_Base>;
6035 _Iterator() =
default;
6038 _Iterator(_Iterator<!_Const> __i)
6039 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
6040 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
6043 constexpr decltype(
auto)
6046 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6047 return _M_fun._M_call_deref(__iters...);
6048 }, _M_inner._M_current);
6051 constexpr _Iterator&
6066 constexpr _Iterator&
6081 constexpr _Iterator&
6088 constexpr _Iterator&
6095 constexpr decltype(
auto)
6098 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6099 return _M_fun._M_call_subscript(__n, __iters...);
6100 }, _M_inner._M_current);
6103 friend constexpr bool
6104 operator==(
const _Iterator& __x,
const _Iterator& __y)
6105 {
return __x._M_inner == __y._M_inner; }
6107 friend constexpr bool
6108 operator<(
const _Iterator& __x,
const _Iterator& __y)
6110 {
return __x._M_inner < __y._M_inner; }
6112 friend constexpr bool
6113 operator>(
const _Iterator& __x,
const _Iterator& __y)
6115 {
return __x._M_inner > __y._M_inner; }
6117 friend constexpr bool
6118 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6120 {
return __x._M_inner <= __y._M_inner; }
6122 friend constexpr bool
6123 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6125 {
return __x._M_inner >= __y._M_inner; }
6127 friend constexpr auto
6128 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6130 three_way_comparable<_InnerIter<_Const>>
6131 {
return __x._M_inner <=> __y._M_inner; }
6133 friend constexpr _Iterator
6134 operator+(
const _Iterator& __i, difference_type __n)
6136 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6138 friend constexpr _Iterator
6139 operator+(difference_type __n,
const _Iterator& __i)
6141 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6143 friend constexpr _Iterator
6144 operator-(
const _Iterator& __i, difference_type __n)
6146 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
6148 friend constexpr difference_type
6149 operator-(
const _Iterator& __x,
const _Iterator& __y)
6150 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
6151 {
return __x._M_inner - __y._M_inner; }
6154 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6155 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6156 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6157 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6158 range_reference_t<_Vp>>>
6159 template<bool _Const>
6160 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6162 _InnerSent<_Const> _M_inner;
6165 _Sentinel(_InnerSent<_Const> __inner)
6169 friend class adjacent_transform_view;
6172 _Sentinel() =
default;
6175 _Sentinel(_Sentinel<!_Const> __i)
6176 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6180 template<
bool _OtherConst>
6181 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6182 friend constexpr bool
6183 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6184 {
return __x._M_inner == __y._M_inner; }
6186 template<
bool _OtherConst>
6187 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6188 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6189 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6190 {
return __x._M_inner - __y._M_inner; }
6192 template<
bool _OtherConst>
6193 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6194 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6195 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
6196 {
return __x._M_inner - __y._M_inner; }
6203 template<
size_t _Nm,
typename _Range,
typename _Fp>
6204 concept __can_adjacent_transform_view
6205 =
requires { adjacent_transform_view<all_t<_Range>,
decay_t<_Fp>, _Nm>
6209 template<
size_t _Nm>
6210 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6214 template<viewable_range _Range,
typename _Fp>
6215 requires ((_Nm == 0) && forward_range<_Range>)
6216 || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6218 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
6220 if constexpr (_Nm == 0)
6223 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6227 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6228 static constexpr int _S_arity = 2;
6229 static constexpr bool _S_has_simple_extra_args =
true;
6232 template<
size_t _Nm>
6233 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6235 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6239#ifdef __cpp_lib_ranges_chunk
6242 template<
typename _Tp>
6243 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6245 _Tp __r = __num / __denom;
6246 if (__num % __denom)
6257 range_difference_t<_Vp> _M_n;
6258 range_difference_t<_Vp> _M_remainder = 0;
6259 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6266 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6267 : _M_base(std::move(
__base)), _M_n(__n)
6268 { __glibcxx_assert(__n >= 0); }
6271 base() const & requires copy_constructible<_Vp>
6278 constexpr _OuterIter
6281 _M_current = ranges::begin(_M_base);
6282 _M_remainder = _M_n;
6283 return _OuterIter(*
this);
6286 constexpr default_sentinel_t
6287 end() const noexcept
6291 size()
requires sized_range<_Vp>
6293 return __detail::__to_unsigned_like(__detail::__div_ceil
6294 (ranges::distance(_M_base), _M_n));
6298 size() const requires sized_range<const _Vp>
6300 return __detail::__to_unsigned_like(__detail::__div_ceil
6301 (ranges::distance(_M_base), _M_n));
6305 template<
typename _Range>
6306 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6310 class chunk_view<_Vp>::_OuterIter
6312 chunk_view* _M_parent;
6315 _OuterIter(chunk_view& __parent) noexcept
6322 using iterator_concept = input_iterator_tag;
6323 using difference_type = range_difference_t<_Vp>;
6327 _OuterIter(_OuterIter&&) =
default;
6328 _OuterIter& operator=(_OuterIter&&) =
default;
6330 constexpr value_type
6333 __glibcxx_assert(*
this != default_sentinel);
6334 return value_type(*_M_parent);
6337 constexpr _OuterIter&
6340 __glibcxx_assert(*
this != default_sentinel);
6341 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6342 ranges::end(_M_parent->_M_base));
6343 _M_parent->_M_remainder = _M_parent->_M_n;
6351 friend constexpr bool
6352 operator==(
const _OuterIter& __x, default_sentinel_t)
6354 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6355 && __x._M_parent->_M_remainder != 0;
6358 friend constexpr difference_type
6359 operator-(default_sentinel_t,
const _OuterIter& __x)
6360 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6362 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6364 if (__dist < __x._M_parent->_M_remainder)
6365 return __dist == 0 ? 0 : 1;
6367 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6368 __x._M_parent->_M_n);
6371 friend constexpr difference_type
6372 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6373 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6374 {
return -(__y - __x); }
6379 struct chunk_view<_Vp>::_OuterIter::value_type :
view_interface<value_type>
6382 chunk_view* _M_parent;
6385 value_type(chunk_view& __parent) noexcept
6392 constexpr _InnerIter
6393 begin() const noexcept
6394 {
return _InnerIter(*_M_parent); }
6396 constexpr default_sentinel_t
6397 end() const noexcept
6402 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6404 return __detail::__to_unsigned_like
6405 (ranges::min(_M_parent->_M_remainder,
6406 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6412 class chunk_view<_Vp>::_InnerIter
6414 chunk_view* _M_parent;
6417 _InnerIter(chunk_view& __parent) noexcept
6421 friend _OuterIter::value_type;
6424 using iterator_concept = input_iterator_tag;
6425 using difference_type = range_difference_t<_Vp>;
6426 using value_type = range_value_t<_Vp>;
6428 _InnerIter(_InnerIter&&) =
default;
6429 _InnerIter& operator=(_InnerIter&&) =
default;
6431 constexpr const iterator_t<_Vp>&
6433 {
return *_M_parent->_M_current; }
6435 constexpr range_reference_t<_Vp>
6438 __glibcxx_assert(*
this != default_sentinel);
6439 return **_M_parent->_M_current;
6442 constexpr _InnerIter&
6445 __glibcxx_assert(*
this != default_sentinel);
6446 ++*_M_parent->_M_current;
6447 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6448 _M_parent->_M_remainder = 0;
6450 --_M_parent->_M_remainder;
6458 friend constexpr bool
6459 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6460 {
return __x._M_parent->_M_remainder == 0; }
6462 friend constexpr difference_type
6463 operator-(default_sentinel_t,
const _InnerIter& __x)
6464 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6466 return ranges::min(__x._M_parent->_M_remainder,
6467 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6470 friend constexpr difference_type
6471 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6472 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6473 {
return -(__y - __x); }
6477 friend constexpr range_rvalue_reference_t<_Vp>
6478 iter_move(
const _InnerIter& __i)
6479 noexcept(
noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6480 {
return ranges::iter_move(*__i._M_parent->_M_current); }
6482 friend constexpr void
6483 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
6484 noexcept(
noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6485 *__x._M_parent->_M_current)))
6486 requires indirectly_swappable<iterator_t<_Vp>>
6487 {
return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6495 range_difference_t<_Vp> _M_n;
6496 template<
bool>
class _Iterator;
6500 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6501 : _M_base(std::move(
__base)), _M_n(__n)
6502 { __glibcxx_assert(__n > 0); }
6505 base() const & requires copy_constructible<_Vp>
6513 begin()
requires (!__detail::__simple_view<_Vp>)
6514 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6517 begin() const requires forward_range<const _Vp>
6518 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6521 end()
requires (!__detail::__simple_view<_Vp>)
6523 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6525 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6526 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6528 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6529 return _Iterator<false>(
this, ranges::end(_M_base));
6535 end() const requires forward_range<const _Vp>
6537 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6539 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6540 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6542 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6543 return _Iterator<true>(
this, ranges::end(_M_base));
6549 size()
requires sized_range<_Vp>
6551 return __detail::__to_unsigned_like(__detail::__div_ceil
6552 (ranges::distance(_M_base), _M_n));
6556 size() const requires sized_range<const _Vp>
6558 return __detail::__to_unsigned_like(__detail::__div_ceil
6559 (ranges::distance(_M_base), _M_n));
6563 template<
typename _Vp>
6564 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6569 template<
bool _Const>
6570 class chunk_view<_Vp>::_Iterator
6572 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6573 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6575 iterator_t<_Base> _M_current = iterator_t<_Base>();
6576 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6577 range_difference_t<_Base> _M_n = 0;
6578 range_difference_t<_Base> _M_missing = 0;
6581 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6582 range_difference_t<_Base> __missing = 0)
6583 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6584 _M_n(__parent->_M_n), _M_missing(__missing)
6590 if constexpr (random_access_range<_Base>)
6591 return random_access_iterator_tag{};
6592 else if constexpr (bidirectional_range<_Base>)
6593 return bidirectional_iterator_tag{};
6595 return forward_iterator_tag{};
6601 using iterator_category = input_iterator_tag;
6602 using iterator_concept =
decltype(_S_iter_cat());
6603 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6604 using difference_type = range_difference_t<_Base>;
6606 _Iterator() =
default;
6608 constexpr _Iterator(_Iterator<!_Const> __i)
6610 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6611 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6613 _M_n(__i._M_n), _M_missing(__i._M_missing)
6616 constexpr iterator_t<_Base>
6618 {
return _M_current; }
6620 constexpr value_type
6623 __glibcxx_assert(_M_current != _M_end);
6624 return views::take(subrange(_M_current, _M_end), _M_n);
6627 constexpr _Iterator&
6630 __glibcxx_assert(_M_current != _M_end);
6631 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6643 constexpr _Iterator&
6644 operator--()
requires bidirectional_range<_Base>
6646 ranges::advance(_M_current, _M_missing - _M_n);
6652 operator--(
int)
requires bidirectional_range<_Base>
6659 constexpr _Iterator&
6660 operator+=(difference_type __x)
6661 requires random_access_range<_Base>
6665 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6666 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6670 ranges::advance(_M_current, _M_n * __x + _M_missing);
6676 constexpr _Iterator&
6677 operator-=(difference_type __x)
6678 requires random_access_range<_Base>
6679 {
return *
this += -__x; }
6681 constexpr value_type
6682 operator[](difference_type __n)
const
6683 requires random_access_range<_Base>
6684 {
return *(*
this + __n); }
6686 friend constexpr bool
6687 operator==(
const _Iterator& __x,
const _Iterator& __y)
6688 {
return __x._M_current == __y._M_current; }
6690 friend constexpr bool
6691 operator==(
const _Iterator& __x, default_sentinel_t)
6692 {
return __x._M_current == __x._M_end; }
6694 friend constexpr bool
6695 operator<(
const _Iterator& __x,
const _Iterator& __y)
6696 requires random_access_range<_Base>
6697 {
return __x._M_current > __y._M_current; }
6699 friend constexpr bool
6700 operator>(
const _Iterator& __x,
const _Iterator& __y)
6701 requires random_access_range<_Base>
6702 {
return __y < __x; }
6704 friend constexpr bool
6705 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6706 requires random_access_range<_Base>
6707 {
return !(__y < __x); }
6709 friend constexpr bool
6710 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6711 requires random_access_range<_Base>
6712 {
return !(__x < __y); }
6714 friend constexpr auto
6715 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6716 requires random_access_range<_Base>
6717 && three_way_comparable<iterator_t<_Base>>
6718 {
return __x._M_current <=> __y._M_current; }
6720 friend constexpr _Iterator
6721 operator+(
const _Iterator& __i, difference_type __n)
6722 requires random_access_range<_Base>
6729 friend constexpr _Iterator
6730 operator+(difference_type __n,
const _Iterator& __i)
6731 requires random_access_range<_Base>
6738 friend constexpr _Iterator
6739 operator-(
const _Iterator& __i, difference_type __n)
6740 requires random_access_range<_Base>
6747 friend constexpr difference_type
6748 operator-(
const _Iterator& __x,
const _Iterator& __y)
6749 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6751 return (__x._M_current - __y._M_current
6752 + __x._M_missing - __y._M_missing) / __x._M_n;
6755 friend constexpr difference_type
6756 operator-(default_sentinel_t,
const _Iterator& __x)
6757 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6758 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6760 friend constexpr difference_type
6761 operator-(
const _Iterator& __x, default_sentinel_t __y)
6762 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6763 {
return -(__y - __x); }
6770 template<
typename _Range,
typename _Dp>
6771 concept __can_chunk_view
6775 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6777 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6778 requires __detail::__can_chunk_view<_Range, _Dp>
6780 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6783 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6784 static constexpr int _S_arity = 2;
6785 static constexpr bool _S_has_simple_extra_args =
true;
6788 inline constexpr _Chunk chunk;
6792#ifdef __cpp_lib_ranges_slide
6795 template<
typename _Vp>
6796 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6798 template<
typename _Vp>
6799 concept __slide_caches_last
6800 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6802 template<
typename _Vp>
6803 concept __slide_caches_first
6804 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6807 template<forward_range _Vp>
6812 range_difference_t<_Vp> _M_n;
6813 [[no_unique_address]]
6814 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6815 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6816 [[no_unique_address]]
6817 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6818 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6820 template<
bool>
class _Iterator;
6825 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6826 : _M_base(std::move(
__base)), _M_n(__n)
6827 { __glibcxx_assert(__n > 0); }
6832 base() const & requires copy_constructible<_Vp>
6840 begin()
requires (!(__detail::__simple_view<_Vp>
6841 && __detail::__slide_caches_nothing<const _Vp>))
6843 if constexpr (__detail::__slide_caches_first<_Vp>)
6845 iterator_t<_Vp> __it;
6846 if (_M_cached_begin._M_has_value())
6847 __it = _M_cached_begin._M_get(_M_base);
6850 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6851 _M_cached_begin._M_set(_M_base, __it);
6853 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6856 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6860 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6861 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6864 end()
requires (!(__detail::__simple_view<_Vp>
6865 && __detail::__slide_caches_nothing<const _Vp>))
6867 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6868 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6870 else if constexpr (__detail::__slide_caches_last<_Vp>)
6872 iterator_t<_Vp> __it;
6873 if (_M_cached_end._M_has_value())
6874 __it = _M_cached_end._M_get(_M_base);
6877 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6878 _M_cached_end._M_set(_M_base, __it);
6880 return _Iterator<false>(
std::move(__it), _M_n);
6882 else if constexpr (common_range<_Vp>)
6883 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6885 return _Sentinel(ranges::end(_M_base));
6889 end() const requires __detail::__slide_caches_nothing<const _Vp>
6890 {
return begin() + range_difference_t<const _Vp>(size()); }
6893 size()
requires sized_range<_Vp>
6895 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6898 return __detail::__to_unsigned_like(__sz);
6902 size() const requires sized_range<const _Vp>
6904 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6907 return __detail::__to_unsigned_like(__sz);
6911 template<
typename _Range>
6912 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6914 template<
typename _Vp>
6915 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6916 = enable_borrowed_range<_Vp>;
6918 template<forward_range _Vp>
6920 template<
bool _Const>
6921 class slide_view<_Vp>::_Iterator
6923 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6924 static constexpr bool _S_last_elt_present
6925 = __detail::__slide_caches_first<_Base>;
6927 iterator_t<_Base> _M_current = iterator_t<_Base>();
6928 [[no_unique_address]]
6929 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6930 _M_last_elt =
decltype(_M_last_elt)();
6931 range_difference_t<_Base> _M_n = 0;
6934 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6935 requires (!_S_last_elt_present)
6936 : _M_current(__current), _M_n(__n)
6940 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6941 range_difference_t<_Base> __n)
6942 requires _S_last_elt_present
6943 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6949 if constexpr (random_access_range<_Base>)
6950 return random_access_iterator_tag{};
6951 else if constexpr (bidirectional_range<_Base>)
6952 return bidirectional_iterator_tag{};
6954 return forward_iterator_tag{};
6958 friend slide_view::_Sentinel;
6961 using iterator_category = input_iterator_tag;
6962 using iterator_concept =
decltype(_S_iter_concept());
6963 using value_type =
decltype(views::counted(_M_current, _M_n));
6964 using difference_type = range_difference_t<_Base>;
6966 _Iterator() =
default;
6969 _Iterator(_Iterator<!_Const> __i)
6970 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6971 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
6976 {
return views::counted(_M_current, _M_n); }
6978 constexpr _Iterator&
6982 if constexpr (_S_last_elt_present)
6995 constexpr _Iterator&
6996 operator--()
requires bidirectional_range<_Base>
6999 if constexpr (_S_last_elt_present)
7005 operator--(
int)
requires bidirectional_range<_Base>
7012 constexpr _Iterator&
7013 operator+=(difference_type __x)
7014 requires random_access_range<_Base>
7017 if constexpr (_S_last_elt_present)
7022 constexpr _Iterator&
7023 operator-=(difference_type __x)
7024 requires random_access_range<_Base>
7027 if constexpr (_S_last_elt_present)
7033 operator[](difference_type __n)
const
7034 requires random_access_range<_Base>
7035 {
return views::counted(_M_current + __n, _M_n); }
7037 friend constexpr bool
7038 operator==(
const _Iterator& __x,
const _Iterator& __y)
7040 if constexpr (_S_last_elt_present)
7041 return __x._M_last_elt == __y._M_last_elt;
7043 return __x._M_current == __y._M_current;
7046 friend constexpr bool
7047 operator<(
const _Iterator& __x,
const _Iterator& __y)
7048 requires random_access_range<_Base>
7049 {
return __x._M_current < __y._M_current; }
7051 friend constexpr bool
7052 operator>(
const _Iterator& __x,
const _Iterator& __y)
7053 requires random_access_range<_Base>
7054 {
return __y < __x; }
7056 friend constexpr bool
7057 operator<=(
const _Iterator& __x,
const _Iterator& __y)
7058 requires random_access_range<_Base>
7059 {
return !(__y < __x); }
7061 friend constexpr bool
7062 operator>=(
const _Iterator& __x,
const _Iterator& __y)
7063 requires random_access_range<_Base>
7064 {
return !(__x < __y); }
7066 friend constexpr auto
7067 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7068 requires random_access_range<_Base>
7069 && three_way_comparable<iterator_t<_Base>>
7070 {
return __x._M_current <=> __y._M_current; }
7072 friend constexpr _Iterator
7073 operator+(
const _Iterator& __i, difference_type __n)
7074 requires random_access_range<_Base>
7081 friend constexpr _Iterator
7082 operator+(difference_type __n,
const _Iterator& __i)
7083 requires random_access_range<_Base>
7090 friend constexpr _Iterator
7091 operator-(
const _Iterator& __i, difference_type __n)
7092 requires random_access_range<_Base>
7099 friend constexpr difference_type
7100 operator-(
const _Iterator& __x,
const _Iterator& __y)
7101 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7103 if constexpr (_S_last_elt_present)
7104 return __x._M_last_elt - __y._M_last_elt;
7106 return __x._M_current - __y._M_current;
7110 template<forward_range _Vp>
7112 class slide_view<_Vp>::_Sentinel
7114 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
7117 _Sentinel(sentinel_t<_Vp> __end)
7124 _Sentinel() =
default;
7126 friend constexpr bool
7127 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
7128 {
return __x._M_last_elt == __y._M_end; }
7130 friend constexpr range_difference_t<_Vp>
7131 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
7132 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7133 {
return __x._M_last_elt - __y._M_end; }
7135 friend constexpr range_difference_t<_Vp>
7136 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
7137 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7138 {
return __y._M_end -__x._M_last_elt; }
7145 template<
typename _Range,
typename _Dp>
7146 concept __can_slide_view
7150 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
7152 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
7153 requires __detail::__can_slide_view<_Range, _Dp>
7155 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
7158 using __adaptor::_RangeAdaptor<_Slide>::operator();
7159 static constexpr int _S_arity = 2;
7160 static constexpr bool _S_has_simple_extra_args =
true;
7163 inline constexpr _Slide slide;
7167#ifdef __cpp_lib_ranges_chunk_by
7169 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7170 requires view<_Vp> && is_object_v<_Pred>
7171 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
7173 _Vp _M_base = _Vp();
7174 __detail::__box<_Pred> _M_pred;
7175 __detail::_CachedPosition<_Vp> _M_cached_begin;
7177 constexpr iterator_t<_Vp>
7178 _M_find_next(iterator_t<_Vp> __current)
7180 __glibcxx_assert(_M_pred.has_value());
7181 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7184 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7185 return ranges::next(__it, 1, ranges::end(_M_base));
7188 constexpr iterator_t<_Vp>
7189 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
7191 __glibcxx_assert(_M_pred.has_value());
7192 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7197 __glibcxx_assert(__rbegin != __rend);
7198 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7199 return ranges::prev(__it, 1, ranges::begin(_M_base));
7205 chunk_by_view()
requires (default_initializable<_Vp>
7206 && default_initializable<_Pred>)
7210 chunk_by_view(_Vp __base, _Pred __pred)
7211 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
7215 base() const & requires copy_constructible<_Vp>
7222 constexpr const _Pred&
7224 {
return *_M_pred; }
7229 __glibcxx_assert(_M_pred.has_value());
7230 iterator_t<_Vp> __it;
7231 if (_M_cached_begin._M_has_value())
7232 __it = _M_cached_begin._M_get(_M_base);
7235 __it = _M_find_next(ranges::begin(_M_base));
7236 _M_cached_begin._M_set(_M_base, __it);
7238 return _Iterator(*
this, ranges::begin(_M_base), __it);
7244 if constexpr (common_range<_Vp>)
7245 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
7251 template<
typename _Range,
typename _Pred>
7252 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7255 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7256 requires view<_Vp> && is_object_v<_Pred>
7257 class chunk_by_view<_Vp, _Pred>::_Iterator
7259 chunk_by_view* _M_parent =
nullptr;
7260 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7261 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7264 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7265 : _M_parent(std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7271 if constexpr (bidirectional_range<_Vp>)
7272 return bidirectional_iterator_tag{};
7274 return forward_iterator_tag{};
7277 friend chunk_by_view;
7280 using value_type = subrange<iterator_t<_Vp>>;
7281 using difference_type = range_difference_t<_Vp>;
7282 using iterator_category = input_iterator_tag;
7283 using iterator_concept =
decltype(_S_iter_concept());
7285 _Iterator() =
default;
7287 constexpr value_type
7290 __glibcxx_assert(_M_current != _M_next);
7291 return ranges::subrange(_M_current, _M_next);
7294 constexpr _Iterator&
7297 __glibcxx_assert(_M_current != _M_next);
7298 _M_current = _M_next;
7299 _M_next = _M_parent->_M_find_next(_M_current);
7311 constexpr _Iterator&
7312 operator--()
requires bidirectional_range<_Vp>
7314 _M_next = _M_current;
7315 _M_current = _M_parent->_M_find_prev(_M_next);
7320 operator--(
int)
requires bidirectional_range<_Vp>
7327 friend constexpr bool
7328 operator==(
const _Iterator& __x,
const _Iterator& __y)
7329 {
return __x._M_current == __y._M_current; }
7331 friend constexpr bool
7332 operator==(
const _Iterator& __x, default_sentinel_t)
7333 {
return __x._M_current == __x._M_next; }
7340 template<
typename _Range,
typename _Pred>
7341 concept __can_chunk_by_view
7345 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7347 template<viewable_range _Range,
typename _Pred>
7348 requires __detail::__can_chunk_by_view<_Range, _Pred>
7350 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7353 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7354 static constexpr int _S_arity = 2;
7355 static constexpr bool _S_has_simple_extra_args =
true;
7358 inline constexpr _ChunkBy chunk_by;
7362#ifdef __cpp_lib_ranges_join_with
7365 template<
typename _Range,
typename _Pattern>
7366 concept __compatible_joinable_ranges
7367 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7368 && common_reference_with<range_reference_t<_Range>,
7369 range_reference_t<_Pattern>>
7370 && common_reference_with<range_rvalue_reference_t<_Range>,
7371 range_rvalue_reference_t<_Pattern>>;
7373 template<
typename _Range>
7374 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7377 template<input_range _Vp, forward_range _Pattern>
7380 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7381 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7383 using _InnerRange = range_reference_t<_Vp>;
7385 _Vp _M_base = _Vp();
7386 [[no_unique_address]]
7387 __detail::__maybe_present_t<!forward_range<_Vp>,
7388 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7389 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7390 _Pattern _M_pattern = _Pattern();
7392 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7393 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7394 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7396 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7397 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7398 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7400 template<
bool _Const>
7401 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7403 template<
bool _Const>
7407 template<
bool _Const>
7408 requires _S_ref_is_glvalue<_Const>
7409 && forward_range<_Base<_Const>>
7410 && forward_range<_InnerBase<_Const>>
7411 struct __iter_cat<_Const>
7417 using _OuterIter = join_with_view::_OuterIter<_Const>;
7418 using _InnerIter = join_with_view::_InnerIter<_Const>;
7419 using _PatternIter = join_with_view::_PatternIter<_Const>;
7420 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7421 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7422 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7425 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7426 iter_reference_t<_PatternIter>>>)
7427 return input_iterator_tag{};
7428 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7429 && derived_from<_InnerCat, bidirectional_iterator_tag>
7430 && derived_from<_PatternCat, bidirectional_iterator_tag>
7431 && common_range<_InnerBase<_Const>>
7432 && common_range<_PatternBase<_Const>>)
7433 return bidirectional_iterator_tag{};
7434 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7435 && derived_from<_InnerCat, forward_iterator_tag>
7436 && derived_from<_PatternCat, forward_iterator_tag>)
7437 return forward_iterator_tag{};
7439 return input_iterator_tag{};
7442 using iterator_category =
decltype(_S_iter_cat());
7445 template<
bool>
class _Iterator;
7446 template<
bool>
class _Sentinel;
7449 join_with_view()
requires (default_initializable<_Vp>
7450 && default_initializable<_Pattern>)
7454 join_with_view(_Vp __base, _Pattern __pattern)
7455 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
7458 template<input_range _Range>
7459 requires constructible_from<_Vp, views::all_t<_Range>>
7460 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7462 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7463 : _M_base(views::all(std::
forward<_Range>(__r))),
7464 _M_pattern(views::single(std::move(__e)))
7468 base() const& requires copy_constructible<_Vp>
7478 if constexpr (forward_range<_Vp>)
7480 constexpr bool __use_const = is_reference_v<_InnerRange>
7481 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7482 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7486 _M_outer_it = ranges::begin(_M_base);
7487 return _Iterator<false>{*
this};
7493 requires forward_range<const _Vp>
7494 && forward_range<const _Pattern>
7495 && is_reference_v<range_reference_t<const _Vp>>
7496 && input_range<range_reference_t<const _Vp>>
7497 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7502 constexpr bool __use_const
7503 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7504 if constexpr (is_reference_v<_InnerRange>
7505 && forward_range<_Vp> && common_range<_Vp>
7506 && forward_range<_InnerRange> && common_range<_InnerRange>)
7507 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7509 return _Sentinel<__use_const>{*
this};
7514 requires forward_range<const _Vp>
7515 && forward_range<const _Pattern>
7516 && is_reference_v<range_reference_t<const _Vp>>
7517 && input_range<range_reference_t<const _Vp>>
7519 using _InnerConstRange = range_reference_t<const _Vp>;
7520 if constexpr (forward_range<_InnerConstRange>
7521 && common_range<const _Vp>
7522 && common_range<_InnerConstRange>)
7523 return _Iterator<true>{*
this, ranges::end(_M_base)};
7525 return _Sentinel<true>{*
this};
7529 template<
typename _Range,
typename _Pattern>
7530 join_with_view(_Range&&, _Pattern&&)
7531 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7533 template<input_range _Range>
7534 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7535 -> join_with_view<views::all_t<_Range>,
7538 template<input_range _Vp, forward_range _Pattern>
7541 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7542 template<
bool _Const>
7543 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7545 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7546 using _Base = join_with_view::_Base<_Const>;
7547 using _InnerBase = join_with_view::_InnerBase<_Const>;
7548 using _PatternBase = join_with_view::_PatternBase<_Const>;
7550 using _OuterIter = join_with_view::_OuterIter<_Const>;
7551 using _InnerIter = join_with_view::_InnerIter<_Const>;
7552 using _PatternIter = join_with_view::_PatternIter<_Const>;
7554 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7556 _Parent* _M_parent =
nullptr;
7557 [[no_unique_address]]
7558 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7559 =
decltype(_M_outer_it)();
7560 variant<_PatternIter, _InnerIter> _M_inner_it;
7562 constexpr _OuterIter&
7565 if constexpr (forward_range<_Base>)
7568 return *_M_parent->_M_outer_it;
7571 constexpr const _OuterIter&
7572 _M_get_outer()
const
7574 if constexpr (forward_range<_Base>)
7577 return *_M_parent->_M_outer_it;
7581 _Iterator(_Parent& __parent, _OuterIter __outer)
7582 requires forward_range<_Base>
7585 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7587 auto&& __inner = _M_update_inner();
7588 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7594 _Iterator(_Parent& __parent)
7595 requires (!forward_range<_Base>)
7598 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7600 auto&& __inner = _M_update_inner();
7601 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7609 _OuterIter& __outer = _M_get_outer();
7610 if constexpr (_S_ref_is_glvalue)
7611 return __detail::__as_lvalue(*__outer);
7613 return _M_parent->_M_inner._M_emplace_deref(__outer);
7619 if constexpr (_S_ref_is_glvalue)
7620 return __detail::__as_lvalue(*_M_get_outer());
7622 return *_M_parent->_M_inner;
7630 if (_M_inner_it.index() == 0)
7632 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7635 auto&& __inner = _M_update_inner();
7636 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7640 auto&& __inner = _M_get_inner();
7641 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7644 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7646 if constexpr (_S_ref_is_glvalue)
7647 _M_inner_it.template emplace<0>();
7651 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7659 if constexpr (_S_ref_is_glvalue
7660 && bidirectional_range<_Base>
7661 && __detail::__bidirectional_common<_InnerBase>
7662 && __detail::__bidirectional_common<_PatternBase>)
7663 return bidirectional_iterator_tag{};
7664 else if constexpr (_S_ref_is_glvalue
7665 && forward_range<_Base>
7666 && forward_range<_InnerBase>)
7667 return forward_iterator_tag{};
7669 return input_iterator_tag{};
7672 friend join_with_view;
7675 using iterator_concept =
decltype(_S_iter_concept());
7677 using value_type = common_type_t<iter_value_t<_InnerIter>,
7678 iter_value_t<_PatternIter>>;
7679 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7680 iter_difference_t<_InnerIter>,
7681 iter_difference_t<_PatternIter>>;
7683 _Iterator() =
default;
7686 _Iterator(_Iterator<!_Const> __i)
7688 && convertible_to<iterator_t<_Vp>, _OuterIter>
7689 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7690 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7691 : _M_parent(__i._M_parent),
7694 if (__i._M_inner_it.index() == 0)
7695 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7697 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7700 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7701 iter_reference_t<_PatternIter>>
7704 if (_M_inner_it.index() == 0)
7705 return *std::get<0>(_M_inner_it);
7707 return *std::get<1>(_M_inner_it);
7710 constexpr _Iterator&
7713 if (_M_inner_it.index() == 0)
7714 ++std::get<0>(_M_inner_it);
7716 ++std::get<1>(_M_inner_it);
7727 requires _S_ref_is_glvalue
7728 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7730 _Iterator __tmp = *
this;
7735 constexpr _Iterator&
7737 requires _S_ref_is_glvalue
7738 && bidirectional_range<_Base>
7739 && __detail::__bidirectional_common<_InnerBase>
7740 && __detail::__bidirectional_common<_PatternBase>
7742 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7744 auto&& __inner = *--_M_outer_it;
7745 _M_inner_it.template emplace<1>(ranges::end(__inner));
7750 if (_M_inner_it.index() == 0)
7752 auto& __it = std::get<0>(_M_inner_it);
7753 if (__it == ranges::begin(_M_parent->_M_pattern))
7755 auto&& __inner = *--_M_outer_it;
7756 _M_inner_it.template emplace<1>(ranges::end(__inner));
7763 auto& __it = std::get<1>(_M_inner_it);
7764 auto&& __inner = *_M_outer_it;
7765 if (__it == ranges::begin(__inner))
7766 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7772 if (_M_inner_it.index() == 0)
7773 --std::get<0>(_M_inner_it);
7775 --std::get<1>(_M_inner_it);
7781 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7782 && __detail::__bidirectional_common<_InnerBase>
7783 && __detail::__bidirectional_common<_PatternBase>
7785 _Iterator __tmp = *
this;
7790 friend constexpr bool
7791 operator==(
const _Iterator& __x,
const _Iterator& __y)
7792 requires _S_ref_is_glvalue
7793 && forward_range<_Base> && equality_comparable<_InnerIter>
7794 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7796 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7797 iter_rvalue_reference_t<_PatternIter>>
7798 iter_move(
const _Iterator& __x)
7800 if (__x._M_inner_it.index() == 0)
7801 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7803 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7806 friend constexpr void
7807 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7808 requires indirectly_swappable<_InnerIter, _PatternIter>
7810 if (__x._M_inner_it.index() == 0)
7812 if (__y._M_inner_it.index() == 0)
7813 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7815 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7819 if (__y._M_inner_it.index() == 0)
7820 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7822 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7827 template<input_range _Vp, forward_range _Pattern>
7830 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7831 template<
bool _Const>
7832 class join_with_view<_Vp, _Pattern>::_Sentinel
7834 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7835 using _Base = join_with_view::_Base<_Const>;
7837 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7840 _Sentinel(_Parent& __parent)
7841 : _M_end(ranges::end(__parent._M_base))
7844 friend join_with_view;
7847 _Sentinel() =
default;
7850 _Sentinel(_Sentinel<!_Const> __s)
7851 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7855 template<
bool _OtherConst>
7856 requires sentinel_for<sentinel_t<_Base>,
7857 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7858 friend constexpr bool
7859 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7860 {
return __x._M_get_outer() == __y._M_end; }
7867 template<
typename _Range,
typename _Pattern>
7868 concept __can_join_with_view
7872 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7874 template<viewable_range _Range,
typename _Pattern>
7875 requires __detail::__can_join_with_view<_Range, _Pattern>
7877 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7882 using _RangeAdaptor<_JoinWith>::operator();
7883 static constexpr int _S_arity = 2;
7884 template<
typename _Pattern>
7885 static constexpr bool _S_has_simple_extra_args
7886 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7889 inline constexpr _JoinWith join_with;
7893#ifdef __cpp_lib_ranges_repeat
7894 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7895 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7896 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7897 class repeat_view : public
view_interface<repeat_view<_Tp, _Bound>>
7899 [[no_unique_address]] __detail::__box<_Tp> _M_value;
7900 [[no_unique_address]] _Bound _M_bound = _Bound();
7904 template<
typename _Range>
7905 friend constexpr auto
7906 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7908 template<
typename _Range>
7909 friend constexpr auto
7910 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7913 repeat_view()
requires default_initializable<_Tp> = default;
7916 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7917 requires copy_constructible<_Tp>
7918 : _M_value(__value), _M_bound(__bound)
7920 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7921 __glibcxx_assert(__bound >= 0);
7925 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7926 : _M_value(std::move(__value)), _M_bound(__bound)
7929 template<
typename... _Args,
typename... _BoundArgs>
7930 requires constructible_from<_Tp, _Args...>
7931 && constructible_from<_Bound, _BoundArgs...>
7933 repeat_view(piecewise_construct_t,
7934 tuple<_Args...> __args,
7935 tuple<_BoundArgs...> __bound_args = tuple<>{})
7936 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7937 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7945 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7948 constexpr unreachable_sentinel_t
7949 end() const noexcept
7950 {
return unreachable_sentinel; }
7953 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7954 {
return __detail::__to_unsigned_like(_M_bound); }
7959 template<
typename _Tp,
typename _Bound = unreachable_sentinel_t>
7960 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7962 template<move_constructible _Tp, semiregular _Bound>
7963 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7964 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7965 class repeat_view<_Tp, _Bound>::_Iterator
7968 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7970 const _Tp* _M_value =
nullptr;
7971 __index_type _M_current = __index_type();
7974 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
7975 : _M_value(__value), _M_current(__bound)
7977 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7978 __glibcxx_assert(__bound >= 0);
7984 using iterator_concept = random_access_iterator_tag;
7985 using iterator_category = random_access_iterator_tag;
7986 using value_type = _Tp;
7987 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7989 __detail::__iota_diff_t<__index_type>>;
7991 _Iterator() =
default;
7993 constexpr const _Tp&
7995 {
return *_M_value; }
7997 constexpr _Iterator&
8012 constexpr _Iterator&
8015 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8016 __glibcxx_assert(_M_current > 0);
8029 constexpr _Iterator&
8030 operator+=(difference_type __n)
8032 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8033 __glibcxx_assert(_M_current + __n >= 0);
8038 constexpr _Iterator&
8039 operator-=(difference_type __n)
8041 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8042 __glibcxx_assert(_M_current - __n >= 0);
8047 constexpr const _Tp&
8048 operator[](difference_type __n)
const noexcept
8049 {
return *(*
this + __n); }
8051 friend constexpr bool
8052 operator==(
const _Iterator& __x,
const _Iterator& __y)
8053 {
return __x._M_current == __y._M_current; }
8055 friend constexpr auto
8056 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8057 {
return __x._M_current <=> __y._M_current; }
8059 friend constexpr _Iterator
8060 operator+(_Iterator __i, difference_type __n)
8066 friend constexpr _Iterator
8067 operator+(difference_type __n, _Iterator __i)
8068 {
return __i + __n; }
8070 friend constexpr _Iterator
8071 operator-(_Iterator __i, difference_type __n)
8077 friend constexpr difference_type
8078 operator-(
const _Iterator& __x,
const _Iterator& __y)
8080 return (
static_cast<difference_type
>(__x._M_current)
8081 -
static_cast<difference_type
>(__y._M_current));
8089 template<
typename _Tp,
typename _Bound>
8090 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
8092 template<
typename _Tp>
8093 concept __can_repeat_view
8096 template<
typename _Tp,
typename _Bound>
8097 concept __can_bounded_repeat_view
8103 template<
typename _Tp>
8104 requires __detail::__can_repeat_view<_Tp>
8106 operator() [[nodiscard]] (_Tp&& __value)
const
8113 template<
typename _Tp,
typename _Bound>
8114 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
8116 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
8120 inline constexpr _Repeat repeat;
8124 template<
typename _Range>
8126 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8128 using _Tp = remove_cvref_t<_Range>;
8129 static_assert(__is_repeat_view<_Tp>);
8130 if constexpr (sized_range<_Tp>)
8132 std::min(ranges::distance(__r), __n));
8137 template<
typename _Range>
8139 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8141 using _Tp = remove_cvref_t<_Range>;
8142 static_assert(__is_repeat_view<_Tp>);
8143 if constexpr (sized_range<_Tp>)
8145 auto __sz = ranges::distance(__r);
8156#ifdef __cpp_lib_ranges_stride
8157 template<input_range _Vp>
8162 range_difference_t<_Vp> _M_stride;
8164 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8166 template<
bool _Const>
8170 template<
bool _Const>
8171 requires forward_range<_Base<_Const>>
8172 struct __iter_cat<_Const>
8178 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8179 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8180 return random_access_iterator_tag{};
8185 using iterator_category =
decltype(_S_iter_cat());
8188 template<
bool>
class _Iterator;
8192 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8193 : _M_base(std::move(
__base)), _M_stride(__stride)
8194 { __glibcxx_assert(__stride > 0); }
8197 base() const& requires copy_constructible<_Vp>
8204 constexpr range_difference_t<_Vp>
8205 stride() const noexcept
8206 {
return _M_stride; }
8209 begin()
requires (!__detail::__simple_view<_Vp>)
8210 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
8213 begin() const requires range<const _Vp>
8214 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
8217 end()
requires (!__detail::__simple_view<_Vp>)
8219 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8221 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8222 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
8224 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8225 return _Iterator<false>(
this, ranges::end(_M_base));
8231 end() const requires range<const _Vp>
8233 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8234 && forward_range<const _Vp>)
8236 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8237 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
8239 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8240 return _Iterator<true>(
this, ranges::end(_M_base));
8246 size()
requires sized_range<_Vp>
8248 return __detail::__to_unsigned_like
8249 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8253 size() const requires sized_range<const _Vp>
8255 return __detail::__to_unsigned_like
8256 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8260 template<
typename _Range>
8261 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8263 template<
typename _Vp>
8264 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8265 = enable_borrowed_range<_Vp>;
8267 template<input_range _Vp>
8269 template<
bool _Const>
8270 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8272 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8273 using _Base = stride_view::_Base<_Const>;
8275 iterator_t<_Base> _M_current = iterator_t<_Base>();
8276 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8277 range_difference_t<_Base> _M_stride = 0;
8278 range_difference_t<_Base> _M_missing = 0;
8281 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8282 range_difference_t<_Base> __missing = 0)
8283 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8284 _M_stride(__parent->_M_stride), _M_missing(__missing)
8290 if constexpr (random_access_range<_Base>)
8291 return random_access_iterator_tag{};
8292 else if constexpr (bidirectional_range<_Base>)
8293 return bidirectional_iterator_tag{};
8294 else if constexpr (forward_range<_Base>)
8295 return forward_iterator_tag{};
8297 return input_iterator_tag{};
8303 using difference_type = range_difference_t<_Base>;
8304 using value_type = range_value_t<_Base>;
8305 using iterator_concept =
decltype(_S_iter_concept());
8308 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8311 _Iterator(_Iterator<!_Const> __other)
8313 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8314 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8315 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8316 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8319 constexpr iterator_t<_Base>
8323 constexpr const iterator_t<_Base>&
8324 base() const & noexcept
8325 {
return _M_current; }
8327 constexpr decltype(
auto)
8329 {
return *_M_current; }
8331 constexpr _Iterator&
8334 __glibcxx_assert(_M_current != _M_end);
8335 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8344 operator++(
int)
requires forward_range<_Base>
8351 constexpr _Iterator&
8352 operator--()
requires bidirectional_range<_Base>
8354 ranges::advance(_M_current, _M_missing - _M_stride);
8360 operator--(
int)
requires bidirectional_range<_Base>
8367 constexpr _Iterator&
8368 operator+=(difference_type __n)
requires random_access_range<_Base>
8372 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8373 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8377 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8383 constexpr _Iterator&
8384 operator-=(difference_type __n)
requires random_access_range<_Base>
8385 {
return *
this += -__n; }
8387 constexpr decltype(
auto)
operator[](difference_type __n)
const
8388 requires random_access_range<_Base>
8389 {
return *(*
this + __n); }
8391 friend constexpr bool
8392 operator==(
const _Iterator& __x, default_sentinel_t)
8393 {
return __x._M_current == __x._M_end; }
8395 friend constexpr bool
8396 operator==(
const _Iterator& __x,
const _Iterator& __y)
8397 requires equality_comparable<iterator_t<_Base>>
8398 {
return __x._M_current == __y._M_current; }
8400 friend constexpr bool
8401 operator<(
const _Iterator& __x,
const _Iterator& __y)
8402 requires random_access_range<_Base>
8403 {
return __x._M_current < __y._M_current; }
8405 friend constexpr bool
8406 operator>(
const _Iterator& __x,
const _Iterator& __y)
8407 requires random_access_range<_Base>
8408 {
return __y._M_current < __x._M_current; }
8410 friend constexpr bool
8411 operator<=(
const _Iterator& __x,
const _Iterator& __y)
8412 requires random_access_range<_Base>
8413 {
return !(__y._M_current < __x._M_current); }
8415 friend constexpr bool
8416 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8417 requires random_access_range<_Base>
8418 {
return !(__x._M_current < __y._M_current); }
8420 friend constexpr auto
8421 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8422 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8423 {
return __x._M_current <=> __y._M_current; }
8425 friend constexpr _Iterator
8426 operator+(
const _Iterator& __i, difference_type __n)
8427 requires random_access_range<_Base>
8434 friend constexpr _Iterator
8435 operator+(difference_type __n,
const _Iterator& __i)
8436 requires random_access_range<_Base>
8437 {
return __i + __n; }
8439 friend constexpr _Iterator
8440 operator-(
const _Iterator& __i, difference_type __n)
8441 requires random_access_range<_Base>
8448 friend constexpr difference_type
8449 operator-(
const _Iterator& __x,
const _Iterator& __y)
8450 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8452 auto __n = __x._M_current - __y._M_current;
8453 if constexpr (forward_range<_Base>)
8454 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8456 return -__detail::__div_ceil(-__n, __x._M_stride);
8458 return __detail::__div_ceil(__n, __x._M_stride);
8461 friend constexpr difference_type
8462 operator-(default_sentinel_t,
const _Iterator& __x)
8463 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8464 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8466 friend constexpr difference_type
8467 operator-(
const _Iterator& __x, default_sentinel_t __y)
8468 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8469 {
return -(__y - __x); }
8471 friend constexpr range_rvalue_reference_t<_Base>
8472 iter_move(
const _Iterator& __i)
8473 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8474 {
return ranges::iter_move(__i._M_current); }
8476 friend constexpr void
8477 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8478 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8479 requires indirectly_swappable<iterator_t<_Base>>
8480 { ranges::iter_swap(__x._M_current, __y._M_current); }
8487 template<
typename _Range,
typename _Dp>
8488 concept __can_stride_view
8492 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8494 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8495 requires __detail::__can_stride_view<_Range, _Dp>
8497 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8500 using __adaptor::_RangeAdaptor<_Stride>::operator();
8501 static constexpr int _S_arity = 2;
8502 static constexpr bool _S_has_simple_extra_args =
true;
8505 inline constexpr _Stride stride;
8509#ifdef __cpp_lib_ranges_cartesian_product
8512 template<
bool _Const,
typename _First,
typename... _Vs>
8513 concept __cartesian_product_is_random_access
8514 = (random_access_range<__maybe_const_t<_Const, _First>>
8516 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8517 && sized_range<__maybe_const_t<_Const, _Vs>>));
8519 template<
typename _Range>
8520 concept __cartesian_product_common_arg
8521 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8523 template<
bool _Const,
typename _First,
typename... _Vs>
8524 concept __cartesian_product_is_bidirectional
8525 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8527 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8528 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8530 template<
typename _First,
typename... _Vs>
8531 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8533 template<
typename... _Vs>
8534 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8536 template<
bool _Const,
template<
typename>
class _FirstSent,
8537 typename _First,
typename... _Vs>
8538 concept __cartesian_is_sized_sentinel
8539 = (sized_sentinel_for<_FirstSent<__maybe_const_t<_Const, _First>>,
8540 iterator_t<__maybe_const_t<_Const, _First>>>
8542 && (sized_range<__maybe_const_t<_Const, _Vs>>
8543 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8544 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8546 template<__cartesian_product_common_arg _Range>
8548 __cartesian_common_arg_end(_Range& __r)
8550 if constexpr (common_range<_Range>)
8551 return ranges::end(__r);
8553 return ranges::begin(__r) + ranges::distance(__r);
8559 class cartesian_product_view : public
view_interface<cartesian_product_view<_First, _Vs...>>
8561 tuple<_First, _Vs...> _M_bases;
8563 template<
bool>
class _Iterator;
8566 _S_difference_type()
8572 range_difference_t<_First>,
8573 range_difference_t<_Vs>...>{};
8577 cartesian_product_view() =
default;
8580 cartesian_product_view(_First __first, _Vs... __rest)
8581 : _M_bases(std::move(__first), std::move(__rest)...)
8584 constexpr _Iterator<false>
8585 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8586 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8588 constexpr _Iterator<true>
8589 begin() const requires (
range<const _First> && ... &&
range<const _Vs>)
8590 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8592 constexpr _Iterator<false>
8593 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8594 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8597 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8598 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8599 auto& __first = std::get<0>(_M_bases);
8600 return _Ret{(__empty_tail
8601 ? ranges::begin(__first)
8602 : __detail::__cartesian_common_arg_end(__first)),
8603 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8606 return _Iterator<false>{*
this,
std::move(__its)};
8609 constexpr _Iterator<true>
8610 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8613 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8614 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8615 auto& __first = std::get<0>(_M_bases);
8616 return _Ret{(__empty_tail
8617 ? ranges::begin(__first)
8618 : __detail::__cartesian_common_arg_end(__first)),
8619 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8622 return _Iterator<true>{*
this,
std::move(__its)};
8625 constexpr default_sentinel_t
8626 end() const noexcept
8630 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8632 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8634 auto __size =
static_cast<_ST
>(1);
8635#ifdef _GLIBCXX_ASSERTIONS
8636 if constexpr (integral<_ST>)
8639 = (__builtin_mul_overflow(__size,
8640 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8643 __glibcxx_assert(!__overflow);
8647 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8653 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8655 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8657 auto __size =
static_cast<_ST
>(1);
8658#ifdef _GLIBCXX_ASSERTIONS
8659 if constexpr (integral<_ST>)
8662 = (__builtin_mul_overflow(__size,
8663 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8666 __glibcxx_assert(!__overflow);
8670 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8676 template<
typename... _Vs>
8677 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8681 template<bool _Const>
8682 class cartesian_product_view<_First, _Vs...>::_Iterator
8684 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8685 _Parent* _M_parent =
nullptr;
8686 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8687 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8690 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8692 _M_current(std::move(__current))
8698 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8699 return random_access_iterator_tag{};
8700 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8701 return bidirectional_iterator_tag{};
8703 return forward_iterator_tag{};
8705 return input_iterator_tag{};
8708 friend cartesian_product_view;
8711 using iterator_category = input_iterator_tag;
8712 using iterator_concept =
decltype(_S_iter_concept());
8714 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8715 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8717 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8718 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8719 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8721 _Iterator() =
default;
8724 _Iterator(_Iterator<!_Const> __i)
8726 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8727 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8729 _M_current(std::move(__i._M_current))
8735 auto __f = [](
auto& __i) ->
decltype(
auto) {
8738 return __detail::__tuple_transform(__f, _M_current);
8741 constexpr _Iterator&
8760 constexpr _Iterator&
8762 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8770 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8777 constexpr _Iterator&
8778 operator+=(difference_type __x)
8779 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8785 constexpr _Iterator&
8786 operator-=(difference_type __x)
8787 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8788 {
return *
this += -__x; }
8791 operator[](difference_type __n)
const
8792 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8793 {
return *((*this) + __n); }
8795 friend constexpr bool
8796 operator==(
const _Iterator& __x,
const _Iterator& __y)
8797 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8798 {
return __x._M_current == __y._M_current; }
8800 friend constexpr bool
8801 operator==(
const _Iterator& __x, default_sentinel_t)
8804 return ((std::get<_Is>(__x._M_current)
8805 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8810 friend constexpr auto
8811 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8812 requires __detail::__all_random_access<_Const, _First, _Vs...>
8813 {
return __x._M_current <=> __y._M_current; }
8815 friend constexpr _Iterator
8816 operator+(_Iterator __x, difference_type __y)
8817 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8818 {
return __x += __y; }
8820 friend constexpr _Iterator
8821 operator+(difference_type __x, _Iterator __y)
8822 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8823 {
return __y += __x; }
8825 friend constexpr _Iterator
8826 operator-(_Iterator __x, difference_type __y)
8827 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8828 {
return __x -= __y; }
8830 friend constexpr difference_type
8831 operator-(
const _Iterator& __x,
const _Iterator& __y)
8832 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8833 {
return __x._M_distance_from(__y._M_current); }
8835 friend constexpr difference_type
8836 operator-(
const _Iterator& __i, default_sentinel_t)
8837 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8840 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8841 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8843 return __i._M_distance_from(__end_tuple);
8846 friend constexpr difference_type
8847 operator-(default_sentinel_t,
const _Iterator& __i)
8848 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8851 friend constexpr auto
8852 iter_move(
const _Iterator& __i)
8853 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8855 friend constexpr void
8856 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8857 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8859 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8862 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8867 template<
size_t _Nm =
sizeof...(_Vs)>
8871 auto& __it = std::get<_Nm>(_M_current);
8873 if constexpr (_Nm > 0)
8874 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8876 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8881 template<
size_t _Nm =
sizeof...(_Vs)>
8885 auto& __it = std::get<_Nm>(_M_current);
8886 if constexpr (_Nm > 0)
8887 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8889 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8895 template<
size_t _Nm =
sizeof...(_Vs)>
8897 _M_advance(difference_type __x)
8898 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8907 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8908 auto& __it = std::get<_Nm>(_M_current);
8909 if constexpr (_Nm == 0)
8911#ifdef _GLIBCXX_ASSERTIONS
8914 auto __size = ranges::ssize(__r);
8915 auto __begin = ranges::begin(__r);
8916 auto __offset = __it - __begin;
8917 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8924 auto __size = ranges::ssize(__r);
8925 auto __begin = ranges::begin(__r);
8926 auto __offset = __it - __begin;
8928 __x = __offset / __size;
8932 __offset = __size + __offset;
8935 __it = __begin + __offset;
8936 _M_advance<_Nm - 1>(__x);
8941 template<
typename _Tuple>
8942 constexpr difference_type
8943 _M_distance_from(
const _Tuple& __t)
const
8946 auto __sum =
static_cast<difference_type
>(0);
8947#ifdef _GLIBCXX_ASSERTIONS
8948 if constexpr (integral<difference_type>)
8951 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8953 __glibcxx_assert(!__overflow);
8957 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8962 template<
size_t _Nm,
typename _Tuple>
8963 constexpr difference_type
8964 _M_scaled_distance(
const _Tuple& __t)
const
8966 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8967 - std::get<_Nm>(__t));
8968#ifdef _GLIBCXX_ASSERTIONS
8969 if constexpr (integral<difference_type>)
8971 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8972 __glibcxx_assert(!__overflow);
8976 __dist *= _M_scaled_size<_Nm+1>();
8980 template<
size_t _Nm>
8981 constexpr difference_type
8982 _M_scaled_size()
const
8984 if constexpr (_Nm <=
sizeof...(_Vs))
8986 auto __size =
static_cast<difference_type
>(ranges::size
8987 (std::get<_Nm>(_M_parent->_M_bases)));
8988#ifdef _GLIBCXX_ASSERTIONS
8989 if constexpr (integral<difference_type>)
8991 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8992 __glibcxx_assert(!__overflow);
8996 __size *= _M_scaled_size<_Nm+1>();
9000 return static_cast<difference_type
>(1);
9008 template<
typename... _Ts>
9009 concept __can_cartesian_product_view
9013 struct _CartesianProduct
9015 template<
typename... _Ts>
9016 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
9018 operator() [[nodiscard]] (_Ts&&... __ts)
const
9020 if constexpr (
sizeof...(_Ts) == 0)
9021 return views::single(tuple{});
9027 inline constexpr _CartesianProduct cartesian_product;
9031#ifdef __cpp_lib_ranges_as_rvalue
9032 template<input_range _Vp>
9034 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
9036 _Vp _M_base = _Vp();
9039 as_rvalue_view()
requires default_initializable<_Vp> = default;
9042 as_rvalue_view(_Vp __base)
9043 : _M_base(std::move(__base))
9047 base() const& requires copy_constructible<_Vp>
9055 begin()
requires (!__detail::__simple_view<_Vp>)
9056 {
return move_iterator(ranges::begin(_M_base)); }
9059 begin() const requires range<const _Vp>
9060 {
return move_iterator(ranges::begin(_M_base)); }
9063 end()
requires (!__detail::__simple_view<_Vp>)
9065 if constexpr (common_range<_Vp>)
9066 return move_iterator(ranges::end(_M_base));
9068 return move_sentinel(ranges::end(_M_base));
9072 end() const requires range<const _Vp>
9074 if constexpr (common_range<const _Vp>)
9075 return move_iterator(ranges::end(_M_base));
9077 return move_sentinel(ranges::end(_M_base));
9081 size()
requires sized_range<_Vp>
9082 {
return ranges::size(_M_base); }
9085 size() const requires sized_range<const _Vp>
9086 {
return ranges::size(_M_base); }
9089 template<
typename _Range>
9090 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
9092 template<
typename _Tp>
9093 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
9094 = enable_borrowed_range<_Tp>;
9100 template<
typename _Tp>
9101 concept __can_as_rvalue_view =
requires { as_rvalue_view(
std::declval<_Tp>()); };
9104 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
9106 template<viewable_range _Range>
9107 requires __detail::__can_as_rvalue_view<_Range>
9109 operator() [[nodiscard]] (_Range&& __r)
const
9114 if constexpr (same_as<range_rvalue_reference_t<_Range>,
9115 range_reference_t<_Range>>)
9122 inline constexpr _AsRvalue as_rvalue;
9126#ifdef __cpp_lib_ranges_enumerate
9129 template<
typename _Range>
9130 concept __range_with_movable_reference = input_range<_Range>
9131 && move_constructible<range_reference_t<_Range>>
9132 && move_constructible<range_rvalue_reference_t<_Range>>;
9136 requires __detail::__range_with_movable_reference<_Vp>
9137 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
9139 _Vp _M_base = _Vp();
9141 template<
bool _Const>
class _Iterator;
9142 template<
bool _Const>
class _Sentinel;
9145 enumerate_view()
requires default_initializable<_Vp> = default;
9148 enumerate_view(_Vp __base)
9149 : _M_base(std::move(__base))
9153 begin()
requires (!__detail::__simple_view<_Vp>)
9154 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
9157 begin() const requires __detail::__range_with_movable_reference<const _Vp>
9158 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
9161 end()
requires (!__detail::__simple_view<_Vp>)
9163 if constexpr (common_range<_Vp> && sized_range<_Vp>)
9164 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
9166 return _Sentinel<false>(ranges::end(_M_base));
9170 end() const requires __detail::__range_with_movable_reference<const _Vp>
9172 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9173 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9175 return _Sentinel<true>(ranges::end(_M_base));
9179 size()
requires sized_range<_Vp>
9180 {
return ranges::size(_M_base); }
9183 size() const requires sized_range<const _Vp>
9184 {
return ranges::size(_M_base); }
9187 base() const & requires copy_constructible<_Vp>
9195 template<
typename _Range>
9196 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9198 template<
typename _Tp>
9199 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9200 = enable_borrowed_range<_Tp>;
9203 requires __detail::__range_with_movable_reference<_Vp>
9204 template<
bool _Const>
9205 class enumerate_view<_Vp>::_Iterator
9207 using _Base = __maybe_const_t<_Const, _Vp>;
9212 if constexpr (random_access_range<_Base>)
9213 return random_access_iterator_tag{};
9214 else if constexpr (bidirectional_range<_Base>)
9215 return bidirectional_iterator_tag{};
9216 else if constexpr (forward_range<_Base>)
9217 return forward_iterator_tag{};
9219 return input_iterator_tag{};
9222 friend enumerate_view;
9225 using iterator_category = input_iterator_tag;
9226 using iterator_concept =
decltype(_S_iter_concept());
9227 using difference_type = range_difference_t<_Base>;
9228 using value_type = tuple<difference_type, range_value_t<_Base>>;
9231 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9233 iterator_t<_Base> _M_current = iterator_t<_Base>();
9234 difference_type _M_pos = 0;
9237 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9238 : _M_current(std::move(__current)), _M_pos(__pos)
9242 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
9245 _Iterator(_Iterator<!_Const> __i)
9246 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9247 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9250 constexpr const iterator_t<_Base> &
9251 base() const & noexcept
9252 {
return _M_current; }
9254 constexpr iterator_t<_Base>
9258 constexpr difference_type
9259 index() const noexcept
9264 {
return __reference_type(_M_pos, *_M_current); }
9266 constexpr _Iterator&
9279 operator++(
int)
requires forward_range<_Base>
9286 constexpr _Iterator&
9287 operator--()
requires bidirectional_range<_Base>
9295 operator--(
int)
requires bidirectional_range<_Base>
9302 constexpr _Iterator&
9303 operator+=(difference_type __n)
requires random_access_range<_Base>
9310 constexpr _Iterator&
9311 operator-=(difference_type __n)
requires random_access_range<_Base>
9319 operator[](difference_type __n)
const requires random_access_range<_Base>
9320 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9322 friend constexpr bool
9323 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9324 {
return __x._M_pos == __y._M_pos; }
9326 friend constexpr strong_ordering
9327 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9328 {
return __x._M_pos <=> __y._M_pos; }
9330 friend constexpr _Iterator
9331 operator+(
const _Iterator& __x, difference_type __y)
9332 requires random_access_range<_Base>
9333 {
return (
auto(__x) += __y); }
9335 friend constexpr _Iterator
9336 operator+(difference_type __x,
const _Iterator& __y)
9337 requires random_access_range<_Base>
9338 {
return auto(__y) += __x; }
9340 friend constexpr _Iterator
9341 operator-(
const _Iterator& __x, difference_type __y)
9342 requires random_access_range<_Base>
9343 {
return auto(__x) -= __y; }
9345 friend constexpr difference_type
9346 operator-(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9347 {
return __x._M_pos - __y._M_pos; }
9349 friend constexpr auto
9350 iter_move(
const _Iterator& __i)
9351 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9352 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9354 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9355 (__i._M_pos, ranges::iter_move(__i._M_current));
9360 requires __detail::__range_with_movable_reference<_Vp>
9361 template<
bool _Const>
9362 class enumerate_view<_Vp>::_Sentinel
9364 using _Base = __maybe_const_t<_Const, _Vp>;
9366 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9369 _Sentinel(sentinel_t<_Base> __end)
9370 : _M_end(std::move(__end))
9373 friend enumerate_view;
9376 _Sentinel() =
default;
9379 _Sentinel(_Sentinel<!_Const> __other)
9380 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9384 constexpr sentinel_t<_Base>
9388 template<
bool _OtherConst>
9389 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9390 friend constexpr bool
9391 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9392 {
return __x._M_current == __y._M_end; }
9394 template<
bool _OtherConst>
9395 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9396 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9397 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9398 {
return __x._M_current - __y._M_end; }
9400 template<
bool _OtherConst>
9401 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9402 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9403 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9404 {
return __x._M_end - __y._M_current; }
9411 template<
typename _Tp>
9412 concept __can_enumerate_view
9416 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9418 template<viewable_range _Range>
9419 requires __detail::__can_enumerate_view<_Range>
9421 operator() [[nodiscard]] (_Range&& __r)
const
9425 inline constexpr _Enumerate enumerate;
9429#ifdef __cpp_lib_ranges_as_const
9434 _Vp _M_base = _Vp();
9437 as_const_view()
requires default_initializable<_Vp> = default;
9440 as_const_view(_Vp __base)
9441 noexcept(is_nothrow_move_constructible_v<_Vp>)
9442 : _M_base(std::move(__base))
9447 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9448 requires copy_constructible<_Vp>
9453 noexcept(is_nothrow_move_constructible_v<_Vp>)
9457 begin()
requires (!__detail::__simple_view<_Vp>)
9458 {
return ranges::cbegin(_M_base); }
9461 begin() const requires range<const _Vp>
9462 {
return ranges::cbegin(_M_base); }
9465 end()
requires (!__detail::__simple_view<_Vp>)
9466 {
return ranges::cend(_M_base); }
9469 end() const requires range<const _Vp>
9470 {
return ranges::cend(_M_base); }
9473 size()
requires sized_range<_Vp>
9474 {
return ranges::size(_M_base); }
9477 size() const requires sized_range<const _Vp>
9478 {
return ranges::size(_M_base); }
9481 template<
typename _Range>
9482 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9484 template<
typename _Tp>
9485 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9486 = enable_borrowed_range<_Tp>;
9492 template<
typename _Tp>
9493 inline constexpr bool __is_constable_ref_view =
false;
9495 template<
typename _Range>
9496 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9497 = constant_range<const _Range>;
9499 template<
typename _Range>
9503 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9505 template<viewable_range _Range>
9507 operator()(_Range&& __r)
const
9509 requires __detail::__can_as_const_view<_Range>
9511 using _Tp = remove_cvref_t<_Range>;
9512 using element_type = remove_reference_t<range_reference_t<_Range>>;
9513 if constexpr (constant_range<views::all_t<_Range>>)
9515 else if constexpr (__detail::__is_empty_view<_Tp>)
9516 return views::empty<const element_type>;
9517#if __cpp_lib_optional >= 202506L && __cpp_lib_optional_range_support
9518 else if constexpr (__is_optional_ref_v<_Tp>)
9519 return optional<const typename _Tp::value_type&>(__r);
9521 else if constexpr (std::__detail::__is_span<_Tp>)
9523 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9525 else if constexpr (is_lvalue_reference_v<_Range>
9526 && constant_range<const _Tp>
9528 return ref_view(
static_cast<const _Tp&
>(__r));
9534 inline constexpr _AsConst as_const;
9539 namespace views = ranges::views;
9541#if __cpp_lib_ranges_to_container
9547 template<
typename _Container>
9548 constexpr bool __reservable_container
9549 = sized_range<_Container>
9550 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9552 { __c.capacity() } -> same_as<
decltype(__n)>;
9553 { __c.max_size() } -> same_as<
decltype(__n)>;
9556 template<
typename _Cont,
typename _Range>
9557 constexpr bool __toable =
requires {
9558 requires (!input_range<_Cont>
9559 || convertible_to<range_reference_t<_Range>,
9560 range_value_t<_Cont>>);
9581 template<
typename _Cont, input_range _Rg,
typename... _Args>
9582 requires (!view<_Cont>)
9584 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9586 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9587 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9589 if constexpr (__detail::__toable<_Cont, _Rg>)
9591 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9594 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9597 else if constexpr (
requires {
requires common_range<_Rg>;
9598 typename __iter_category_t<iterator_t<_Rg>>;
9599 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9600 input_iterator_tag>;
9601 requires constructible_from<_Cont, iterator_t<_Rg>,
9602 sentinel_t<_Rg>, _Args...>;
9604 return _Cont(ranges::begin(__r), ranges::end(__r),
9608 static_assert(constructible_from<_Cont, _Args...>);
9610 if constexpr (sized_range<_Rg>
9611 && __detail::__reservable_container<_Cont>)
9612 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9616 auto __it = ranges::begin(__r);
9617 const auto __sent = ranges::end(__r);
9618 while (__it != __sent)
9620 if constexpr (
requires { __c.emplace_back(*__it); })
9621 __c.emplace_back(*__it);
9622 else if constexpr (
requires { __c.push_back(*__it); })
9623 __c.push_back(*__it);
9624 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9625 __c.emplace(__c.end(), *__it);
9627 __c.insert(__c.end(), *__it);
9635 static_assert(input_range<range_reference_t<_Rg>>);
9638 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9639 []<
typename _Elt>(_Elt&& __elem) {
9640 using _ValT = range_value_t<_Cont>;
9649 template<
typename _Rg>
9652 using iterator_category = input_iterator_tag;
9653 using value_type = range_value_t<_Rg>;
9654 using difference_type = ptrdiff_t;
9655 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9656 using reference = range_reference_t<_Rg>;
9658 pointer operator->()
const;
9659 _InputIter& operator++();
9660 _InputIter operator++(
int);
9661 bool operator==(
const _InputIter&)
const;
9664 template<
template<
typename...>
typename _Cont, input_range _Rg,
9669 template<
template<
typename...>
typename _Cont, input_range _Rg,
9675 template<
template<
typename...>
typename _Cont, input_range _Rg,
9685 template<
template<
typename...>
typename _Cont, input_range _Rg,
9688 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9690 using __detail::_DeduceExpr1;
9691 using __detail::_DeduceExpr2;
9692 using __detail::_DeduceExpr3;
9693 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9694 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9696 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9697 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9699 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9700 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9703 static_assert(
false);
9709 template<
typename _Cont>
9712 template<
typename _Range,
typename... _Args>
9716 operator()(_Range&& __r, _Args&&... __args)
const
9740 template<
typename _Cont,
typename... _Args>
9741 requires (!view<_Cont>)
9743 to [[nodiscard]] (_Args&&... __args)
9745 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9746 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9748 using __detail::_To;
9749 using views::__adaptor::_Partial;
9756 template<
template<
typename...>
typename _Cont>
9759 template<
typename _Range,
typename... _Args>
9763 operator()(_Range&& __r, _Args&&... __args)
const
9789 template<
template<
typename...>
typename _Cont,
typename... _Args>
9791 to [[nodiscard]] (_Args&&... __args)
9793 using __detail::_To2;
9794 using views::__adaptor::_Partial;
9801#if __cpp_lib_ranges_concat
9806 template<
typename... _Rs>
9807 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9809 template<
typename... _Rs>
9810 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9812 template<
typename... _Rs>
9813 using __concat_rvalue_reference_t
9814 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9816 template<
typename _Ref,
typename _RRef,
typename _It>
9817 concept __concat_indirectly_readable_impl =
requires(
const _It __it) {
9818 { *__it } -> convertible_to<_Ref>;
9819 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9822 template<
typename... _Rs>
9823 concept __concat_indirectly_readable
9824 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9825 && common_reference_with<__concat_reference_t<_Rs...>&&,
9826 __concat_rvalue_reference_t<_Rs...>&&>
9827 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9828 __concat_value_t<_Rs...>
const&>
9829 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9830 __concat_rvalue_reference_t<_Rs...>,
9834 template<
typename... _Rs>
9835 concept __concatable =
requires {
9836 typename __concat_reference_t<_Rs...>;
9837 typename __concat_value_t<_Rs...>;
9838 typename __concat_rvalue_reference_t<_Rs...>;
9839 } && __concat_indirectly_readable<_Rs...>;
9841 template<
bool _Const,
typename _Range,
typename... _Rs>
9842 struct __all_but_last_common
9844 static inline constexpr bool value
9845 =
requires {
requires (common_range<__maybe_const_t<_Const, _Range>>
9846 && __all_but_last_common<_Const, _Rs...>::value); };
9849 template<
bool _Const,
typename _Range>
9850 struct __all_but_last_common<_Const, _Range>
9851 {
static inline constexpr bool value =
true; };
9853 template<
bool _Const,
typename... _Rs>
9854 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9855 && __all_but_last_common<_Const, _Rs...>::value;
9857 template<
bool _Const,
typename... _Rs>
9858 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9859 && __all_but_last_common<_Const, _Rs...>::value;
9861 template<
typename _Range,
typename... _Rs>
9862 struct __all_but_first_sized
9863 {
static inline constexpr bool value = (sized_range<_Rs> && ...); };
9866 template<input_range... _Vs>
9867 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9868 class concat_view : public view_interface<concat_view<_Vs...>>
9870 tuple<_Vs...> _M_views;
9872 template<
bool _Const>
class _Iterator;
9875 constexpr concat_view() =
default;
9878 concat_view(_Vs... __views)
9879 : _M_views(std::move(__views)...)
9882 constexpr _Iterator<false>
9883 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
9885 _Iterator<false> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9886 __it.template _M_satisfy<0>();
9890 constexpr _Iterator<true>
9891 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9893 _Iterator<true> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9894 __it.template _M_satisfy<0>();
9899 end()
requires (!(__detail::__simple_view<_Vs> && ...))
9901 constexpr auto __n =
sizeof...(_Vs);
9902 if constexpr (__detail::__all_forward<
false, _Vs...>
9903 && common_range<_Vs...[__n - 1]>)
9904 return _Iterator<false>(
this, in_place_index<__n - 1>,
9905 ranges::end(std::get<__n - 1>(_M_views)));
9911 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9913 constexpr auto __n =
sizeof...(_Vs);
9914 if constexpr (__detail::__all_forward<
true, _Vs...>
9915 && common_range<
const _Vs...[__n - 1]>)
9916 return _Iterator<true>(
this, in_place_index<__n - 1>,
9917 ranges::end(std::get<__n - 1>(_M_views)));
9923 size()
requires (sized_range<_Vs>&&...)
9925 return std::apply([](
auto... __sizes) {
9926 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9927 return (_CT(__sizes) + ...);
9928 }, __detail::__tuple_transform(ranges::size, _M_views));
9932 size() const requires (sized_range<const _Vs>&&...)
9934 return std::apply([](
auto... __sizes) {
9935 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9936 return (_CT(__sizes) + ...);
9937 }, __detail::__tuple_transform(ranges::size, _M_views));
9941 template<
typename... _Rs>
9942 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9946 template<
bool _Const,
typename... _Vs>
9947 struct __concat_view_iter_cat
9950 template<
bool _Const,
typename... _Vs>
9951 requires __detail::__all_forward<_Const, _Vs...>
9952 struct __concat_view_iter_cat<_Const, _Vs...>
9957 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9958 return input_iterator_tag{};
9960 return []<
typename... _Cats>(_Cats... __cats) {
9961 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9962 && __concat_is_random_access<_Const, _Vs...>)
9963 return random_access_iterator_tag{};
9964 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9965 && __concat_is_bidirectional<_Const, _Vs...>)
9966 return bidirectional_iterator_tag{};
9967 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9968 return forward_iterator_tag{};
9970 return input_iterator_tag{};
9971 }(
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9972 ::iterator_category{}...);
9977 template<input_range... _Vs>
9978 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9979 template<bool _Const>
9980 class concat_view<_Vs...>::_Iterator
9981 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9986 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9987 return random_access_iterator_tag{};
9988 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9989 return bidirectional_iterator_tag{};
9990 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9991 return forward_iterator_tag{};
9993 return input_iterator_tag{};
9997 friend _Iterator<!_Const>;
10001 using iterator_concept =
decltype(_S_iter_concept());
10002 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
10003 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
10006 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
10008 __maybe_const_t<_Const, concat_view>* _M_parent =
nullptr;
10011 template<
size_t _Nm>
10015 if constexpr (_Nm < (
sizeof...(_Vs) - 1))
10017 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
10019 _M_it.template emplace<_Nm + 1>(ranges::begin
10020 (std::get<_Nm + 1>(_M_parent->_M_views)));
10021 _M_satisfy<_Nm + 1>();
10026 template<
size_t _Nm>
10030 if constexpr (_Nm == 0)
10031 --std::get<0>(_M_it);
10034 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
10036 _M_it.template emplace<_Nm - 1>(ranges::end
10037 (std::get<_Nm - 1>(_M_parent->_M_views)));
10038 _M_prev<_Nm - 1>();
10041 --std::get<_Nm>(_M_it);
10045 template<
size_t _Nm>
10047 _M_advance_fwd(difference_type __offset, difference_type __steps)
10049 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10050 if constexpr (_Nm ==
sizeof...(_Vs) - 1)
10051 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10054 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
10055 if (__offset + __steps < __n_size)
10056 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10059 _M_it.template emplace<_Nm + 1>(ranges::begin
10060 (std::get<_Nm + 1>(_M_parent->_M_views)));
10061 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
10066 template<
size_t _Nm>
10068 _M_advance_bwd(difference_type __offset, difference_type __steps)
10070 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10071 if constexpr (_Nm == 0)
10072 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10074 if (__offset >= __steps)
10075 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10078 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
10079 _M_it.template emplace<_Nm - 1>(ranges::end
10080 (std::get<_Nm - 1>(_M_parent->_M_views)));
10081 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
10089 template<
typename _Fp>
10090 static constexpr auto
10091 _S_invoke_with_runtime_index(_Fp&& __f,
size_t __index)
10093 return [&__f, __index]<
size_t _Idx>(
this auto&& __self) {
10094 if (_Idx == __index)
10095 return __f.template operator()<_Idx>();
10096 if constexpr (_Idx + 1 <
sizeof...(_Vs))
10097 return __self.template
operator()<_Idx + 1>();
10098 __builtin_unreachable();
10099 }.template operator()<0>();
10102 template<
typename _Fp>
10104 _M_invoke_with_runtime_index(_Fp&& __f)
10105 {
return _S_invoke_with_runtime_index(
std::forward<_Fp>(__f), _M_it.index()); }
10107 template<
typename... _Args>
10109 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
10110 requires constructible_from<__base_iter, _Args&&...>
10115 _Iterator() =
default;
10118 _Iterator(_Iterator<!_Const> __it)
10119 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
10120 : _M_parent(__it._M_parent),
10121 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
10122 return __base_iter(in_place_index<_Idx>,
10123 std::get<_Idx>(
std::move(__it._M_it)));
10124 }, __it._M_it.index()))
10127 constexpr decltype(
auto)
10130 __glibcxx_assert(!_M_it.valueless_by_exception());
10131 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
10132 return std::visit([](
auto&& __it) -> reference {
return *__it; }, _M_it);
10135 constexpr _Iterator&
10138 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10139 ++std::get<_Idx>(_M_it);
10140 _M_satisfy<_Idx>();
10149 constexpr _Iterator
10151 requires __detail::__all_forward<_Const, _Vs...>
10153 auto __tmp = *
this;
10158 constexpr _Iterator&
10160 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10162 __glibcxx_assert(!_M_it.valueless_by_exception());
10163 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10169 constexpr _Iterator
10171 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10173 auto __tmp = *
this;
10178 constexpr _Iterator&
10179 operator+=(difference_type __n)
10180 requires __detail::__concat_is_random_access<_Const, _Vs...>
10182 __glibcxx_assert(!_M_it.valueless_by_exception());
10183 _M_invoke_with_runtime_index([
this, __n]<
size_t _Idx>() {
10184 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10186 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10188 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10193 constexpr _Iterator&
10194 operator-=(difference_type __n)
10195 requires __detail::__concat_is_random_access<_Const, _Vs...>
10201 constexpr decltype(
auto)
10202 operator[](difference_type __n)
const
10203 requires __detail::__concat_is_random_access<_Const, _Vs...>
10204 {
return *((*this) + __n); }
10206 friend constexpr bool
10207 operator==(
const _Iterator& __x,
const _Iterator& __y)
10208 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10210 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10211 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10212 return __x._M_it == __y._M_it;
10215 friend constexpr bool
10216 operator==(
const _Iterator& __it, default_sentinel_t)
10218 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10219 constexpr auto __last_idx =
sizeof...(_Vs) - 1;
10220 return (__it._M_it.index() == __last_idx
10221 && (std::get<__last_idx>(__it._M_it)
10222 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10225 friend constexpr bool
10226 operator<(
const _Iterator& __x,
const _Iterator& __y)
10227 requires __detail::__all_random_access<_Const, _Vs...>
10228 {
return __x._M_it < __y._M_it; }
10230 friend constexpr bool
10231 operator>(
const _Iterator& __x,
const _Iterator& __y)
10232 requires __detail::__all_random_access<_Const, _Vs...>
10233 {
return __x._M_it > __y._M_it; }
10235 friend constexpr bool
10236 operator<=(
const _Iterator& __x,
const _Iterator& __y)
10237 requires __detail::__all_random_access<_Const, _Vs...>
10238 {
return __x._M_it <= __y._M_it; }
10240 friend constexpr bool
10241 operator>=(
const _Iterator& __x,
const _Iterator& __y)
10242 requires __detail::__all_random_access<_Const, _Vs...>
10243 {
return __x._M_it >= __y._M_it; }
10245 friend constexpr auto
10246 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
10247 requires __detail::__all_random_access<_Const, _Vs...>
10248 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10249 {
return __x._M_it <=> __y._M_it; }
10251 friend constexpr _Iterator
10252 operator+(
const _Iterator& __it, difference_type __n)
10253 requires __detail::__concat_is_random_access<_Const, _Vs...>
10254 {
return auto(__it) += __n; }
10256 friend constexpr _Iterator
10257 operator+(difference_type __n,
const _Iterator& __it)
10258 requires __detail::__concat_is_random_access<_Const, _Vs...>
10259 {
return __it + __n; }
10261 friend constexpr _Iterator
10262 operator-(
const _Iterator& __it, difference_type __n)
10263 requires __detail::__concat_is_random_access<_Const, _Vs...>
10264 {
return auto(__it) -= __n; }
10266 friend constexpr difference_type
10267 operator-(
const _Iterator& __x,
const _Iterator& __y)
10268 requires __detail::__concat_is_random_access<_Const, _Vs...>
10270 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10271 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> difference_type {
10272 if constexpr (_Ix > _Iy)
10274 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10275 ranges::end(std::get<_Iy>(__y._M_parent
10277 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10279 std::get<_Ix>(__x._M_it));
10280 difference_type __s = 0;
10281 [&]<
size_t _Idx = _Iy + 1>(
this auto&& __self) {
10282 if constexpr (_Idx < _Ix)
10284 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10285 __self.template operator()<_Idx + 1>();
10288 return __dy + __s + __dx;
10290 else if constexpr (_Ix < _Iy)
10291 return -(__y - __x);
10293 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10294 }, __y._M_it.index());
10295 }, __x._M_it.index());
10298 friend constexpr difference_type
10299 operator-(
const _Iterator& __x, default_sentinel_t)
10300 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10301 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10302 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10304 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10305 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10306 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10307 difference_type __s = 0;
10308 [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) {
10309 if constexpr (_Idx <
sizeof...(_Vs))
10311 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10312 __self.template operator()<_Idx + 1>();
10315 return -(__dx + __s);
10316 }, __x._M_it.index());
10319 friend constexpr difference_type
10320 operator-(default_sentinel_t,
const _Iterator& __x)
10321 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10322 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10323 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10326 friend constexpr decltype(
auto)
10327 iter_move(
const _Iterator& __it)
10329 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10330 return std::visit([](
const auto& __i) -> _Res {
10331 return ranges::iter_move(__i);
10335 friend constexpr void
10336 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10337 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10338 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10340 std::visit([&]<
typename _Tp,
typename _Up>(
const _Tp& __it1,
const _Up& __it2) {
10341 if constexpr (is_same_v<_Tp, _Up>)
10342 ranges::iter_swap(__it1, __it2);
10344 ranges::swap(*__it1, *__it2);
10345 }, __x._M_it, __y._M_it);
10353 template<
typename... _Ts>
10359 template<
typename... _Ts>
10360 requires __detail::__can_concat_view<_Ts...>
10362 operator() [[nodiscard]] (_Ts&&... __ts)
const
10365 template<input_range _Range>
10367 operator() [[nodiscard]] (_Range&& __t)
const
10371 inline constexpr _Concat concat;
10377#if __cpp_lib_ranges_cache_latest
10380 template<input_range _Vp>
10382 class cache_latest_view :
public view_interface<cache_latest_view<_Vp>>
10384 _Vp _M_base = _Vp();
10386 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10387 add_pointer_t<range_reference_t<_Vp>>,
10388 range_reference_t<_Vp>>;
10389 __detail::__non_propagating_cache<__cache_t> _M_cache;
10395 cache_latest_view()
requires default_initializable<_Vp> = default;
10398 cache_latest_view(_Vp __base)
10399 : _M_base(std::move(__base))
10403 base() const & requires copy_constructible<_Vp>
10404 {
return _M_base; }
10412 {
return _Iterator(*
this); }
10416 {
return _Sentinel(*
this); }
10419 size()
requires sized_range<_Vp>
10420 {
return ranges::size(_M_base); }
10423 size() const requires sized_range<const _Vp>
10424 {
return ranges::size(_M_base); }
10427 template<
typename _Range>
10428 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10430 template<input_range _Vp>
10432 class cache_latest_view<_Vp>::_Iterator
10434 cache_latest_view* _M_parent;
10435 iterator_t<_Vp> _M_current;
10438 _Iterator(cache_latest_view& __parent)
10440 _M_current(ranges::begin(__parent._M_base))
10443 friend class cache_latest_view;
10446 using difference_type = range_difference_t<_Vp>;
10447 using value_type = range_value_t<_Vp>;
10448 using iterator_concept = input_iterator_tag;
10450 _Iterator(_Iterator&&) =
default;
10453 operator=(_Iterator&&) =
default;
10455 constexpr iterator_t<_Vp>
10459 constexpr const iterator_t<_Vp>&
10460 base() const & noexcept
10461 {
return _M_current; }
10463 constexpr range_reference_t<_Vp>&
10466 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10468 if (!_M_parent->_M_cache)
10469 _M_parent->_M_cache =
std::__addressof(__detail::__as_lvalue(*_M_current));
10470 return **_M_parent->_M_cache;
10474 if (!_M_parent->_M_cache)
10475 _M_parent->_M_cache._M_emplace_deref(_M_current);
10476 return *_M_parent->_M_cache;
10480 constexpr _Iterator&
10483 _M_parent->_M_cache._M_reset();
10492 friend constexpr range_rvalue_reference_t<_Vp>
10493 iter_move(
const _Iterator& __i)
10494 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10495 {
return ranges::iter_move(__i._M_current); }
10497 friend constexpr void
10498 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10499 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10500 requires indirectly_swappable<iterator_t<_Vp>>
10501 { ranges::iter_swap(__x._M_current, __y._M_current); }
10504 template<input_range _Vp>
10506 class cache_latest_view<_Vp>::_Sentinel
10508 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10511 _Sentinel(cache_latest_view& __parent)
10512 : _M_end(ranges::end(__parent._M_base))
10515 friend class cache_latest_view;
10518 _Sentinel() =
default;
10520 constexpr sentinel_t<_Vp>
10524 friend constexpr bool
10525 operator==(
const _Iterator& __x,
const _Sentinel& __y)
10526 {
return __x._M_current == __y._M_end; }
10528 friend constexpr range_difference_t<_Vp>
10529 operator-(
const _Iterator& __x,
const _Sentinel& __y)
10530 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10531 {
return __x._M_current - __y._M_end; }
10533 friend constexpr range_difference_t<_Vp>
10534 operator-(
const _Sentinel& __x,
const _Iterator& __y)
10535 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10536 {
return __x._M_end - __y._M_current; }
10543 template<
typename _Tp>
10544 concept __can_cache_latest =
requires { cache_latest_view(
std::declval<_Tp>()); };
10547 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10549 template<viewable_range _Range>
10550 requires __detail::__can_cache_latest<_Range>
10552 operator() [[nodiscard]] (_Range&& __r)
const
10555 static constexpr bool _S_has_simple_call_op =
true;
10558 inline constexpr _CacheLatest cache_latest;
10563#if __cpp_lib_ranges_as_input
10566 template<input_range _Vp>
10568 class as_input_view :
public view_interface<as_input_view<_Vp>>
10570 _Vp _M_base = _Vp();
10572 template<
bool _Const>
10576 as_input_view()
requires default_initializable<_Vp> = default;
10579 as_input_view(_Vp __base)
10580 : _M_base(std::move(__base))
10584 base() const & requires copy_constructible<_Vp>
10585 {
return _M_base; }
10592 begin()
requires (!__detail::__simple_view<_Vp>)
10593 {
return _Iterator<false>(ranges::begin(_M_base)); }
10596 begin() const requires range<const _Vp>
10597 {
return _Iterator<true>(ranges::begin(_M_base)); }
10600 end()
requires (!__detail::__simple_view<_Vp>)
10601 {
return ranges::end(_M_base); }
10604 end() const requires range<const _Vp>
10605 {
return ranges::end(_M_base); }
10608 size()
requires sized_range<_Vp>
10609 {
return ranges::size(_M_base); }
10612 size() const requires sized_range<const _Vp>
10613 {
return ranges::size(_M_base); }
10616 template<
typename _Range>
10617 as_input_view(_Range&&) -> as_input_view<views::all_t<_Range>>;
10619 template<input_range _Vp>
10621 template<
bool _Const>
10622 class as_input_view<_Vp>::_Iterator
10624 using _Base = __maybe_const_t<_Const, _Vp>;
10626 iterator_t<_Base> _M_current = iterator_t<_Base>();
10629 _Iterator(iterator_t<_Base> __current)
10630 : _M_current(std::move(__current))
10633 friend as_input_view;
10634 friend _Iterator<!_Const>;
10637 using difference_type = range_difference_t<_Base>;
10638 using value_type = range_value_t<_Base>;
10639 using iterator_concept = input_iterator_tag;
10641 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
10643 _Iterator(_Iterator&&) = default;
10644 _Iterator& operator=(_Iterator&&) = default;
10647 _Iterator(_Iterator<!_Const> __i)
10648 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10649 : _M_current(std::move(__i._M_current))
10652 constexpr iterator_t<_Base>
10656 constexpr const iterator_t<_Base>&
10657 base() const & noexcept
10658 {
return _M_current; }
10660 constexpr decltype(
auto)
10662 {
return *_M_current; }
10664 constexpr _Iterator&
10675 friend constexpr bool
10676 operator==(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10677 {
return __x._M_current == __y; }
10679 friend constexpr difference_type
10680 operator-(
const sentinel_t<_Base>& __y,
const _Iterator& __x)
10681 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10682 {
return __y - __x._M_current; }
10684 friend constexpr difference_type
10685 operator-(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10686 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10687 {
return __x._M_current - __y; }
10689 friend constexpr range_rvalue_reference_t<_Base>
10690 iter_move(
const _Iterator& __i)
10691 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10692 {
return ranges::iter_move(__i._M_current); }
10694 friend constexpr void
10695 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10696 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10697 requires indirectly_swappable<iterator_t<_Base>>
10698 { ranges::iter_swap(__x._M_current, __y._M_current); }
10705 template<
typename _Tp>
10709 struct _AsInput : __adaptor::_RangeAdaptorClosure<_AsInput>
10711 template<viewable_range _Range>
10712 requires __detail::__can_as_input<_Range>
10714 operator() [[nodiscard]] (_Range&& __r)
const
10716 if constexpr (input_range<_Range>
10717 && !common_range<_Range>
10718 && !forward_range<_Range>)
10724 static constexpr bool _S_has_simple_call_op =
true;
10727 inline constexpr _AsInput as_input;
10732_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.