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_hardened_view_interface
60#define __glibcxx_want_ranges
61#define __glibcxx_want_ranges_as_const
62#define __glibcxx_want_ranges_as_rvalue
63#define __glibcxx_want_ranges_cache_latest
64#define __glibcxx_want_ranges_cartesian_product
65#define __glibcxx_want_ranges_concat
66#define __glibcxx_want_ranges_chunk
67#define __glibcxx_want_ranges_chunk_by
68#define __glibcxx_want_ranges_enumerate
69#define __glibcxx_want_ranges_filter
70#define __glibcxx_want_ranges_indices
71#define __glibcxx_want_ranges_join_with
72#define __glibcxx_want_ranges_repeat
73#define __glibcxx_want_ranges_slide
74#define __glibcxx_want_ranges_stride
75#define __glibcxx_want_ranges_to_container
76#define __glibcxx_want_ranges_as_input
77#define __glibcxx_want_ranges_zip
80#ifdef __glibcxx_generator
81# include <bits/elements_of.h>
90namespace std _GLIBCXX_VISIBILITY(default)
92_GLIBCXX_BEGIN_NAMESPACE_VERSION
107 template<
typename _Tp>
requires is_object_v<_Tp>
112 static constexpr _Tp* begin()
noexcept {
return nullptr; }
113 static constexpr _Tp* end()
noexcept {
return nullptr; }
114 static constexpr _Tp* data()
noexcept {
return nullptr; }
115 static constexpr size_t size()
noexcept {
return 0; }
116 static constexpr bool empty()
noexcept {
return true; }
119 template<
typename _Tp>
120 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> =
true;
124#if __cpp_lib_ranges >= 202207L
126 template<
typename _Tp>
129 template<
typename _Tp>
133 template<__boxable _Tp>
134 struct __box : std::optional<_Tp>
136 using std::optional<_Tp>::optional;
140 noexcept(is_nothrow_default_constructible_v<_Tp>)
142 :
std::optional<_Tp>{std::in_place}
145 __box(
const __box&) =
default;
146 __box(__box&&) =
default;
148 using std::optional<_Tp>::operator=;
154 operator=(
const __box& __that)
155 noexcept(is_nothrow_copy_constructible_v<_Tp>)
156 requires (!copyable<_Tp>) && copy_constructible<_Tp>
161 this->emplace(*__that);
169 operator=(__box&& __that)
170 noexcept(is_nothrow_move_constructible_v<_Tp>)
171 requires (!movable<_Tp>)
184 template<
typename _Tp>
185 concept __boxable_copyable
186 = copy_constructible<_Tp>
187 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
188 && is_nothrow_copy_constructible_v<_Tp>));
189 template<
typename _Tp>
190 concept __boxable_movable
191 = (!copy_constructible<_Tp>)
192 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
198 template<__boxable _Tp>
199 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
203 [[no_unique_address]] _Tp _M_value = _Tp();
206 __box()
requires default_initializable<_Tp> = default;
209 __box(const _Tp& __t)
210 noexcept(is_nothrow_copy_constructible_v<_Tp>)
211 requires copy_constructible<_Tp>
217 noexcept(is_nothrow_move_constructible_v<_Tp>)
218 : _M_value(std::move(__t))
221 template<
typename... _Args>
222 requires constructible_from<_Tp, _Args...>
224 __box(in_place_t, _Args&&... __args)
225 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
226 : _M_value(std::
forward<_Args>(__args)...)
229 __box(
const __box&) =
default;
230 __box(__box&&) =
default;
231 __box& operator=(
const __box&)
requires copyable<_Tp> =
default;
232 __box& operator=(__box&&)
requires movable<_Tp> = default;
237 operator=(const __box& __that) noexcept
238 requires (!copyable<_Tp>) && copy_constructible<_Tp>
240 static_assert(is_nothrow_copy_constructible_v<_Tp>);
251 operator=(__box&& __that)
noexcept
252 requires (!movable<_Tp>)
254 static_assert(is_nothrow_move_constructible_v<_Tp>);
264 has_value() const noexcept
279 constexpr const _Tp&&
284 operator->() noexcept
288 operator->() const noexcept
292 namespace __func_handle
294 template<
typename _Fn>
297 _Inplace() =
default;
300 _Inplace(_Fn __func) noexcept
304 template<
typename... _Iters>
305 constexpr decltype(
auto)
306 _M_call_deref(
const _Iters&... __iters)
const
307 noexcept(
noexcept(_M_fn(*__iters...)))
308 {
return _M_fn(*__iters...); }
310 template<
typename _DistType,
typename... _Iters>
311 constexpr decltype(
auto)
312 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
313 noexcept(
noexcept(_M_fn(__iters[iter_difference_t<_Iters>(__n)]...)))
314 {
return _M_fn(__iters[iter_difference_t<_Iters>(__n)]...); }
317 [[no_unique_address]] _Fn _M_fn = _Fn();
320 template<
typename _Fn>
321 struct _InplaceMemPtr
323 _InplaceMemPtr() =
default;
326 _InplaceMemPtr(_Fn __func) noexcept
330 template<
typename... _Iters>
331 constexpr decltype(
auto)
332 _M_call_deref(
const _Iters&... __iters)
const
336 template<
typename _DistType,
typename... _Iters>
337 constexpr decltype(
auto)
338 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
339 noexcept(
noexcept(
std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...)))
340 {
return std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...); }
343 _Fn _M_ptr =
nullptr;
346 template<
typename _Fn>
349 _ViaPointer() =
default;
352 _ViaPointer(_Fn& __func) noexcept
356 template<
typename _Un>
357 requires (!is_const_v<_Un>) && is_same_v<const _Un, _Fn>
359 _ViaPointer(_ViaPointer<_Un> __other) noexcept
360 : _M_ptr(__other._M_ptr)
363 template<
typename... _Iters>
364 constexpr decltype(
auto)
365 _M_call_deref(
const _Iters&... __iters)
const
366 noexcept(
noexcept((*_M_ptr)(*__iters...)))
367 {
return (*_M_ptr)(*__iters...); }
369 template<
typename _DistType,
typename... _Iters>
370 constexpr decltype(
auto)
371 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
372 noexcept(
noexcept((*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...)))
373 {
return (*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...); }
376 _Fn* _M_ptr =
nullptr;
379 friend struct _ViaPointer;
382 template<
typename _Fn>
385 _StaticCall() =
default;
388 _StaticCall(
const _Fn&)
noexcept
391 template<
typename... _Iters>
392 static constexpr decltype(
auto)
393 _M_call_deref(
const _Iters&... __iters)
394 noexcept(
noexcept(_Fn::operator()(*__iters...)))
395 {
return _Fn::operator()(*__iters...); }
397 template<
typename _DistType,
typename... _Iters>
398 static constexpr decltype(
auto)
399 _M_call_subscript(_DistType __n,
const _Iters&... __iters)
400 noexcept(
noexcept(_Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...)))
401 {
return _Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...); }
404 template<
typename _Fn,
typename... _Iters>
408 using _Fd = remove_cv_t<_Fn>;
409 if constexpr (is_member_pointer_v<_Fd>)
410 return __func_handle::_InplaceMemPtr<_Fd>();
411 else if constexpr (is_function_v<remove_pointer_t<_Fd>>)
412 return __func_handle::_Inplace<_Fd>();
413 else if constexpr (__is_std_op_wrapper<_Fd>)
414 return __func_handle::_Inplace<_Fd>();
415 else if constexpr (
requires (
const _Iters&... __iters)
416 { _Fd::operator()(*__iters...); })
417 return __func_handle::_StaticCall<_Fd>();
419 return __func_handle::_ViaPointer<_Fn>();
423 template<
typename _Fn,
typename... _Iters>
424 using __func_handle_t =
decltype(__func_handle::__select<_Fn, _Iters...>());
428#if __cpp_lib_ranges >= 202207L
429 template<move_constructible _Tp>
431 template<copy_constructible _Tp>
433 requires is_object_v<_Tp>
440 single_view(
const _Tp& __t)
441 noexcept(is_nothrow_copy_constructible_v<_Tp>)
447 single_view(_Tp&& __t)
448 noexcept(is_nothrow_move_constructible_v<_Tp>)
454 template<
typename... _Args>
457 single_view(in_place_t, _Args&&... __args)
458 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
467 begin()
const noexcept
472 {
return data() + 1; }
476 {
return data() + 1; }
480 static constexpr bool
484 static constexpr size_t
490 {
return _M_value.operator->(); }
493 data()
const noexcept
494 {
return _M_value.operator->(); }
497 [[no_unique_address]] __detail::__box<_Tp> _M_value;
500 template<
typename _Tp>
505 template<
typename _Wp>
508 template<
typename _It>
509 concept __decrementable = incrementable<_It>
513 { __i-- } -> same_as<_It>;
516 template<
typename _It>
517 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
518 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
520 { __i += __n } -> same_as<_It&>;
521 { __i -= __n } -> same_as<_It&>;
525 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
528 template<
typename _Winc>
529 struct __iota_view_iter_cat
532 template<incrementable _Winc>
533 struct __iota_view_iter_cat<_Winc>
534 {
using iterator_category = input_iterator_tag; };
537 template<weakly_incrementable _Winc,
538 semiregular _Bound = unreachable_sentinel_t>
539 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
546 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
552 using namespace __detail;
553 if constexpr (__advanceable<_Winc>)
554 return random_access_iterator_tag{};
555 else if constexpr (__decrementable<_Winc>)
556 return bidirectional_iterator_tag{};
557 else if constexpr (incrementable<_Winc>)
558 return forward_iterator_tag{};
560 return input_iterator_tag{};
564 using iterator_concept =
decltype(_S_iter_concept());
566 using value_type = _Winc;
567 using difference_type = __detail::__iota_diff_t<_Winc>;
569 _Iterator()
requires default_initializable<_Winc> = default;
572 _Iterator(_Winc __value)
573 : _M_value(__value) { }
576 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
591 operator++(
int)
requires incrementable<_Winc>
599 operator--()
requires __detail::__decrementable<_Winc>
606 operator--(
int)
requires __detail::__decrementable<_Winc>
614 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
616 using __detail::__is_integer_like;
617 using __detail::__is_signed_integer_like;
618 if constexpr (__is_integer_like<_Winc>
619 && !__is_signed_integer_like<_Winc>)
621 if (__n >= difference_type(0))
622 _M_value +=
static_cast<_Winc
>(__n);
624 _M_value -=
static_cast<_Winc
>(-__n);
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)
const
651 requires __detail::__advanceable<_Winc>
652 {
return _Winc(_M_value + __n); }
654 friend constexpr bool
655 operator==(
const _Iterator& __x,
const _Iterator& __y)
656 requires equality_comparable<_Winc>
657 {
return __x._M_value == __y._M_value; }
659 friend constexpr bool
660 operator<(
const _Iterator& __x,
const _Iterator& __y)
661 requires totally_ordered<_Winc>
662 {
return __x._M_value < __y._M_value; }
664 friend constexpr bool
665 operator>(
const _Iterator& __x,
const _Iterator& __y)
666 requires totally_ordered<_Winc>
667 {
return __y < __x; }
669 friend constexpr bool
670 operator<=(
const _Iterator& __x,
const _Iterator& __y)
671 requires totally_ordered<_Winc>
672 {
return !(__y < __x); }
674 friend constexpr bool
675 operator>=(
const _Iterator& __x,
const _Iterator& __y)
676 requires totally_ordered<_Winc>
677 {
return !(__x < __y); }
679#ifdef __cpp_lib_three_way_comparison
680 friend constexpr auto
681 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
682 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
683 {
return __x._M_value <=> __y._M_value; }
686 friend constexpr _Iterator
687 operator+(_Iterator __i, difference_type __n)
688 requires __detail::__advanceable<_Winc>
694 friend constexpr _Iterator
695 operator+(difference_type __n, _Iterator __i)
696 requires __detail::__advanceable<_Winc>
697 {
return __i += __n; }
699 friend constexpr _Iterator
700 operator-(_Iterator __i, difference_type __n)
701 requires __detail::__advanceable<_Winc>
707 friend constexpr difference_type
708 operator-(
const _Iterator& __x,
const _Iterator& __y)
709 requires __detail::__advanceable<_Winc>
711 using __detail::__is_integer_like;
712 using __detail::__is_signed_integer_like;
713 using _Dt = difference_type;
714 if constexpr (__is_integer_like<_Winc>)
716 if constexpr (__is_signed_integer_like<_Winc>)
717 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
719 return (__y._M_value > __x._M_value)
720 ? _Dt(-_Dt(__y._M_value - __x._M_value))
721 : _Dt(__x._M_value - __y._M_value);
724 return __x._M_value - __y._M_value;
728 _Winc _M_value = _Winc();
737 _Bound _M_bound = _Bound();
740 _Sentinel() =
default;
743 _Sentinel(_Bound __bound)
744 : _M_bound(__bound) { }
746 friend constexpr bool
747 operator==(
const _Iterator& __x,
const _Sentinel& __y)
748 {
return __x._M_value == __y._M_bound; }
750 friend constexpr iter_difference_t<_Winc>
751 operator-(
const _Iterator& __x,
const _Sentinel& __y)
752 requires sized_sentinel_for<_Bound, _Winc>
753 {
return -(__y._M_bound - __x._M_value); }
755 friend constexpr iter_difference_t<_Winc>
756 operator-(
const _Sentinel& __x,
const _Iterator& __y)
757 requires sized_sentinel_for<_Bound, _Winc>
758 {
return __x._M_bound - __y._M_value; }
763 _Winc _M_value = _Winc();
764 [[no_unique_address]] _Bound _M_bound = _Bound();
767 iota_view()
requires default_initializable<_Winc> = default;
770 iota_view(_Winc __value)
775 iota_view(type_identity_t<_Winc> __value,
776 type_identity_t<_Bound> __bound)
777 : _M_value(__value), _M_bound(__bound)
779 if constexpr (totally_ordered_with<_Winc, _Bound>)
780 __glibcxx_assert(
bool(__value <= __bound) );
784 iota_view(_Iterator __first, _Iterator __last)
785 requires same_as<_Winc, _Bound>
786 : iota_view(__first._M_value, __last._M_value)
790 iota_view(_Iterator __first, unreachable_sentinel_t __last)
791 requires same_as<_Bound, unreachable_sentinel_t>
792 : iota_view(__first._M_value, __last)
796 iota_view(_Iterator __first, _Sentinel __last)
797 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
798 : iota_view(__first._M_value, __last._M_bound)
802 begin()
const {
return _Iterator{_M_value}; }
807 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
808 return unreachable_sentinel;
810 return _Sentinel{_M_bound};
814 end() const requires same_as<_Winc, _Bound>
815 {
return _Iterator{_M_bound}; }
821 {
return _M_value == _M_bound; }
825 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
826 || (integral<_Winc> && integral<_Bound>)
827 || sized_sentinel_for<_Bound, _Winc>
829 using __detail::__is_integer_like;
830 using __detail::__to_unsigned_like;
831 if constexpr (integral<_Winc> && integral<_Bound>)
834 return _Up(_M_bound) - _Up(_M_value);
836 else if constexpr (__is_integer_like<_Winc>)
837 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
839 return __to_unsigned_like(_M_bound - _M_value);
843 template<
typename _Winc,
typename _Bound>
844 requires (!__detail::__is_integer_like<_Winc>
845 || !__detail::__is_integer_like<_Bound>
846 || (__detail::__is_signed_integer_like<_Winc>
847 == __detail::__is_signed_integer_like<_Bound>))
848 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
850 template<
typename _Winc,
typename _Bound>
851 inline constexpr bool
852 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
856 template<
typename _Tp>
857 inline constexpr empty_view<_Tp> empty{};
861 template<
typename _Tp>
862 concept __can_single_view
868 template<__detail::__can_single_view _Tp>
870 operator() [[nodiscard]] (_Tp&& __e)
const
875 inline constexpr _Single single{};
879 template<
typename... _Args>
887 template<__detail::__can_iota_view _Tp>
888 constexpr iota_view<decay_t<_Tp>>
889 operator() [[nodiscard]] (_Tp&& __e)
const
892 template<
typename _Tp,
typename _Up>
893 requires __detail::__can_iota_view<_Tp, _Up>
895 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
899 inline constexpr _Iota iota{};
901#ifdef __cpp_lib_ranges_indices
904 template<ranges::__detail::__is_
integer_like _Tp>
905 requires __detail::__can_iota_view<_Tp>
906 [[nodiscard]]
constexpr auto
907 operator() (_Tp __e)
const noexcept
908 {
return iota(_Tp{}, __e); }
911 inline constexpr _Indices indices{};
918 template<
typename _Val,
typename _CharT,
typename _Traits>
919 concept __stream_extractable
920 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
923 template<movable _Val,
typename _CharT,
924 typename _Traits = char_traits<_CharT>>
925 requires default_initializable<_Val>
926 && __detail::__stream_extractable<_Val, _CharT, _Traits>
927 class basic_istream_view
928 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
932 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
939 *_M_stream >> _M_object;
940 return _Iterator{
this};
943 constexpr default_sentinel_t
948 basic_istream<_CharT, _Traits>* _M_stream;
949 _Val _M_object = _Val();
954 using iterator_concept = input_iterator_tag;
955 using difference_type = ptrdiff_t;
956 using value_type = _Val;
959 _Iterator(basic_istream_view* __parent) noexcept
960 : _M_parent(__parent)
963 _Iterator(
const _Iterator&) =
delete;
964 _Iterator(_Iterator&&) =
default;
965 _Iterator& operator=(
const _Iterator&) =
delete;
966 _Iterator& operator=(_Iterator&&) =
default;
971 *_M_parent->_M_stream >> _M_parent->_M_object;
981 {
return _M_parent->_M_object; }
984 operator==(
const _Iterator& __x, default_sentinel_t)
985 {
return !*__x._M_parent->_M_stream; }
988 basic_istream_view* _M_parent;
994 template<
typename _Val>
995 using istream_view = basic_istream_view<_Val, char>;
997 template<
typename _Val>
998 using wistream_view = basic_istream_view<_Val, wchar_t>;
1004 template<
typename _Tp,
typename _Up>
1005 concept __can_istream_view =
requires (_Up __e) {
1006 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
1010 template<
typename _Tp>
1013 template<
typename _CharT,
typename _Traits>
1015 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
1017 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
1020 template<
typename _Tp>
1021 inline constexpr _Istream<_Tp> istream;
1029 template<
typename _Tp,
int _Disc>
1038 template<
bool _Present,
typename _Tp,
int _Disc = 0>
1039 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
1042 template<
bool _Const,
typename _Tp>
1043 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
1048using __detail::__maybe_const_t;
1050namespace views::__adaptor
1053 template<
typename _Adaptor,
typename... _Args>
1054 concept __adaptor_invocable
1059 template<
typename _Adaptor,
typename... _Args>
1060 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
1061 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
1062 && (constructible_from<decay_t<_Args>, _Args> && ...);
1064 template<
typename _Adaptor,
typename... _Args>
1067 template<
typename _Lhs,
typename _Rhs>
1075 template<
typename _Derived>
1076 struct _RangeAdaptorClosure;
1078 template<
typename _Tp,
typename _Up>
1079 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
1080 void __is_range_adaptor_closure_fn
1081 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
1083 template<
typename _Tp>
1084 concept __is_range_adaptor_closure
1085 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
1087#pragma GCC diagnostic push
1088#pragma GCC diagnostic ignored "-Wdangling-reference"
1090 template<
typename _Self,
typename _Range>
1091 requires __is_range_adaptor_closure<_Self>
1092 && __adaptor_invocable<_Self, _Range>
1094 operator|(_Range&& __r, _Self&& __self)
1099 template<
typename _Lhs,
typename _Rhs>
1100 requires __is_range_adaptor_closure<_Lhs>
1101 && __is_range_adaptor_closure<_Rhs>
1103 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
1108#pragma GCC diagnostic pop
1110 template<
typename _Derived>
1111 struct _RangeAdaptorClosure
1117 template<
typename _Self,
typename _Range>
1118 requires __is_range_adaptor_closure<_Self>
1119 && __adaptor_invocable<_Self, _Range>
1120 friend constexpr auto
1121 operator|(_Range&& __r, _Self&& __self);
1123 template<
typename _Lhs,
typename _Rhs>
1124 requires __is_range_adaptor_closure<_Lhs>
1125 && __is_range_adaptor_closure<_Rhs>
1126 friend constexpr auto
1127 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1141 template<
typename _Derived>
1142 struct _RangeAdaptor
1146 template<
typename... _Args>
1147 requires __adaptor_partial_app_viable<_Derived, _Args...>
1149 operator()(_Args&&... __args)
const
1158 template<
typename _Adaptor>
1159 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1163 template<
typename _Adaptor,
typename... _Args>
1164 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1165 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1169 template<
typename _Adaptor,
typename... _Args>
1170 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1172 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1173 [[no_unique_address]] _Binder _M_binder;
1177 template<
typename... _Ts>
1179 _Partial(
int, _Ts&&... __args)
1180 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1185#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1186# pragma GCC diagnostic push
1187# pragma GCC diagnostic ignored "-Wc++23-extensions"
1188 template<
typename _Self,
typename _Range>
1189 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1191 operator()(
this _Self&& __self, _Range&& __r)
1193 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1196# pragma GCC diagnostic pop
1198 template<
typename _Range>
1199 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1201 operator()(_Range&& __r)
const &
1204 template<
typename _Range>
1205 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1207 operator()(_Range&& __r) &&
1210 template<
typename _Range>
1212 operator()(_Range&& __r)
const && =
delete;
1220 template<
typename _Adaptor,
typename... _Args>
1221 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1222 && (is_trivially_copy_constructible_v<_Args> && ...)
1223 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1225 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1226 [[no_unique_address]] _Binder _M_binder;
1228 template<
typename... _Ts>
1230 _Partial(
int, _Ts&&... __args)
1231 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1236 template<
typename _Range>
1237 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1239 operator()(_Range&& __r)
const
1242 static constexpr bool _S_has_simple_call_op =
true;
1245 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1246 concept __pipe_invocable
1251 template<
typename _Lhs,
typename _Rhs>
1252 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1254 [[no_unique_address]] _Lhs _M_lhs;
1255 [[no_unique_address]] _Rhs _M_rhs;
1257 template<
typename _Tp,
typename _Up>
1259 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1260 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1265#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1266# pragma GCC diagnostic push
1267# pragma GCC diagnostic ignored "-Wc++23-extensions"
1268 template<
typename _Self,
typename _Range>
1269 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1271 operator()(
this _Self&& __self, _Range&& __r)
1273 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1274 (__like_t<_Self, _Pipe>(__self)._M_lhs
1277# pragma GCC diagnostic pop
1279 template<
typename _Range>
1280 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1282 operator()(_Range&& __r)
const &
1285 template<
typename _Range>
1286 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1288 operator()(_Range&& __r) &&
1291 template<
typename _Range>
1293 operator()(_Range&& __r)
const && =
delete;
1301 template<
typename _Lhs,
typename _Rhs>
1302 requires __closure_has_simple_call_op<_Lhs>
1303 && __closure_has_simple_call_op<_Rhs>
1304 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1306 [[no_unique_address]] _Lhs _M_lhs;
1307 [[no_unique_address]] _Rhs _M_rhs;
1309 template<
typename _Tp,
typename _Up>
1311 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1312 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1315 template<
typename _Range>
1316 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1318 operator()(_Range&& __r)
const
1321 static constexpr bool _S_has_simple_call_op =
true;
1325#if __cpp_lib_ranges >= 202202L
1327 template<
typename _Derived>
1328 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1329 class range_adaptor_closure
1330 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1334 template<range _Range>
requires is_object_v<_Range>
1340 static void _S_fun(_Range&);
1341 static void _S_fun(_Range&&) =
delete;
1344 template<__detail::__different_from<ref_view> _Tp>
1345 requires convertible_to<_Tp, _Range&>
1357 constexpr iterator_t<_Range>
1359 {
return ranges::begin(*_M_r); }
1361 constexpr sentinel_t<_Range>
1363 {
return ranges::end(*_M_r); }
1366 empty() const requires requires { ranges::empty(*_M_r); }
1367 {
return ranges::empty(*_M_r); }
1370 size() const requires sized_range<_Range>
1371 {
return ranges::size(*_M_r); }
1374 data() const requires contiguous_range<_Range>
1375 {
return ranges::data(*_M_r); }
1378 template<
typename _Range>
1379 ref_view(_Range&) -> ref_view<_Range>;
1381 template<
typename _Tp>
1382 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1384 template<range _Range>
1385 requires movable<_Range>
1386 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1390 _Range _M_r = _Range();
1393 owning_view()
requires default_initializable<_Range> = default;
1396 owning_view(_Range&& __t)
1397 noexcept(is_nothrow_move_constructible_v<_Range>)
1398 : _M_r(std::move(__t))
1401 owning_view(owning_view&&) =
default;
1402 owning_view& operator=(owning_view&&) =
default;
1408 constexpr const _Range&
1409 base() const& noexcept
1416 constexpr const _Range&&
1417 base() const&& noexcept
1420 constexpr iterator_t<_Range>
1422 {
return ranges::begin(_M_r); }
1424 constexpr sentinel_t<_Range>
1426 {
return ranges::end(_M_r); }
1430 {
return ranges::begin(_M_r); }
1433 end() const requires
range<const _Range>
1434 {
return ranges::end(_M_r); }
1437 empty()
requires requires { ranges::empty(_M_r); }
1438 {
return ranges::empty(_M_r); }
1441 empty() const requires requires { ranges::empty(_M_r); }
1442 {
return ranges::empty(_M_r); }
1446 {
return ranges::size(_M_r); }
1450 {
return ranges::size(_M_r); }
1454 {
return ranges::data(_M_r); }
1458 {
return ranges::data(_M_r); }
1461 template<
typename _Tp>
1462 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1463 = enable_borrowed_range<_Tp>;
1469 template<
typename _Range>
1472 template<
typename _Range>
1476 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1478 template<
typename _Range>
1479 static constexpr bool
1482 if constexpr (view<decay_t<_Range>>)
1484 else if constexpr (__detail::__can_ref_view<_Range>)
1490 template<viewable_range _Range>
1491 requires view<decay_t<_Range>>
1492 || __detail::__can_ref_view<_Range>
1493 || __detail::__can_owning_view<_Range>
1495 operator() [[nodiscard]] (_Range&& __r)
const
1496 noexcept(_S_noexcept<_Range>())
1498 if constexpr (view<decay_t<_Range>>)
1500 else if constexpr (__detail::__can_ref_view<_Range>)
1506 static constexpr bool _S_has_simple_call_op =
true;
1509 inline constexpr _All all;
1511 template<viewable_range _Range>
1517 template<
typename _Tp>
1518 struct __non_propagating_cache
1526 template<
typename _Tp>
1527 requires is_object_v<_Tp>
1528 struct __non_propagating_cache<_Tp>
1529 :
protected _Optional_base<_Tp>
1531 __non_propagating_cache() =
default;
1534 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1538 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1539 { __other._M_reset(); }
1541 constexpr __non_propagating_cache&
1542 operator=(
const __non_propagating_cache& __other)
noexcept
1549 constexpr __non_propagating_cache&
1550 operator=(__non_propagating_cache&& __other)
noexcept
1557 constexpr __non_propagating_cache&
1558 operator=(_Tp __val)
1561 this->_M_payload._M_construct(
std::move(__val));
1566 operator bool() const noexcept
1567 {
return this->_M_is_engaged(); }
1571 {
return this->_M_get(); }
1573 constexpr const _Tp&
1575 {
return this->_M_get(); }
1577 template<
typename _Iter>
1579 _M_emplace_deref(
const _Iter& __i)
1582 auto __f = [] (
auto& __x) {
return *__x; };
1583 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1584 return this->_M_get();
1587 using _Optional_base<_Tp>::_M_reset;
1590 template<range _Range>
1591 struct _CachedPosition
1594 _M_has_value()
const
1597 constexpr iterator_t<_Range>
1598 _M_get(
const _Range&)
const
1600 __glibcxx_assert(
false);
1601 __builtin_unreachable();
1605 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1609 template<forward_range _Range>
1610 struct _CachedPosition<_Range>
1611 :
protected __non_propagating_cache<iterator_t<_Range>>
1614 _M_has_value()
const
1615 {
return this->_M_is_engaged(); }
1617 constexpr iterator_t<_Range>
1618 _M_get(
const _Range&)
const
1620 __glibcxx_assert(_M_has_value());
1625 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1627 __glibcxx_assert(!_M_has_value());
1630 this->_M_payload._M_engaged =
true;
1634 template<random_access_range _Range>
1635 struct _CachedPosition<_Range>
1638 range_difference_t<_Range> _M_offset = -1;
1641 _CachedPosition() =
default;
1644 _CachedPosition(
const _CachedPosition&) =
default;
1647 _CachedPosition(_CachedPosition&& __other)
noexcept
1650 constexpr _CachedPosition&
1651 operator=(
const _CachedPosition&) =
default;
1653 constexpr _CachedPosition&
1654 operator=(_CachedPosition&& __other)
noexcept
1657 _M_offset = __other._M_offset;
1658 __other._M_offset = -1;
1663 _M_has_value()
const
1664 {
return _M_offset >= 0; }
1666 constexpr iterator_t<_Range>
1667 _M_get(_Range& __r)
const
1669 __glibcxx_assert(_M_has_value());
1670 return ranges::begin(__r) + _M_offset;
1674 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1676 __glibcxx_assert(!_M_has_value());
1677 _M_offset = __it - ranges::begin(__r);
1684 template<
typename _Base>
1685 struct __filter_view_iter_cat
1688 template<forward_range _Base>
1689 struct __filter_view_iter_cat<_Base>
1695 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1696 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1697 return bidirectional_iterator_tag{};
1698 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1699 return forward_iterator_tag{};
1704 using iterator_category =
decltype(_S_iter_cat());
1709 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1710 requires view<_Vp> && is_object_v<_Pred>
1711 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1714 template<
bool _Const>
1717 template<
bool _Const>
1718 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1721 static constexpr auto
1724 if constexpr (_Const)
1725 return input_iterator_tag{};
1726 else if constexpr (bidirectional_range<_Vp>)
1727 return bidirectional_iterator_tag{};
1728 else if constexpr (forward_range<_Vp>)
1729 return forward_iterator_tag{};
1731 return input_iterator_tag{};
1735 friend _Iterator<!_Const>;
1737 using _Parent = __maybe_const_t<_Const, filter_view>;
1738 using _Base = __maybe_const_t<_Const, _Vp>;
1739 using _Base_iter = iterator_t<_Base>;
1741 _Base_iter _M_current = _Base_iter();
1742 _Parent* _M_parent =
nullptr;
1745 using iterator_concept =
decltype(_S_iter_concept());
1747 using value_type = range_value_t<_Base>;
1748 using difference_type = range_difference_t<_Base>;
1750 _Iterator()
requires default_initializable<_Base_iter> = default;
1753 _Iterator(_Parent* __parent, _Base_iter __current)
1754 : _M_current(std::move(__current)),
1759 _Iterator(_Iterator<!_Const> __i)
1760 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
1761 : _M_current(
std::move(__i._M_current)),
1765 constexpr const _Base_iter&
1766 base() const & noexcept
1767 {
return _M_current; }
1769 constexpr _Base_iter
1773 constexpr range_reference_t<_Base>
1775 {
return *_M_current; }
1777 constexpr _Base_iter
1779 requires __detail::__has_arrow<_Base_iter>
1780 && copyable<_Base_iter>
1781 {
return _M_current; }
1783 constexpr _Iterator&
1786 _M_current = ranges::find_if(
std::move(++_M_current),
1787 ranges::end(_M_parent->_M_base),
1797 operator++(
int)
requires forward_range<_Base>
1804 constexpr _Iterator&
1805 operator--()
requires bidirectional_range<_Base>
1814 operator--(
int)
requires bidirectional_range<_Base>
1821 friend constexpr bool
1822 operator==(
const _Iterator& __x,
const _Iterator& __y)
1823 requires equality_comparable<_Base_iter>
1824 {
return __x._M_current == __y._M_current; }
1826 friend constexpr range_rvalue_reference_t<_Base>
1827 iter_move(
const _Iterator& __i)
1828 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1829 {
return ranges::iter_move(__i._M_current); }
1831 friend constexpr void
1832 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1833 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1834 requires indirectly_swappable<_Base_iter>
1835 { ranges::iter_swap(__x._M_current, __y._M_current); }
1838 template<
bool _Const>
1842 using _Parent = __maybe_const_t<_Const, filter_view>;
1843 using _Base = __maybe_const_t<_Const, _Vp>;
1844 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1846 friend _Sentinel<!_Const>;
1849 _Sentinel() =
default;
1852 _Sentinel(_Parent* __parent)
1853 : _M_end(ranges::end(__parent->_M_base))
1857 _Sentinel(_Sentinel<!_Const> __i)
1858 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1862 constexpr sentinel_t<_Base>
1866 template<
bool _Const2>
1867 requires sentinel_for<sentinel_t<_Base>,
1868 iterator_t<__maybe_const_t<_Const2, _Vp>>>
1869 friend constexpr bool
1870 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
1871 {
return __x._M_current == __y._M_end; }
1874 _Vp _M_base = _Vp();
1875 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1876 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1879 filter_view()
requires (default_initializable<_Vp>
1880 && default_initializable<_Pred>)
1884 filter_view(_Vp __base, _Pred __pred)
1885 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
1889 base() const& requires copy_constructible<_Vp>
1896 constexpr const _Pred&
1898 {
return *_M_pred; }
1900 constexpr _Iterator<false>
1903 if (_M_cached_begin._M_has_value())
1904 return {
this, _M_cached_begin._M_get(_M_base)};
1906 __glibcxx_assert(_M_pred.has_value());
1907 auto __it = ranges::find_if(ranges::begin(_M_base),
1908 ranges::end(_M_base),
1910 _M_cached_begin._M_set(_M_base, __it);
1914 constexpr _Iterator<true>
1916 requires (input_range<const _Vp> && !forward_range<const _Vp>
1917 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1919 __glibcxx_assert(_M_pred.has_value());
1920 auto __it = ranges::find_if(ranges::begin(_M_base),
1921 ranges::end(_M_base),
1929 if constexpr (common_range<_Vp>)
1930 return _Iterator<false>{
this, ranges::end(_M_base)};
1932 return _Sentinel<false>{
this};
1935 constexpr _Sentinel<true>
1937 requires (input_range<const _Vp> && !forward_range<const _Vp>
1938 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1939 {
return _Sentinel<true>{
this}; }
1942 template<
typename _Range,
typename _Pred>
1943 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1949 template<
typename _Range,
typename _Pred>
1950 concept __can_filter_view
1954 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1956 template<viewable_range _Range,
typename _Pred>
1957 requires __detail::__can_filter_view<_Range, _Pred>
1959 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1964 using _RangeAdaptor<_Filter>::operator();
1965 static constexpr int _S_arity = 2;
1966 static constexpr bool _S_has_simple_extra_args =
true;
1969 inline constexpr _Filter filter;
1972#if __cpp_lib_ranges >= 202207L
1973 template<input_range _Vp, move_constructible _Fp>
1975 template<input_range _Vp, copy_constructible _Fp>
1978 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1979 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1980 range_reference_t<_Vp>>>
1981 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
1984 template<
bool _Const>
1985 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1987 template<
bool _Const>
1991 template<
bool _Const>
1992 requires forward_range<_Base<_Const>>
1993 struct __iter_cat<_Const>
2002 using _Base = transform_view::_Base<_Const>;
2003 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2004 range_reference_t<_Base>>;
2007 if constexpr (is_reference_v<_Res>)
2010 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
2011 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
2012 return random_access_iterator_tag{};
2017 return input_iterator_tag{};
2020 using iterator_category =
decltype(_S_iter_cat());
2023 template<
bool _Const>
2026 template<
bool _Const>
2027 struct _Iterator : __iter_cat<_Const>
2030 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2031 using _Base = transform_view::_Base<_Const>;
2032 using _Base_iter = iterator_t<_Base>;
2033 using _Func_handle = __detail::__func_handle_t<
2034 __detail::__maybe_const_t<_Const, _Fp>,
2040 if constexpr (random_access_range<_Base>)
2041 return random_access_iterator_tag{};
2042 else if constexpr (bidirectional_range<_Base>)
2043 return bidirectional_iterator_tag{};
2044 else if constexpr (forward_range<_Base>)
2045 return forward_iterator_tag{};
2047 return input_iterator_tag{};
2050 _Base_iter _M_current = _Base_iter();
2051 [[no_unique_address]] _Func_handle _M_fun;
2054 using iterator_concept =
decltype(_S_iter_concept());
2057 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2058 range_reference_t<_Base>>>;
2059 using difference_type = range_difference_t<_Base>;
2061 _Iterator()
requires default_initializable<_Base_iter> = default;
2064 _Iterator(_Func_handle __fun, _Base_iter __current)
2065 : _M_current(std::move(__current)), _M_fun(__fun)
2069 _Iterator(_Parent* __parent, _Base_iter __current)
2070 : _M_current(std::move(__current)), _M_fun(*__parent->_M_fun)
2074 _Iterator(_Iterator<!_Const> __i)
2076 && convertible_to<iterator_t<_Vp>, _Base_iter>
2077 : _M_current(
std::move(__i._M_current)), _M_fun(__i._M_fun)
2080 constexpr const _Base_iter&
2081 base() const & noexcept
2082 {
return _M_current; }
2084 constexpr _Base_iter
2088 constexpr decltype(
auto)
2090 noexcept(
noexcept(_M_fun._M_call_deref(_M_current)))
2091 {
return _M_fun._M_call_deref(_M_current); }
2093 constexpr _Iterator&
2105 operator++(
int)
requires forward_range<_Base>
2112 constexpr _Iterator&
2113 operator--()
requires bidirectional_range<_Base>
2120 operator--(
int)
requires bidirectional_range<_Base>
2127 constexpr _Iterator&
2128 operator+=(difference_type __n)
requires random_access_range<_Base>
2134 constexpr _Iterator&
2135 operator-=(difference_type __n)
requires random_access_range<_Base>
2141 constexpr decltype(
auto)
2142 operator[](difference_type __n)
const
2143 requires random_access_range<_Base>
2144 {
return _M_fun._M_call_subscript(__n, _M_current); }
2146 friend constexpr bool
2147 operator==(
const _Iterator& __x,
const _Iterator& __y)
2148 requires equality_comparable<_Base_iter>
2149 {
return __x._M_current == __y._M_current; }
2151 friend constexpr bool
2152 operator<(
const _Iterator& __x,
const _Iterator& __y)
2153 requires random_access_range<_Base>
2154 {
return __x._M_current < __y._M_current; }
2156 friend constexpr bool
2157 operator>(
const _Iterator& __x,
const _Iterator& __y)
2158 requires random_access_range<_Base>
2159 {
return __y < __x; }
2161 friend constexpr bool
2162 operator<=(
const _Iterator& __x,
const _Iterator& __y)
2163 requires random_access_range<_Base>
2164 {
return !(__y < __x); }
2166 friend constexpr bool
2167 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2168 requires random_access_range<_Base>
2169 {
return !(__x < __y); }
2171#ifdef __cpp_lib_three_way_comparison
2172 friend constexpr auto
2173 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2174 requires random_access_range<_Base>
2175 && three_way_comparable<_Base_iter>
2176 {
return __x._M_current <=> __y._M_current; }
2179 friend constexpr _Iterator
2180 operator+(_Iterator __i, difference_type __n)
2181 requires random_access_range<_Base>
2182 {
return {__i._M_fun, __i._M_current + __n}; }
2184 friend constexpr _Iterator
2185 operator+(difference_type __n, _Iterator __i)
2186 requires random_access_range<_Base>
2187 {
return {__i._M_fun, __i._M_current + __n}; }
2189 friend constexpr _Iterator
2190 operator-(_Iterator __i, difference_type __n)
2191 requires random_access_range<_Base>
2192 {
return {__i._M_fun, __i._M_current - __n}; }
2196 friend constexpr difference_type
2197 operator-(
const _Iterator& __x,
const _Iterator& __y)
2198 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2199 {
return __x._M_current - __y._M_current; }
2201 friend constexpr decltype(
auto)
2202 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2204 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2210 friend _Iterator<!_Const>;
2211 template<
bool>
friend struct _Sentinel;
2214 template<
bool _Const>
2218 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2219 using _Base = transform_view::_Base<_Const>;
2221 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2224 _Sentinel() =
default;
2227 _Sentinel(sentinel_t<_Base> __end)
2232 _Sentinel(_Sentinel<!_Const> __i)
2234 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2238 constexpr sentinel_t<_Base>
2242 template<
bool _Const2>
2243 requires sentinel_for<sentinel_t<_Base>,
2244 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2245 friend constexpr bool
2246 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2247 {
return __x._M_current == __y._M_end; }
2249 template<
bool _Const2,
2250 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2251 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2252 friend constexpr range_difference_t<_Base2>
2253 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2254 {
return -(__y._M_end - __x._M_current); }
2256 template<
bool _Const2,
2257 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2258 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2259 friend constexpr range_difference_t<_Base2>
2260 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2261 {
return __y._M_end - __x._M_current; }
2263 friend _Sentinel<!_Const>;
2266 _Vp _M_base = _Vp();
2267 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2270 transform_view()
requires (default_initializable<_Vp>
2271 && default_initializable<_Fp>)
2275 transform_view(_Vp __base, _Fp __fun)
2276 : _M_base(std::move(
__base)), _M_fun(std::move(__fun))
2280 base() const& requires copy_constructible<_Vp>
2281 {
return _M_base ; }
2287 constexpr _Iterator<false>
2289 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2291 constexpr _Iterator<true>
2293 requires range<const _Vp>
2294 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2295 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2297 constexpr _Sentinel<false>
2299 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2301 constexpr _Iterator<false>
2302 end()
requires common_range<_Vp>
2303 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2305 constexpr _Sentinel<true>
2307 requires range<const _Vp>
2308 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2309 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2311 constexpr _Iterator<true>
2313 requires common_range<const _Vp>
2314 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2315 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2318 size()
requires sized_range<_Vp>
2319 {
return ranges::size(_M_base); }
2322 size() const requires sized_range<const _Vp>
2323 {
return ranges::size(_M_base); }
2326 template<
typename _Range,
typename _Fp>
2327 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2333 template<
typename _Range,
typename _Fp>
2334 concept __can_transform_view
2338 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2340 template<viewable_range _Range,
typename _Fp>
2341 requires __detail::__can_transform_view<_Range, _Fp>
2343 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2348 using _RangeAdaptor<_Transform>::operator();
2349 static constexpr int _S_arity = 2;
2350 static constexpr bool _S_has_simple_extra_args =
true;
2353 inline constexpr _Transform transform;
2360 template<
bool _Const>
2361 using _CI = counted_iterator<
2362 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2364 template<
bool _Const>
2368 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2369 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2372 _Sentinel() =
default;
2375 _Sentinel(sentinel_t<_Base> __end)
2380 _Sentinel(_Sentinel<!_Const> __s)
2381 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2385 constexpr sentinel_t<_Base>
2389 friend constexpr bool
2390 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2391 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2393 template<
bool _OtherConst = !_Const,
2394 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2395 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2396 friend constexpr bool
2397 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2398 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2400 friend _Sentinel<!_Const>;
2403 _Vp _M_base = _Vp();
2404 range_difference_t<_Vp> _M_count = 0;
2407 take_view()
requires default_initializable<_Vp> = default;
2410 take_view(_Vp __base, range_difference_t<_Vp> __count)
2411 : _M_base(std::move(__base)), _M_count(std::move(__count))
2415 base() const& requires copy_constructible<_Vp>
2423 begin()
requires (!__detail::__simple_view<_Vp>)
2425 if constexpr (sized_range<_Vp>)
2427 if constexpr (random_access_range<_Vp>)
2428 return ranges::begin(_M_base);
2432 return counted_iterator(ranges::begin(_M_base), __sz);
2436 return counted_iterator(ranges::begin(_M_base), _M_count);
2440 begin() const requires range<const _Vp>
2442 if constexpr (sized_range<const _Vp>)
2444 if constexpr (random_access_range<const _Vp>)
2445 return ranges::begin(_M_base);
2449 return counted_iterator(ranges::begin(_M_base), __sz);
2453 return counted_iterator(ranges::begin(_M_base), _M_count);
2457 end()
requires (!__detail::__simple_view<_Vp>)
2459 if constexpr (sized_range<_Vp>)
2461 if constexpr (random_access_range<_Vp>)
2462 return ranges::begin(_M_base) + size();
2467 return _Sentinel<false>{ranges::end(_M_base)};
2471 end() const requires range<const _Vp>
2473 if constexpr (sized_range<const _Vp>)
2475 if constexpr (random_access_range<const _Vp>)
2476 return ranges::begin(_M_base) + size();
2481 return _Sentinel<true>{ranges::end(_M_base)};
2485 size()
requires sized_range<_Vp>
2487 auto __n = ranges::size(_M_base);
2488 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2492 size() const requires sized_range<const _Vp>
2494 auto __n = ranges::size(_M_base);
2495 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2502 template<
typename _Range>
2503 take_view(_Range&&, range_difference_t<_Range>)
2504 -> take_view<views::all_t<_Range>>;
2506 template<
typename _Tp>
2507 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2508 = enable_borrowed_range<_Tp>;
2514 template<
typename _Range>
2515 inline constexpr bool __is_empty_view =
false;
2517 template<
typename _Tp>
2518 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2520 template<
typename _Range>
2521 inline constexpr bool __is_basic_string_view =
false;
2523 template<
typename _CharT,
typename _Traits>
2524 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2527 using ranges::__detail::__is_subrange;
2529 template<
typename _Range>
2530 inline constexpr bool __is_iota_view =
false;
2532 template<
typename _Winc,
typename _Bound>
2533 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2535 template<
typename _Range>
2536 inline constexpr bool __is_repeat_view =
false;
2538 template<
typename _Range>
2540 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2542 template<
typename _Range,
typename _Dp>
2543 concept __can_take_view
2547 struct _Take : __adaptor::_RangeAdaptor<_Take>
2549 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2550 requires __detail::__can_take_view<_Range, _Dp>
2552 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2554 using _Tp = remove_cvref_t<_Range>;
2555 if constexpr (__detail::__is_empty_view<_Tp>)
2557#ifdef __cpp_lib_optional_range_support
2558 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2561 else if constexpr (random_access_range<_Tp>
2563 && (std::__detail::__is_span<_Tp>
2564 || __detail::__is_basic_string_view<_Tp>
2565 || __detail::__is_subrange<_Tp>
2566 || __detail::__is_iota_view<_Tp>))
2569 auto __begin = ranges::begin(__r);
2570 auto __end = __begin + __n;
2571 if constexpr (std::__detail::__is_span<_Tp>)
2572 return span<typename _Tp::element_type>(__begin, __end);
2573 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2574 return _Tp(__begin, __end);
2575 else if constexpr (__detail::__is_subrange<_Tp>)
2576 return subrange<iterator_t<_Tp>>(__begin, __end);
2578 return iota_view(*__begin, *__end);
2580 else if constexpr (__detail::__is_repeat_view<_Tp>)
2586 using _RangeAdaptor<_Take>::operator();
2587 static constexpr int _S_arity = 2;
2591 template<
typename _Tp>
2592 static constexpr bool _S_has_simple_extra_args
2593 = ranges::__detail::__is_integer_like<_Tp>;
2596 inline constexpr _Take take;
2599 template<view _Vp,
typename _Pred>
2601 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2602 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2604 template<
bool _Const>
2608 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2610 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2611 const _Pred* _M_pred =
nullptr;
2614 _Sentinel() =
default;
2617 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2618 : _M_end(__end), _M_pred(__pred)
2622 _Sentinel(_Sentinel<!_Const> __s)
2623 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2624 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2627 constexpr sentinel_t<_Base>
2628 base()
const {
return _M_end; }
2630 friend constexpr bool
2631 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2632 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2634 template<
bool _OtherConst = !_Const,
2635 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2636 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2637 friend constexpr bool
2638 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2639 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2641 friend _Sentinel<!_Const>;
2644 _Vp _M_base = _Vp();
2645 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2648 take_while_view()
requires (default_initializable<_Vp>
2649 && default_initializable<_Pred>)
2653 take_while_view(_Vp __base, _Pred __pred)
2654 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2658 base() const& requires copy_constructible<_Vp>
2665 constexpr const _Pred&
2667 {
return *_M_pred; }
2670 begin()
requires (!__detail::__simple_view<_Vp>)
2671 {
return ranges::begin(_M_base); }
2674 begin() const requires range<const _Vp>
2675 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2676 {
return ranges::begin(_M_base); }
2679 end()
requires (!__detail::__simple_view<_Vp>)
2680 {
return _Sentinel<false>(ranges::end(_M_base),
2684 end() const requires range<const _Vp>
2685 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2686 {
return _Sentinel<true>(ranges::end(_M_base),
2690 template<
typename _Range,
typename _Pred>
2691 take_while_view(_Range&&, _Pred)
2692 -> take_while_view<views::all_t<_Range>, _Pred>;
2698 template<
typename _Range,
typename _Pred>
2699 concept __can_take_while_view
2703 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2705 template<viewable_range _Range,
typename _Pred>
2706 requires __detail::__can_take_while_view<_Range, _Pred>
2708 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2713 using _RangeAdaptor<_TakeWhile>::operator();
2714 static constexpr int _S_arity = 2;
2715 static constexpr bool _S_has_simple_extra_args =
true;
2718 inline constexpr _TakeWhile take_while;
2725 _Vp _M_base = _Vp();
2726 range_difference_t<_Vp> _M_count = 0;
2730 static constexpr bool _S_needs_cached_begin
2731 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2732 [[no_unique_address]]
2733 __detail::__maybe_present_t<_S_needs_cached_begin,
2734 __detail::_CachedPosition<_Vp>>
2738 drop_view()
requires default_initializable<_Vp> = default;
2741 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2742 : _M_base(std::move(__base)), _M_count(__count)
2743 { __glibcxx_assert(__count >= 0); }
2746 base() const& requires copy_constructible<_Vp>
2756 requires (!(__detail::__simple_view<_Vp>
2757 && random_access_range<const _Vp>
2758 && sized_range<const _Vp>))
2760 if constexpr (_S_needs_cached_begin)
2761 if (_M_cached_begin._M_has_value())
2762 return _M_cached_begin._M_get(_M_base);
2764 auto __it = ranges::next(ranges::begin(_M_base),
2765 _M_count, ranges::end(_M_base));
2766 if constexpr (_S_needs_cached_begin)
2767 _M_cached_begin._M_set(_M_base, __it);
2775 requires random_access_range<const _Vp> && sized_range<const _Vp>
2777 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2782 end()
requires (!__detail::__simple_view<_Vp>)
2783 {
return ranges::end(_M_base); }
2786 end() const requires range<const _Vp>
2787 {
return ranges::end(_M_base); }
2790 size()
requires sized_range<_Vp>
2792 const auto __s = ranges::size(_M_base);
2793 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2794 return __s < __c ? 0 : __s - __c;
2798 size() const requires sized_range<const _Vp>
2800 const auto __s = ranges::size(_M_base);
2801 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2802 return __s < __c ? 0 : __s - __c;
2806 template<
typename _Range>
2807 drop_view(_Range&&, range_difference_t<_Range>)
2808 -> drop_view<views::all_t<_Range>>;
2810 template<
typename _Tp>
2811 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2812 = enable_borrowed_range<_Tp>;
2818 template<
typename _Range>
2820 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2822 template<
typename _Range,
typename _Dp>
2823 concept __can_drop_view
2827 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2829 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2830 requires __detail::__can_drop_view<_Range, _Dp>
2832 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2834 using _Tp = remove_cvref_t<_Range>;
2835 if constexpr (__detail::__is_empty_view<_Tp>)
2837#ifdef __cpp_lib_optional_range_support
2838 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2841 else if constexpr (random_access_range<_Tp>
2843 && (std::__detail::__is_span<_Tp>
2844 || __detail::__is_basic_string_view<_Tp>
2845 || __detail::__is_iota_view<_Tp>
2846 || __detail::__is_subrange<_Tp>))
2849 auto __begin = ranges::begin(__r) + __n;
2850 auto __end = ranges::end(__r);
2851 if constexpr (std::__detail::__is_span<_Tp>)
2852 return span<typename _Tp::element_type>(__begin, __end);
2853 else if constexpr (__detail::__is_subrange<_Tp>)
2855 if constexpr (_Tp::_S_store_size)
2857 using ranges::__detail::__to_unsigned_like;
2858 auto __m = ranges::distance(__r) - __n;
2859 return _Tp(__begin, __end, __to_unsigned_like(__m));
2862 return _Tp(__begin, __end);
2865 return _Tp(__begin, __end);
2867 else if constexpr (__detail::__is_repeat_view<_Tp>)
2873 using _RangeAdaptor<_Drop>::operator();
2874 static constexpr int _S_arity = 2;
2875 template<
typename _Tp>
2876 static constexpr bool _S_has_simple_extra_args
2877 = _Take::_S_has_simple_extra_args<_Tp>;
2880 inline constexpr _Drop drop;
2883 template<view _Vp,
typename _Pred>
2885 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2886 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2889 _Vp _M_base = _Vp();
2890 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2891 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2894 drop_while_view()
requires (default_initializable<_Vp>
2895 && default_initializable<_Pred>)
2899 drop_while_view(_Vp __base, _Pred __pred)
2900 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2904 base() const& requires copy_constructible<_Vp>
2911 constexpr const _Pred&
2913 {
return *_M_pred; }
2918 if (_M_cached_begin._M_has_value())
2919 return _M_cached_begin._M_get(_M_base);
2921 __glibcxx_assert(_M_pred.has_value());
2922 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2923 ranges::end(_M_base),
2925 _M_cached_begin._M_set(_M_base, __it);
2931 {
return ranges::end(_M_base); }
2934 template<
typename _Range,
typename _Pred>
2935 drop_while_view(_Range&&, _Pred)
2936 -> drop_while_view<views::all_t<_Range>, _Pred>;
2938 template<
typename _Tp,
typename _Pred>
2939 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2940 = enable_borrowed_range<_Tp>;
2946 template<
typename _Range,
typename _Pred>
2947 concept __can_drop_while_view
2951 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2953 template<viewable_range _Range,
typename _Pred>
2954 requires __detail::__can_drop_while_view<_Range, _Pred>
2956 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2962 using _RangeAdaptor<_DropWhile>::operator();
2963 static constexpr int _S_arity = 2;
2964 static constexpr bool _S_has_simple_extra_args =
true;
2967 inline constexpr _DropWhile drop_while;
2972 template<
typename _Tp>
2974 __as_lvalue(_Tp&& __t)
2975 {
return static_cast<_Tp&
>(__t); }
2978 template<input_range _Vp>
2983 using _InnerRange = range_reference_t<_Vp>;
2985 template<
bool _Const>
2986 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2988 template<
bool _Const>
2989 using _Outer_iter = iterator_t<_Base<_Const>>;
2991 template<
bool _Const>
2992 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2994 template<
bool _Const>
2995 static constexpr bool _S_ref_is_glvalue
2996 = is_reference_v<range_reference_t<_Base<_Const>>>;
2998 template<
bool _Const>
3002 template<
bool _Const>
3003 requires _S_ref_is_glvalue<_Const>
3004 && forward_range<_Base<_Const>>
3005 && forward_range<range_reference_t<_Base<_Const>>>
3006 struct __iter_cat<_Const>
3009 static constexpr auto
3012 using _Outer_iter = join_view::_Outer_iter<_Const>;
3013 using _Inner_iter = join_view::_Inner_iter<_Const>;
3014 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
3015 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
3016 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
3017 && derived_from<_InnerCat, bidirectional_iterator_tag>
3018 && common_range<range_reference_t<_Base<_Const>>>)
3019 return bidirectional_iterator_tag{};
3020 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
3021 && derived_from<_InnerCat, forward_iterator_tag>)
3022 return forward_iterator_tag{};
3024 return input_iterator_tag{};
3027 using iterator_category =
decltype(_S_iter_cat());
3030 template<
bool _Const>
3033 template<
bool _Const>
3034 struct _Iterator : __iter_cat<_Const>
3037 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3038 using _Base = join_view::_Base<_Const>;
3042 static constexpr bool _S_ref_is_glvalue
3043 = join_view::_S_ref_is_glvalue<_Const>;
3048 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
3049 if constexpr (_S_ref_is_glvalue)
3052 return _M_parent->_M_inner._M_emplace_deref(__x);
3055 _Outer_iter& __outer = _M_get_outer();
3056 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
3058 auto&& __inner = __update_inner(__outer);
3059 _M_inner = ranges::begin(__inner);
3060 if (_M_inner != ranges::end(__inner))
3064 if constexpr (_S_ref_is_glvalue)
3066 if constexpr (forward_iterator<_Inner_iter>)
3067 _M_inner = _Inner_iter();
3073 static constexpr auto
3076 if constexpr (_S_ref_is_glvalue
3077 && bidirectional_range<_Base>
3078 && bidirectional_range<range_reference_t<_Base>>
3079 && common_range<range_reference_t<_Base>>)
3080 return bidirectional_iterator_tag{};
3081 else if constexpr (_S_ref_is_glvalue
3082 && forward_range<_Base>
3083 && forward_range<range_reference_t<_Base>>)
3084 return forward_iterator_tag{};
3086 return input_iterator_tag{};
3089 using _Outer_iter = join_view::_Outer_iter<_Const>;
3090 using _Inner_iter = join_view::_Inner_iter<_Const>;
3092 constexpr _Outer_iter&
3095 if constexpr (forward_range<_Base>)
3098 return *_M_parent->_M_outer;
3101 constexpr const _Outer_iter&
3102 _M_get_outer()
const
3104 if constexpr (forward_range<_Base>)
3107 return *_M_parent->_M_outer;
3110 constexpr _Inner_iter&
3111 _M_get_inner() noexcept
3113 if constexpr (forward_iterator<_Inner_iter>)
3119 constexpr const _Inner_iter&
3120 _M_get_inner() const noexcept
3122 if constexpr (forward_iterator<_Inner_iter>)
3129 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
3130 : _M_outer(
std::move(__outer)), _M_parent(__parent)
3134 _Iterator(_Parent* __parent, _Outer_iter __outer, _Inner_iter __inner)
3135 requires forward_range<_Base>
3141 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
3142 : _M_parent(__parent)
3145 [[no_unique_address]]
3146 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
3147 =
decltype(_M_outer)();
3148 __conditional_t<forward_iterator<_Inner_iter>,
3149 _Inner_iter, optional<_Inner_iter>> _M_inner
3150 =
decltype(_M_inner)();
3151 _Parent* _M_parent =
nullptr;
3154 using iterator_concept =
decltype(_S_iter_concept());
3156 using value_type = range_value_t<range_reference_t<_Base>>;
3157 using difference_type
3159 range_difference_t<range_reference_t<_Base>>>;
3161 _Iterator() =
default;
3164 _Iterator(_Iterator<!_Const> __i)
3166 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3167 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3169 _M_parent(__i._M_parent)
3172 constexpr decltype(
auto)
3174 {
return *_M_get_inner(); }
3178 constexpr _Inner_iter
3180 requires __detail::__has_arrow<_Inner_iter>
3181 && copyable<_Inner_iter>
3182 {
return _M_get_inner(); }
3184 constexpr _Iterator&
3187 auto&& __inner_range = [
this] () ->
auto&& {
3188 if constexpr (_S_ref_is_glvalue)
3189 return *_M_get_outer();
3191 return *_M_parent->_M_inner;
3193 if (++_M_get_inner() == ranges::end(__inner_range))
3207 requires _S_ref_is_glvalue && forward_range<_Base>
3208 && forward_range<range_reference_t<_Base>>
3215 constexpr _Iterator&
3217 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3218 && bidirectional_range<range_reference_t<_Base>>
3219 && common_range<range_reference_t<_Base>>
3221 if (_M_outer == ranges::end(_M_parent->_M_base))
3222 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3223 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3224 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3231 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3232 && bidirectional_range<range_reference_t<_Base>>
3233 && common_range<range_reference_t<_Base>>
3240 friend constexpr bool
3241 operator==(
const _Iterator& __x,
const _Iterator& __y)
3242 requires _S_ref_is_glvalue
3243 && forward_range<_Base>
3244 && equality_comparable<_Inner_iter>
3246 return (__x._M_outer == __y._M_outer
3247 && __x._M_inner == __y._M_inner);
3250 friend constexpr decltype(
auto)
3251 iter_move(
const _Iterator& __i)
3252 noexcept(
noexcept(ranges::iter_move(__i._M_get_inner())))
3253 {
return ranges::iter_move(__i._M_get_inner()); }
3255 friend constexpr void
3256 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3257 noexcept(
noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3258 requires indirectly_swappable<_Inner_iter>
3259 {
return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3261 friend _Iterator<!_Const>;
3262 template<
bool>
friend struct _Sentinel;
3264 template<
typename _Fn>
3265 static constexpr _Iterator
3266 _S_for_each_segment(_Iterator __first, _Iterator __last, _Fn __func)
3268 _Inner_iter __first_inner = __first._M_get_inner();
3269 _Outer_iter __first_outer = __first._M_get_outer();
3270 _Inner_iter __last_inner = __last._M_get_inner();
3271 _Outer_iter __last_outer = __last._M_get_outer();
3273 if (__first_outer == __last_outer)
3275 auto __ret = __func(__first_inner, __last_inner);
3276 return _Iterator(__first._M_parent, __first_outer, __ret);
3280 auto __end = ranges::end(*__first_outer);
3281 auto __ret = __func(__first_inner, __end);
3283 return _Iterator(__first._M_parent, __first_outer, __ret);
3285 while (++__first_outer != __last_outer)
3287 __end = ranges::end(*__first_outer);
3288 __ret = __func(ranges::begin(*__first_outer), __end);
3290 return _Iterator(__first._M_parent, __first_outer, __ret);
3293 if (__last != __last._M_parent->end())
3295 __end = __last_inner;
3296 __ret = __func(ranges::begin(*__last_outer), __end);
3298 return _Iterator(__first._M_parent, __first_outer, __ret);
3305 static constexpr bool _S_enable_for_each_segment
3306 = forward_iterator<_Iterator>;
3309 template<
bool _Const>
3313 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3314 using _Base = join_view::_Base<_Const>;
3316 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3319 _Sentinel() =
default;
3322 _Sentinel(_Parent* __parent)
3323 : _M_end(ranges::end(__parent->_M_base))
3327 _Sentinel(_Sentinel<!_Const> __s)
3328 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3332 template<
bool _Const2>
3333 requires sentinel_for<sentinel_t<_Base>,
3334 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3335 friend constexpr bool
3336 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3337 {
return __x._M_get_outer() == __y._M_end; }
3339 friend _Sentinel<!_Const>;
3342 _Vp _M_base = _Vp();
3343 [[no_unique_address]]
3344 __detail::__maybe_present_t<!forward_range<_Vp>,
3345 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3346 [[no_unique_address]]
3347 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3350 join_view()
requires default_initializable<_Vp> = default;
3353 join_view(_Vp __base)
3354 : _M_base(std::move(__base))
3358 base() const& requires copy_constructible<_Vp>
3368 if constexpr (forward_range<_Vp>)
3370 constexpr bool __use_const
3371 = (__detail::__simple_view<_Vp>
3372 && is_reference_v<range_reference_t<_Vp>>);
3373 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3377 _M_outer = ranges::begin(_M_base);
3378 return _Iterator<false>{
this};
3384 requires forward_range<const _Vp>
3385 && is_reference_v<range_reference_t<const _Vp>>
3386 && input_range<range_reference_t<const _Vp>>
3388 return _Iterator<true>{
this, ranges::begin(_M_base)};
3394 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3395 && forward_range<_InnerRange>
3396 && common_range<_Vp> && common_range<_InnerRange>)
3397 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3398 ranges::end(_M_base)};
3400 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3405 requires forward_range<const _Vp>
3406 && is_reference_v<range_reference_t<const _Vp>>
3407 && input_range<range_reference_t<const _Vp>>
3409 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3410 && forward_range<range_reference_t<const _Vp>>
3411 && common_range<const _Vp>
3412 && common_range<range_reference_t<const _Vp>>)
3413 return _Iterator<true>{
this, ranges::end(_M_base)};
3415 return _Sentinel<true>{
this};
3419 template<
typename _Range>
3420 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3426 template<
typename _Range>
3427 concept __can_join_view
3431 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3433 template<viewable_range _Range>
3434 requires __detail::__can_join_view<_Range>
3436 operator() [[nodiscard]] (_Range&& __r)
const
3443 static constexpr bool _S_has_simple_call_op =
true;
3446 inline constexpr _Join join;
3452 struct __require_constant;
3454 template<
typename _Range>
3455 concept __tiny_range = sized_range<_Range>
3457 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3458 && (remove_reference_t<_Range>::size() <= 1);
3460 template<
typename _Base>
3461 struct __lazy_split_view_outer_iter_cat
3464 template<forward_range _Base>
3465 struct __lazy_split_view_outer_iter_cat<_Base>
3466 {
using iterator_category = input_iterator_tag; };
3468 template<
typename _Base>
3469 struct __lazy_split_view_inner_iter_cat
3472 template<forward_range _Base>
3473 struct __lazy_split_view_inner_iter_cat<_Base>
3476 static constexpr auto
3479 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3480 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3481 return forward_iterator_tag{};
3486 using iterator_category =
decltype(_S_iter_cat());
3490 template<input_range _Vp, forward_range _Pattern>
3492 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3495 class lazy_split_view : public
view_interface<lazy_split_view<_Vp, _Pattern>>
3498 template<
bool _Const>
3499 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3501 template<
bool _Const>
3504 template<
bool _Const>
3506 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3509 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3510 using _Base = lazy_split_view::_Base<_Const>;
3517 __current() noexcept
3519 if constexpr (forward_range<_Vp>)
3522 return *_M_parent->_M_current;
3526 __current() const noexcept
3528 if constexpr (forward_range<_Vp>)
3531 return *_M_parent->_M_current;
3534 _Parent* _M_parent =
nullptr;
3536 [[no_unique_address]]
3537 __detail::__maybe_present_t<forward_range<_Vp>,
3538 iterator_t<_Base>> _M_current
3539 =
decltype(_M_current)();
3540 bool _M_trailing_empty =
false;
3543 using iterator_concept = __conditional_t<forward_range<_Base>,
3544 forward_iterator_tag,
3545 input_iterator_tag>;
3547 using difference_type = range_difference_t<_Base>;
3549 struct value_type : view_interface<value_type>
3552 _OuterIter _M_i = _OuterIter();
3558 value_type(_OuterIter __i)
3559 : _M_i(std::move(__i))
3565 constexpr _InnerIter<_Const>
3567 {
return _InnerIter<_Const>{_M_i}; }
3569 constexpr default_sentinel_t
3570 end() const noexcept
3574 _OuterIter() =
default;
3577 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3578 : _M_parent(__parent)
3582 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3583 requires forward_range<_Base>
3584 : _M_parent(__parent),
3589 _OuterIter(_OuterIter<!_Const> __i)
3591 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3592 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3593 _M_trailing_empty(__i._M_trailing_empty)
3596 constexpr value_type
3598 {
return value_type{*
this}; }
3600 constexpr _OuterIter&
3605 const auto __end = ranges::end(_M_parent->_M_base);
3606 if (__current() == __end)
3608 _M_trailing_empty =
false;
3611 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3612 if (__pbegin == __pend)
3614 else if constexpr (__detail::__tiny_range<_Pattern>)
3616 __current() = ranges::find(
std::move(__current()), __end,
3618 if (__current() != __end)
3621 if (__current() == __end)
3622 _M_trailing_empty =
true;
3629 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3633 if (__current() == __end)
3634 _M_trailing_empty =
true;
3637 }
while (++__current() != __end);
3641 constexpr decltype(
auto)
3644 if constexpr (forward_range<_Base>)
3654 friend constexpr bool
3655 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3656 requires forward_range<_Base>
3658 return __x._M_current == __y._M_current
3659 && __x._M_trailing_empty == __y._M_trailing_empty;
3662 friend constexpr bool
3663 operator==(
const _OuterIter& __x, default_sentinel_t)
3665 return __x.__current() == ranges::end(__x._M_parent->_M_base)
3666 && !__x._M_trailing_empty;
3669 friend _OuterIter<!_Const>;
3670 friend _InnerIter<_Const>;
3673 template<
bool _Const>
3675 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3678 using _Base = lazy_split_view::_Base<_Const>;
3683 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3684 auto __end = ranges::end(_M_i._M_parent->_M_base);
3685 if constexpr (__detail::__tiny_range<_Pattern>)
3687 const auto& __cur = _M_i_current();
3690 if (__pcur == __pend)
3691 return _M_incremented;
3692 return *__cur == *__pcur;
3696 auto __cur = _M_i_current();
3699 if (__pcur == __pend)
3700 return _M_incremented;
3703 if (*__cur != *__pcur)
3705 if (++__pcur == __pend)
3707 }
while (++__cur != __end);
3713 _M_i_current() noexcept
3714 {
return _M_i.__current(); }
3717 _M_i_current() const noexcept
3718 {
return _M_i.__current(); }
3720 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3721 bool _M_incremented =
false;
3724 using iterator_concept
3725 =
typename _OuterIter<_Const>::iterator_concept;
3727 using value_type = range_value_t<_Base>;
3728 using difference_type = range_difference_t<_Base>;
3730 _InnerIter() =
default;
3733 _InnerIter(_OuterIter<_Const> __i)
3734 : _M_i(std::move(__i))
3737 constexpr const iterator_t<_Base>&
3738 base() const& noexcept
3739 {
return _M_i_current(); }
3741 constexpr iterator_t<_Base>
3742 base() &&
requires forward_range<_Vp>
3745 constexpr decltype(
auto)
3747 {
return *_M_i_current(); }
3749 constexpr _InnerIter&
3752 _M_incremented =
true;
3753 if constexpr (!forward_range<_Base>)
3754 if constexpr (_Pattern::size() == 0)
3760 constexpr decltype(
auto)
3763 if constexpr (forward_range<_Base>)
3773 friend constexpr bool
3774 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3775 requires forward_range<_Base>
3776 {
return __x._M_i == __y._M_i; }
3778 friend constexpr bool
3779 operator==(
const _InnerIter& __x, default_sentinel_t)
3780 {
return __x.__at_end(); }
3782 friend constexpr decltype(
auto)
3783 iter_move(
const _InnerIter& __i)
3784 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3785 {
return ranges::iter_move(__i._M_i_current()); }
3787 friend constexpr void
3788 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3789 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3790 __y._M_i_current())))
3791 requires indirectly_swappable<iterator_t<_Base>>
3792 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3795 _Vp _M_base = _Vp();
3796 _Pattern _M_pattern = _Pattern();
3797 [[no_unique_address]]
3798 __detail::__maybe_present_t<!forward_range<_Vp>,
3799 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3803 lazy_split_view()
requires (default_initializable<_Vp>
3804 && default_initializable<_Pattern>)
3808 lazy_split_view(_Vp __base, _Pattern __pattern)
3809 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3812 template<input_range _Range>
3813 requires constructible_from<_Vp, views::all_t<_Range>>
3814 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3816 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3817 : _M_base(views::all(std::
forward<_Range>(__r))),
3818 _M_pattern(views::single(std::move(__e)))
3822 base() const& requires copy_constructible<_Vp>
3832 if constexpr (forward_range<_Vp>)
3834 constexpr bool __simple
3835 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3836 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3840 _M_current = ranges::begin(_M_base);
3841 return _OuterIter<false>{
this};
3849 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3850 && forward_range<const _Pattern>
3852 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3856 end()
requires forward_range<_Vp> && common_range<_Vp>
3858 constexpr bool __simple
3859 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3860 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3866 if constexpr (forward_range<_Vp>
3867 && forward_range<const _Vp>
3868 && common_range<const _Vp>
3869 && forward_range<const _Pattern>)
3870 return _OuterIter<true>{
this, ranges::end(_M_base)};
3876 template<
typename _Range,
typename _Pattern>
3877 lazy_split_view(_Range&&, _Pattern&&)
3878 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3880 template<input_range _Range>
3881 lazy_split_view(_Range&&, range_value_t<_Range>)
3888 template<
typename _Range,
typename _Pattern>
3889 concept __can_lazy_split_view
3893 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3895 template<viewable_range _Range,
typename _Pattern>
3896 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3898 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3903 using _RangeAdaptor<_LazySplit>::operator();
3904 static constexpr int _S_arity = 2;
3909 template<
typename _Pattern>
3910 static constexpr bool _S_has_simple_extra_args
3911 = is_scalar_v<_Pattern> || (view<_Pattern>
3912 && copy_constructible<_Pattern>);
3915 inline constexpr _LazySplit lazy_split;
3918 template<forward_range _Vp, forward_range _Pattern>
3920 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3922 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3925 _Vp _M_base = _Vp();
3926 _Pattern _M_pattern = _Pattern();
3927 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3933 split_view()
requires (default_initializable<_Vp>
3934 && default_initializable<_Pattern>)
3938 split_view(_Vp __base, _Pattern __pattern)
3939 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3942 template<forward_range _Range>
3943 requires constructible_from<_Vp, views::all_t<_Range>>
3944 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3946 split_view(_Range&& __r, range_value_t<_Range> __e)
3947 : _M_base(views::all(std::
forward<_Range>(__r))),
3948 _M_pattern(views::single(std::move(__e)))
3952 base() const& requires copy_constructible<_Vp>
3962 if (!_M_cached_begin)
3963 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3964 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3970 if constexpr (common_range<_Vp>)
3971 return _Iterator{
this, ranges::end(_M_base), {}};
3973 return _Sentinel{
this};
3976 constexpr subrange<iterator_t<_Vp>>
3977 _M_find_next(iterator_t<_Vp> __it)
3979 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3980 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3992 split_view* _M_parent =
nullptr;
3993 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3994 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3995 bool _M_trailing_empty =
false;
3997 friend struct _Sentinel;
4000 using iterator_concept = forward_iterator_tag;
4001 using iterator_category = input_iterator_tag;
4002 using value_type = subrange<iterator_t<_Vp>>;
4003 using difference_type = range_difference_t<_Vp>;
4005 _Iterator() =
default;
4008 _Iterator(split_view* __parent,
4009 iterator_t<_Vp> __current,
4010 subrange<iterator_t<_Vp>> __next)
4011 : _M_parent(__parent),
4012 _M_cur(std::move(__current)),
4013 _M_next(std::move(__next))
4016 constexpr iterator_t<_Vp>
4020 constexpr value_type
4022 {
return {_M_cur, _M_next.begin()}; }
4024 constexpr _Iterator&
4027 _M_cur = _M_next.begin();
4028 if (_M_cur != ranges::end(_M_parent->_M_base))
4030 _M_cur = _M_next.end();
4031 if (_M_cur == ranges::end(_M_parent->_M_base))
4033 _M_trailing_empty =
true;
4034 _M_next = {_M_cur, _M_cur};
4037 _M_next = _M_parent->_M_find_next(_M_cur);
4040 _M_trailing_empty =
false;
4052 friend constexpr bool
4053 operator==(
const _Iterator& __x,
const _Iterator& __y)
4055 return __x._M_cur == __y._M_cur
4056 && __x._M_trailing_empty == __y._M_trailing_empty;
4063 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
4066 _Sentinel() =
default;
4069 _Sentinel(split_view* __parent)
4070 : _M_end(ranges::end(__parent->_M_base))
4073 friend constexpr bool
4074 operator==(
const _Iterator& __x,
const _Sentinel& __y)
4075 {
return __x._M_cur == __y._M_end && !__x._M_trailing_empty; }
4079 template<
typename _Range,
typename _Pattern>
4080 split_view(_Range&&, _Pattern&&)
4081 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
4083 template<forward_range _Range>
4084 split_view(_Range&&, range_value_t<_Range>)
4091 template<
typename _Range,
typename _Pattern>
4092 concept __can_split_view
4096 struct _Split : __adaptor::_RangeAdaptor<_Split>
4098 template<viewable_range _Range,
typename _Pattern>
4099 requires __detail::__can_split_view<_Range, _Pattern>
4101 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
4106 using _RangeAdaptor<_Split>::operator();
4107 static constexpr int _S_arity = 2;
4108 template<
typename _Pattern>
4109 static constexpr bool _S_has_simple_extra_args
4110 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
4113 inline constexpr _Split split;
4120 template<input_or_output_iterator _Iter>
4122 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
4124 if constexpr (contiguous_iterator<_Iter>)
4126 else if constexpr (random_access_iterator<_Iter>)
4127 return subrange(__i, __i + __n);
4129 return subrange(counted_iterator(
std::move(__i), __n),
4134 inline constexpr _Counted counted{};
4142 _Vp _M_base = _Vp();
4145 common_view()
requires default_initializable<_Vp> = default;
4148 common_view(_Vp __r)
4149 : _M_base(std::move(__r))
4153 base() const& requires copy_constructible<_Vp>
4163 begin()
requires (!__detail::__simple_view<_Vp>)
4166 return ranges::begin(_M_base);
4168 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4169 (ranges::begin(_M_base));
4176 return ranges::begin(_M_base);
4178 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4179 (ranges::begin(_M_base));
4183 end()
requires (!__detail::__simple_view<_Vp>)
4186 return ranges::begin(_M_base) + ranges::size(_M_base);
4188 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4189 (ranges::end(_M_base));
4193 end() const requires
range<const _Vp>
4196 return ranges::begin(_M_base) + ranges::size(_M_base);
4198 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4199 (ranges::end(_M_base));
4204 {
return ranges::size(_M_base); }
4208 {
return ranges::size(_M_base); }
4211 template<
typename _Range>
4212 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4214 template<
typename _Tp>
4215 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4216 = enable_borrowed_range<_Tp>;
4222 template<
typename _Range>
4223 concept __already_common = common_range<_Range>
4226 template<
typename _Range>
4227 concept __can_common_view
4231 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4233 template<viewable_range _Range>
4234 requires __detail::__already_common<_Range>
4235 || __detail::__can_common_view<_Range>
4237 operator() [[nodiscard]] (_Range&& __r)
const
4239 if constexpr (__detail::__already_common<_Range>)
4245 static constexpr bool _S_has_simple_call_op =
true;
4248 inline constexpr _Common common;
4256 static constexpr bool _S_needs_cached_begin
4257 = !common_range<_Vp> && !(random_access_range<_Vp>
4258 && sized_sentinel_for<sentinel_t<_Vp>,
4261 _Vp _M_base = _Vp();
4262 [[no_unique_address]]
4263 __detail::__maybe_present_t<_S_needs_cached_begin,
4264 __detail::_CachedPosition<_Vp>>
4268 reverse_view()
requires default_initializable<_Vp> = default;
4271 reverse_view(_Vp __r)
4272 : _M_base(std::move(__r))
4276 base() const& requires copy_constructible<_Vp>
4283 constexpr reverse_iterator<iterator_t<_Vp>>
4286 if constexpr (_S_needs_cached_begin)
4287 if (_M_cached_begin._M_has_value())
4290 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4291 if constexpr (_S_needs_cached_begin)
4292 _M_cached_begin._M_set(_M_base, __it);
4297 begin()
requires common_range<_Vp>
4301 begin() const requires common_range<const _Vp>
4304 constexpr reverse_iterator<iterator_t<_Vp>>
4309 end() const requires common_range<const _Vp>
4313 size()
requires sized_range<_Vp>
4314 {
return ranges::size(_M_base); }
4317 size() const requires sized_range<const _Vp>
4318 {
return ranges::size(_M_base); }
4321 template<
typename _Range>
4322 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4324 template<
typename _Tp>
4325 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4326 = enable_borrowed_range<_Tp>;
4333 inline constexpr bool __is_reversible_subrange =
false;
4335 template<
typename _Iter, subrange_kind _Kind>
4336 inline constexpr bool
4337 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4338 reverse_iterator<_Iter>,
4342 inline constexpr bool __is_reverse_view =
false;
4344 template<
typename _Vp>
4345 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4347 template<
typename _Range>
4348 concept __can_reverse_view
4352 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4354 template<viewable_range _Range>
4355 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4356 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4357 || __detail::__can_reverse_view<_Range>
4359 operator() [[nodiscard]] (_Range&& __r)
const
4361 using _Tp = remove_cvref_t<_Range>;
4362 if constexpr (__detail::__is_reverse_view<_Tp>)
4364#ifdef __cpp_lib_optional_range_support
4365 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
4368 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4370 using _Iter =
decltype(ranges::begin(__r).base());
4371 if constexpr (sized_range<_Tp>)
4372 return subrange<_Iter, _Iter, subrange_kind::sized>
4373 {__r.end().base(), __r.begin().base(), __r.size()};
4375 return subrange<_Iter, _Iter, subrange_kind::unsized>
4376 {__r.end().base(), __r.begin().base()};
4382 static constexpr bool _S_has_simple_call_op =
true;
4385 inline constexpr _Reverse reverse;
4390#if __cpp_lib_tuple_like
4393 template<
typename _Tp,
size_t _Nm>
4394 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>
4395 &&
requires(_Tp __t)
4397 { std::get<_Nm>(__t) }
4398 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4401 template<
typename _Tp,
size_t _Nm>
4402 concept __has_tuple_element =
requires(_Tp __t)
4404 typename tuple_size<_Tp>::type;
4405 requires _Nm < tuple_size_v<_Tp>;
4406 typename tuple_element_t<_Nm, _Tp>;
4407 { std::get<_Nm>(__t) }
4408 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4412 template<
typename _Tp,
size_t _Nm>
4413 concept __returnable_element
4414 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4417 template<input_range _Vp,
size_t _Nm>
4419 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4420 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4422 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4423 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4426 elements_view()
requires default_initializable<_Vp> = default;
4429 elements_view(_Vp __base)
4430 : _M_base(std::move(__base))
4434 base() const& requires copy_constructible<_Vp>
4442 begin()
requires (!__detail::__simple_view<_Vp>)
4443 {
return _Iterator<false>(ranges::begin(_M_base)); }
4446 begin() const requires range<const _Vp>
4447 {
return _Iterator<true>(ranges::begin(_M_base)); }
4450 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4451 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4454 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4455 {
return _Iterator<false>{ranges::end(_M_base)}; }
4458 end() const requires range<const _Vp>
4459 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4462 end() const requires common_range<const _Vp>
4463 {
return _Iterator<true>{ranges::end(_M_base)}; }
4466 size()
requires sized_range<_Vp>
4467 {
return ranges::size(_M_base); }
4470 size() const requires sized_range<const _Vp>
4471 {
return ranges::size(_M_base); }
4474 template<
bool _Const>
4475 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4477 template<
bool _Const>
4481 template<
bool _Const>
4482 requires forward_range<_Base<_Const>>
4483 struct __iter_cat<_Const>
4486 static auto _S_iter_cat()
4488 using _Base = elements_view::_Base<_Const>;
4489 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4490 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4491 if constexpr (!is_lvalue_reference_v<_Res>)
4492 return input_iterator_tag{};
4493 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4494 return random_access_iterator_tag{};
4499 using iterator_category =
decltype(_S_iter_cat());
4502 template<
bool _Const>
4505 template<
bool _Const>
4506 struct _Iterator : __iter_cat<_Const>
4509 using _Base = elements_view::_Base<_Const>;
4511 iterator_t<_Base> _M_current = iterator_t<_Base>();
4513 static constexpr decltype(
auto)
4514 _S_get_element(
const iterator_t<_Base>& __i)
4516 if constexpr (is_reference_v<range_reference_t<_Base>>)
4517 return std::get<_Nm>(*__i);
4520 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4521 return static_cast<_Et
>(std::get<_Nm>(*__i));
4528 if constexpr (random_access_range<_Base>)
4529 return random_access_iterator_tag{};
4530 else if constexpr (bidirectional_range<_Base>)
4531 return bidirectional_iterator_tag{};
4532 else if constexpr (forward_range<_Base>)
4533 return forward_iterator_tag{};
4535 return input_iterator_tag{};
4538 friend _Iterator<!_Const>;
4541 using iterator_concept =
decltype(_S_iter_concept());
4544 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4545 using difference_type = range_difference_t<_Base>;
4547 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4550 _Iterator(iterator_t<_Base> __current)
4551 : _M_current(std::move(__current))
4555 _Iterator(_Iterator<!_Const> __i)
4556 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4560 constexpr const iterator_t<_Base>&
4561 base() const& noexcept
4562 {
return _M_current; }
4564 constexpr iterator_t<_Base>
4568 constexpr decltype(
auto)
4570 {
return _S_get_element(_M_current); }
4572 constexpr _Iterator&
4584 operator++(
int)
requires forward_range<_Base>
4591 constexpr _Iterator&
4592 operator--()
requires bidirectional_range<_Base>
4599 operator--(
int)
requires bidirectional_range<_Base>
4606 constexpr _Iterator&
4607 operator+=(difference_type __n)
4608 requires random_access_range<_Base>
4614 constexpr _Iterator&
4615 operator-=(difference_type __n)
4616 requires random_access_range<_Base>
4622 constexpr decltype(
auto)
4623 operator[](difference_type __n)
const
4624 requires random_access_range<_Base>
4625 {
return _S_get_element(_M_current + __n); }
4627 friend constexpr bool
4628 operator==(
const _Iterator& __x,
const _Iterator& __y)
4629 requires equality_comparable<iterator_t<_Base>>
4630 {
return __x._M_current == __y._M_current; }
4632 friend constexpr bool
4633 operator<(
const _Iterator& __x,
const _Iterator& __y)
4634 requires random_access_range<_Base>
4635 {
return __x._M_current < __y._M_current; }
4637 friend constexpr bool
4638 operator>(
const _Iterator& __x,
const _Iterator& __y)
4639 requires random_access_range<_Base>
4640 {
return __y._M_current < __x._M_current; }
4642 friend constexpr bool
4643 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4644 requires random_access_range<_Base>
4645 {
return !(__y._M_current > __x._M_current); }
4647 friend constexpr bool
4648 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4649 requires random_access_range<_Base>
4650 {
return !(__x._M_current > __y._M_current); }
4652#ifdef __cpp_lib_three_way_comparison
4653 friend constexpr auto
4654 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4655 requires random_access_range<_Base>
4656 && three_way_comparable<iterator_t<_Base>>
4657 {
return __x._M_current <=> __y._M_current; }
4660 friend constexpr _Iterator
4661 operator+(
const _Iterator& __x, difference_type __y)
4662 requires random_access_range<_Base>
4663 {
return _Iterator{__x} += __y; }
4665 friend constexpr _Iterator
4666 operator+(difference_type __x,
const _Iterator& __y)
4667 requires random_access_range<_Base>
4668 {
return __y + __x; }
4670 friend constexpr _Iterator
4671 operator-(
const _Iterator& __x, difference_type __y)
4672 requires random_access_range<_Base>
4673 {
return _Iterator{__x} -= __y; }
4677 friend constexpr difference_type
4678 operator-(
const _Iterator& __x,
const _Iterator& __y)
4679 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4680 {
return __x._M_current - __y._M_current; }
4682 template <
bool>
friend struct _Sentinel;
4685 template<
bool _Const>
4689 using _Base = elements_view::_Base<_Const>;
4690 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4693 _Sentinel() =
default;
4696 _Sentinel(sentinel_t<_Base> __end)
4697 : _M_end(std::move(__end))
4701 _Sentinel(_Sentinel<!_Const> __other)
4703 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4707 constexpr sentinel_t<_Base>
4711 template<
bool _Const2>
4712 requires sentinel_for<sentinel_t<_Base>,
4713 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4714 friend constexpr bool
4715 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4716 {
return __x._M_current == __y._M_end; }
4718 template<
bool _Const2,
4719 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4720 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4721 friend constexpr range_difference_t<_Base2>
4722 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4723 {
return -(__y._M_end - __x._M_current); }
4725 template<
bool _Const2,
4726 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4727 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4728 friend constexpr range_difference_t<_Base2>
4729 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4730 {
return __x._M_end - __y._M_current; }
4732 friend _Sentinel<!_Const>;
4735 _Vp _M_base = _Vp();
4738 template<
typename _Tp,
size_t _Nm>
4739 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4740 = enable_borrowed_range<_Tp>;
4744 template<
typename _Range>
4745 using keys_view = elements_view<_Range, 0>;
4747 template<
typename _Range>
4748 using values_view = elements_view<_Range, 1>;
4754 template<
size_t _Nm,
typename _Range>
4755 concept __can_elements_view
4759 template<
size_t _Nm>
4760 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4762 template<viewable_range _Range>
4763 requires __detail::__can_elements_view<_Nm, _Range>
4765 operator() [[nodiscard]] (_Range&& __r)
const
4770 static constexpr bool _S_has_simple_call_op =
true;
4773 template<
size_t _Nm>
4774 inline constexpr _Elements<_Nm> elements;
4775 inline constexpr auto keys = elements<0>;
4776 inline constexpr auto values = elements<1>;
4779#ifdef __cpp_lib_ranges_zip
4782 template<
typename... _Rs>
4783 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4784 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4785 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4787 template<
typename _Fp,
typename _Tuple>
4789 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4791 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4792 return tuple<invoke_result_t<_Fp&, _Ts>...>
4797 template<
typename _Fp,
typename _Tuple>
4799 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4801 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4808 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4811 tuple<_Vs...> _M_views;
4813 template<
bool>
class _Iterator;
4814 template<
bool>
class _Sentinel;
4817 zip_view() =
default;
4820 zip_view(_Vs... __views)
4821 : _M_views(std::move(__views)...)
4825 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4826 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4829 begin() const requires (
range<const _Vs> && ...)
4830 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4833 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4835 if constexpr (!__detail::__zip_is_common<_Vs...>)
4836 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4838 return begin() + iter_difference_t<_Iterator<false>>(
size());
4840 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4844 end() const requires (
range<const _Vs> && ...)
4846 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4847 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4849 return begin() + iter_difference_t<_Iterator<true>>(
size());
4851 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4857 return std::apply([](
auto... __sizes) {
4858 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4859 return ranges::min({_CT(__sizes)...});
4860 }, __detail::__tuple_transform(ranges::size, _M_views));
4866 return std::apply([](
auto... __sizes) {
4867 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4868 return ranges::min({_CT(__sizes)...});
4869 }, __detail::__tuple_transform(ranges::size, _M_views));
4873 template<
typename... _Rs>
4874 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4876 template<
typename... _Views>
4877 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4878 = (enable_borrowed_range<_Views> && ...);
4882 template<
bool _Const,
typename... _Vs>
4883 concept __all_random_access
4884 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4886 template<
bool _Const,
typename... _Vs>
4887 concept __all_bidirectional
4888 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4890 template<
bool _Const,
typename... _Vs>
4891 concept __all_forward
4892 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4894 template<
bool _Const,
typename... _Views>
4895 struct __zip_view_iter_cat
4898 template<
bool _Const,
typename... _Views>
4899 requires __all_forward<_Const, _Views...>
4900 struct __zip_view_iter_cat<_Const, _Views...>
4901 {
using iterator_category = input_iterator_tag; };
4905 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4906 template<bool _Const>
4907 class zip_view<_Vs...>::_Iterator
4908 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4910#ifdef _GLIBCXX_CLANG
4913 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4916 _Iterator(
decltype(_M_current) __current)
4917 : _M_current(std::move(__current))
4923 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4924 return random_access_iterator_tag{};
4925 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4926 return bidirectional_iterator_tag{};
4927 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4928 return forward_iterator_tag{};
4930 return input_iterator_tag{};
4933#ifndef _GLIBCXX_CLANG
4934 template<move_constructible _Fp,
input_range... _Ws>
4935 requires (
view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4936 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4937 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4938 friend class zip_transform_view;
4943 using iterator_concept =
decltype(_S_iter_concept());
4945 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4946 using difference_type
4949 _Iterator() =
default;
4952 _Iterator(_Iterator<!_Const> __i)
4954 && (convertible_to<iterator_t<_Vs>,
4955 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4956 : _M_current(std::move(__i._M_current))
4962 auto __f = [](
auto& __i) ->
decltype(
auto) {
4965 return __detail::__tuple_transform(__f, _M_current);
4968 constexpr _Iterator&
4971 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4981 requires __detail::__all_forward<_Const, _Vs...>
4988 constexpr _Iterator&
4990 requires __detail::__all_bidirectional<_Const, _Vs...>
4992 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4998 requires __detail::__all_bidirectional<_Const, _Vs...>
5005 constexpr _Iterator&
5006 operator+=(difference_type __x)
5007 requires __detail::__all_random_access<_Const, _Vs...>
5009 auto __f = [&]<
typename _It>(_It& __i) {
5010 __i += iter_difference_t<_It>(__x);
5012 __detail::__tuple_for_each(__f, _M_current);
5016 constexpr _Iterator&
5017 operator-=(difference_type __x)
5018 requires __detail::__all_random_access<_Const, _Vs...>
5020 auto __f = [&]<
typename _It>(_It& __i) {
5021 __i -= iter_difference_t<_It>(__x);
5023 __detail::__tuple_for_each(__f, _M_current);
5028 operator[](difference_type __n)
const
5029 requires __detail::__all_random_access<_Const, _Vs...>
5031 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
5032 return __i[iter_difference_t<_It>(__n)];
5034 return __detail::__tuple_transform(__f, _M_current);
5037 friend constexpr bool
5038 operator==(
const _Iterator& __x,
const _Iterator& __y)
5039 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5041 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
5042 return __x._M_current == __y._M_current;
5045 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
5049 friend constexpr auto
5050 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5051 requires __detail::__all_random_access<_Const, _Vs...>
5052 {
return __x._M_current <=> __y._M_current; }
5054 friend constexpr _Iterator
5055 operator+(
const _Iterator& __i, difference_type __n)
5056 requires __detail::__all_random_access<_Const, _Vs...>
5063 friend constexpr _Iterator
5064 operator+(difference_type __n,
const _Iterator& __i)
5065 requires __detail::__all_random_access<_Const, _Vs...>
5072 friend constexpr _Iterator
5073 operator-(
const _Iterator& __i, difference_type __n)
5074 requires __detail::__all_random_access<_Const, _Vs...>
5081 friend constexpr difference_type
5082 operator-(
const _Iterator& __x,
const _Iterator& __y)
5083 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
5084 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5087 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
5088 - std::get<_Is>(__y._M_current))...},
5090 [](difference_type __i) {
5091 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5096 friend constexpr auto
5097 iter_move(
const _Iterator& __i)
5098 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5100 friend constexpr void
5101 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5102 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5105 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
5109 friend class zip_view;
5113 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
5114 template<bool _Const>
5115 class zip_view<_Vs...>::_Sentinel
5117 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
5120 _Sentinel(
decltype(_M_end) __end)
5124 friend class zip_view;
5127 _Sentinel() =
default;
5130 _Sentinel(_Sentinel<!_Const> __i)
5132 && (convertible_to<sentinel_t<_Vs>,
5133 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5134 : _M_end(std::move(__i._M_end))
5137 template<
bool _OtherConst>
5138 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5139 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5140 friend constexpr bool
5141 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5144 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
5148 template<
bool _OtherConst>
5149 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5150 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5151 friend constexpr auto
5152 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5157 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
5160 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5165 template<
bool _OtherConst>
5166 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5167 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5168 friend constexpr auto
5169 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5170 {
return -(__x - __y); }
5177 template<
typename... _Ts>
5178 concept __can_zip_view
5184 template<
typename... _Ts>
5185 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5187 operator() [[nodiscard]] (_Ts&&... __ts)
const
5189 if constexpr (
sizeof...(_Ts) == 0)
5190 return views::empty<tuple<>>;
5196 inline constexpr _Zip zip;
5201 template<
typename _Range,
bool _Const>
5202 using __range_iter_cat
5203 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5206 template<move_constructible _Fp,
input_range... _Vs>
5207 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5208 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5209 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5210 class zip_transform_view : public
view_interface<zip_transform_view<_Fp, _Vs...>>
5212 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5213 zip_view<_Vs...> _M_zip;
5215 using _InnerView = zip_view<_Vs...>;
5217 template<
bool _Const>
5218 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5220 template<
bool _Const>
5221 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5223 template<
bool _Const>
5224 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5226 template<
bool _Const>
5230 template<
bool _Const>
5232 struct __iter_cat<_Const>
5238 using __detail::__maybe_const_t;
5239 using __detail::__range_iter_cat;
5240 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5241 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5244 if constexpr (!is_reference_v<_Res>)
5245 return input_iterator_tag{};
5246 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5247 random_access_iterator_tag> && ...))
5248 return random_access_iterator_tag{};
5249 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5250 bidirectional_iterator_tag> && ...))
5251 return bidirectional_iterator_tag{};
5252 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5253 forward_iterator_tag> && ...))
5254 return forward_iterator_tag{};
5256 return input_iterator_tag{};
5259 using iterator_category =
decltype(_S_iter_cat());
5262 template<
bool>
class _Iterator;
5263 template<
bool>
class _Sentinel;
5266 zip_transform_view() =
default;
5269 zip_transform_view(_Fp __fun, _Vs... __views)
5270 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5275 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5279 requires
range<const _InnerView>
5280 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5281 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5287 return _Iterator<false>(*
this, _M_zip.end());
5289 return _Sentinel<false>(_M_zip.end());
5294 requires
range<const _InnerView>
5295 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5298 return _Iterator<true>(*
this, _M_zip.end());
5300 return _Sentinel<true>(_M_zip.end());
5305 {
return _M_zip.size(); }
5309 {
return _M_zip.size(); }
5312 template<
class _Fp,
class... _Rs>
5313 zip_transform_view(_Fp, _Rs&&...)
5314 -> zip_transform_view<_Fp, views::all_t<_Rs>...>;
5316 template<move_constructible _Fp,
input_range... _Vs>
5317 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5318 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5319 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5320 template<bool _Const>
5321 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5323 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5324 using _Fun_handle = __detail::__func_handle_t<
5325 __detail::__maybe_const_t<_Const, _Fp>,
5326 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
5328 [[no_unique_address]] _Fun_handle _M_fun;
5329 __ziperator<_Const> _M_inner;
5332 _Iterator(_Fun_handle __fun, __ziperator<_Const> __inner)
5333 : _M_fun(__fun), _M_inner(std::move(__inner))
5337 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5338 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
5341 friend class zip_transform_view;
5345 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5347 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5348 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5349 using difference_type = range_difference_t<_Base<_Const>>;
5351 _Iterator() =
default;
5354 _Iterator(_Iterator<!_Const> __i)
5355 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5356 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
5359 constexpr decltype(
auto)
5362 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5363 return _M_fun._M_call_deref(__iters...);
5364 }, _M_inner._M_current);
5367 constexpr _Iterator&
5386 constexpr _Iterator&
5401 constexpr _Iterator&
5408 constexpr _Iterator&
5415 constexpr decltype(
auto)
5418 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5419 return _M_fun._M_call_subscript(__n, __iters...);
5420 }, _M_inner._M_current);
5423 friend constexpr bool
5424 operator==(
const _Iterator& __x,
const _Iterator& __y)
5425 requires equality_comparable<__ziperator<_Const>>
5426 {
return __x._M_inner == __y._M_inner; }
5428 friend constexpr auto
5429 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5431 {
return __x._M_inner <=> __y._M_inner; }
5433 friend constexpr _Iterator
5434 operator+(
const _Iterator& __i, difference_type __n)
5436 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5438 friend constexpr _Iterator
5439 operator+(difference_type __n,
const _Iterator& __i)
5441 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5443 friend constexpr _Iterator
5444 operator-(
const _Iterator& __i, difference_type __n)
5446 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
5448 friend constexpr difference_type
5449 operator-(
const _Iterator& __x,
const _Iterator& __y)
5450 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5451 {
return __x._M_inner - __y._M_inner; }
5454 template<move_constructible _Fp,
input_range... _Vs>
5455 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5456 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5457 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5458 template<bool _Const>
5459 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5461 __zentinel<_Const> _M_inner;
5464 _Sentinel(__zentinel<_Const> __inner)
5468 friend class zip_transform_view;
5471 _Sentinel() =
default;
5474 _Sentinel(_Sentinel<!_Const> __i)
5475 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5479 template<
bool _OtherConst>
5480 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5481 friend constexpr bool
5482 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5483 {
return __x._M_inner == __y._M_inner; }
5485 template<
bool _OtherConst>
5486 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5487 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5488 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5489 {
return __x._M_inner - __y._M_inner; }
5491 template<
bool _OtherConst>
5492 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5493 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5494 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5495 {
return __x._M_inner - __y._M_inner; }
5502 template<
typename _Fp,
typename... _Ts>
5503 concept __can_zip_transform_view
5507 struct _ZipTransform
5509 template<
typename _Fp>
5510 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5511 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5513 operator() [[nodiscard]] (_Fp&&)
const
5515 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5518 template<
typename _Fp,
typename... _Ts>
5519 requires (
sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5521 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5527 inline constexpr _ZipTransform zip_transform;
5530 template<forward_range _Vp,
size_t _Nm>
5532 class adjacent_view : public
view_interface<adjacent_view<_Vp, _Nm>>
5534 _Vp _M_base = _Vp();
5536 template<
bool>
class _Iterator;
5537 template<
bool>
class _Sentinel;
5539 struct __as_sentinel
5543 adjacent_view()
requires default_initializable<_Vp> = default;
5546 adjacent_view(_Vp __base)
5547 : _M_base(std::move(__base))
5553 base() const & requires copy_constructible<_Vp>
5561 begin()
requires (!__detail::__simple_view<_Vp>)
5562 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5566 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5569 end()
requires (!__detail::__simple_view<_Vp>)
5572 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5574 return _Sentinel<false>(ranges::end(_M_base));
5578 end() const requires
range<const _Vp>
5581 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5583 return _Sentinel<true>(ranges::end(_M_base));
5589 using _ST =
decltype(ranges::size(_M_base));
5591 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5593 return static_cast<_ST
>(__sz);
5599 using _ST =
decltype(ranges::size(_M_base));
5601 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5603 return static_cast<_ST
>(__sz);
5607 template<
typename _Vp,
size_t _Nm>
5608 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5609 = enable_borrowed_range<_Vp>;
5614 template<
typename _Tp,
size_t _Nm>
5615 using __repeated_tuple =
typename __make_tuple<array<_Tp, _Nm>>::__type;
5619 template<
typename _Fp,
size_t _Nm>
5622 template<
typename... _Ts>
5623 static invoke_result_t<_Fp, _Ts...>
5624 __tuple_apply(
const tuple<_Ts...>&);
5626 template<
typename _Tp>
5627 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5632 template<forward_range _Vp,
size_t _Nm>
5634 template<bool _Const>
5635 class adjacent_view<_Vp, _Nm>::_Iterator
5637#ifdef _GLIBCXX_CLANG
5640 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5641 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5644 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5646 for (
auto& __i : _M_current)
5649 ranges::advance(__first, 1, __last);
5654 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5657 for (
auto& __it : _M_current)
5660 for (
size_t __i = 0; __i < _Nm; ++__i)
5662 _M_current[_Nm - 1 - __i] = __last;
5663 ranges::advance(__last, -1, __first);
5671 return random_access_iterator_tag{};
5673 return bidirectional_iterator_tag{};
5675 return forward_iterator_tag{};
5678 friend class adjacent_view;
5680#ifndef _GLIBCXX_CLANG
5681 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5682 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5683 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5684 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5685 range_reference_t<_Wp>>>
5686 friend class adjacent_transform_view;
5690 using iterator_category = input_iterator_tag;
5691 using iterator_concept =
decltype(_S_iter_concept());
5692 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5693 using difference_type = range_difference_t<_Base>;
5695 _Iterator() =
default;
5698 _Iterator(_Iterator<!_Const> __i)
5699 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5701 for (
size_t __j = 0; __j < _Nm; ++__j)
5702 _M_current[__j] =
std::move(__i._M_current[__j]);
5708 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5709 return __detail::__tuple_transform(__f, _M_current);
5712 constexpr _Iterator&
5715 for (
auto& __i : _M_current)
5728 constexpr _Iterator&
5731 for (
auto& __i : _M_current)
5744 constexpr _Iterator&
5745 operator+=(difference_type __x)
5748 for (
auto& __i : _M_current)
5753 constexpr _Iterator&
5754 operator-=(difference_type __x)
5757 for (
auto& __i : _M_current)
5763 operator[](difference_type __n)
const
5766 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5767 return __detail::__tuple_transform(__f, _M_current);
5770 friend constexpr bool
5771 operator==(
const _Iterator& __x,
const _Iterator& __y)
5772 {
return __x._M_current.back() == __y._M_current.back(); }
5774 friend constexpr bool
5775 operator<(
const _Iterator& __x,
const _Iterator& __y)
5777 {
return __x._M_current.back() < __y._M_current.back(); }
5779 friend constexpr bool
5780 operator>(
const _Iterator& __x,
const _Iterator& __y)
5782 {
return __y < __x; }
5784 friend constexpr bool
5785 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5787 {
return !(__y < __x); }
5789 friend constexpr bool
5790 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5792 {
return !(__x < __y); }
5794 friend constexpr auto
5795 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5797 && three_way_comparable<iterator_t<_Base>>
5798 {
return __x._M_current.back() <=> __y._M_current.back(); }
5800 friend constexpr _Iterator
5801 operator+(
const _Iterator& __i, difference_type __n)
5809 friend constexpr _Iterator
5810 operator+(difference_type __n,
const _Iterator& __i)
5818 friend constexpr _Iterator
5819 operator-(
const _Iterator& __i, difference_type __n)
5827 friend constexpr difference_type
5828 operator-(
const _Iterator& __x,
const _Iterator& __y)
5829 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5830 {
return __x._M_current.back() - __y._M_current.back(); }
5832 friend constexpr auto
5833 iter_move(
const _Iterator& __i)
5834 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5836 friend constexpr void
5837 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5838 requires indirectly_swappable<iterator_t<_Base>>
5840 for (
size_t __i = 0; __i < _Nm; __i++)
5841 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5845 template<forward_range _Vp,
size_t _Nm>
5847 template<bool _Const>
5848 class adjacent_view<_Vp, _Nm>::_Sentinel
5850 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5852 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5855 _Sentinel(sentinel_t<_Base> __end)
5859 friend class adjacent_view;
5862 _Sentinel() =
default;
5865 _Sentinel(_Sentinel<!_Const> __i)
5866 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5870 template<
bool _OtherConst>
5871 requires sentinel_for<sentinel_t<_Base>,
5872 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5873 friend constexpr bool
5874 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5875 {
return __x._M_current.back() == __y._M_end; }
5877 template<
bool _OtherConst>
5878 requires sized_sentinel_for<sentinel_t<_Base>,
5879 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5880 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5881 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5882 {
return __x._M_current.back() - __y._M_end; }
5884 template<
bool _OtherConst>
5885 requires sized_sentinel_for<sentinel_t<_Base>,
5886 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5887 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5888 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5889 {
return __y._M_end - __x._M_current.back(); }
5896 template<
size_t _Nm,
typename _Range>
5897 concept __can_adjacent_view
5901 template<
size_t _Nm>
5902 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5906 template<viewable_range _Range>
5907 requires ((_Nm == 0) && forward_range<_Range>)
5908 || __detail::__can_adjacent_view<_Nm, _Range>
5910 operator() [[nodiscard]] (_Range&& __r)
const
5912 if constexpr (_Nm == 0)
5913 return views::empty<tuple<>>;
5919 template<
size_t _Nm>
5920 inline constexpr _Adjacent<_Nm> adjacent;
5922 inline constexpr auto pairwise = adjacent<2>;
5925 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5926 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5927 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5928 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5929 range_reference_t<_Vp>>>
5930 class adjacent_transform_view : public
view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5932 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5933 adjacent_view<_Vp, _Nm> _M_inner;
5935 using _InnerView = adjacent_view<_Vp, _Nm>;
5937 template<
bool _Const>
5938 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5940 template<
bool _Const>
5941 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5943 template<
bool>
class _Iterator;
5944 template<
bool>
class _Sentinel;
5947 adjacent_transform_view() =
default;
5950 adjacent_transform_view(_Vp __base, _Fp __fun)
5951 : _M_fun(std::move(__fun)), _M_inner(std::move(
__base))
5958 base() const & requires copy_constructible<_Vp>
5959 {
return _M_inner.base(); }
5967 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5971 requires
range<const _InnerView>
5972 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5973 range_reference_t<const _Vp>>
5974 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5980 return _Iterator<false>(*
this, _M_inner.end());
5982 return _Sentinel<false>(_M_inner.end());
5987 requires
range<const _InnerView>
5988 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5989 range_reference_t<const _Vp>>
5992 return _Iterator<true>(*
this, _M_inner.end());
5994 return _Sentinel<true>(_M_inner.end());
5999 {
return _M_inner.size(); }
6003 {
return _M_inner.size(); }
6006 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6007 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6008 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6009 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6010 range_reference_t<_Vp>>>
6011 template<bool _Const>
6012 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
6014 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
6015 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6017 return __detail::__func_handle_t<
6018 __detail::__maybe_const_t<_Const, _Fp>,
6019 iterator_t<__detail::__maybe_const_t<(_Ids, _Const), _Vp>>...>();
6022 [[no_unique_address]] _Fun_handle _M_fun;
6023 _InnerIter<_Const> _M_inner;
6026 _Iterator(_Fun_handle __fun, _InnerIter<_Const> __inner)
6027 : _M_fun(__fun), _M_inner(std::move(__inner))
6031 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
6032 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
6038 using __detail::__maybe_const_t;
6039 using __detail::__unarize;
6040 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
6041 range_reference_t<_Base>>;
6042 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
6045 if constexpr (!is_reference_v<_Res>)
6046 return input_iterator_tag{};
6047 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
6048 return random_access_iterator_tag{};
6049 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
6050 return bidirectional_iterator_tag{};
6051 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
6052 return forward_iterator_tag{};
6054 return input_iterator_tag{};
6057 friend class adjacent_transform_view;
6060 using iterator_category =
decltype(_S_iter_cat());
6061 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
6063 = remove_cvref_t<invoke_result_t
6064 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
6065 range_reference_t<_Base>>>;
6066 using difference_type = range_difference_t<_Base>;
6068 _Iterator() =
default;
6071 _Iterator(_Iterator<!_Const> __i)
6072 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
6073 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
6076 constexpr decltype(
auto)
6079 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6080 return _M_fun._M_call_deref(__iters...);
6081 }, _M_inner._M_current);
6084 constexpr _Iterator&
6099 constexpr _Iterator&
6114 constexpr _Iterator&
6121 constexpr _Iterator&
6128 constexpr decltype(
auto)
6131 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6132 return _M_fun._M_call_subscript(__n, __iters...);
6133 }, _M_inner._M_current);
6136 friend constexpr bool
6137 operator==(
const _Iterator& __x,
const _Iterator& __y)
6138 {
return __x._M_inner == __y._M_inner; }
6140 friend constexpr bool
6141 operator<(
const _Iterator& __x,
const _Iterator& __y)
6143 {
return __x._M_inner < __y._M_inner; }
6145 friend constexpr bool
6146 operator>(
const _Iterator& __x,
const _Iterator& __y)
6148 {
return __x._M_inner > __y._M_inner; }
6150 friend constexpr bool
6151 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6153 {
return __x._M_inner <= __y._M_inner; }
6155 friend constexpr bool
6156 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6158 {
return __x._M_inner >= __y._M_inner; }
6160 friend constexpr auto
6161 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6163 three_way_comparable<_InnerIter<_Const>>
6164 {
return __x._M_inner <=> __y._M_inner; }
6166 friend constexpr _Iterator
6167 operator+(
const _Iterator& __i, difference_type __n)
6169 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6171 friend constexpr _Iterator
6172 operator+(difference_type __n,
const _Iterator& __i)
6174 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6176 friend constexpr _Iterator
6177 operator-(
const _Iterator& __i, difference_type __n)
6179 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
6181 friend constexpr difference_type
6182 operator-(
const _Iterator& __x,
const _Iterator& __y)
6183 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
6184 {
return __x._M_inner - __y._M_inner; }
6187 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6188 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6189 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6190 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6191 range_reference_t<_Vp>>>
6192 template<bool _Const>
6193 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6195 _InnerSent<_Const> _M_inner;
6198 _Sentinel(_InnerSent<_Const> __inner)
6202 friend class adjacent_transform_view;
6205 _Sentinel() =
default;
6208 _Sentinel(_Sentinel<!_Const> __i)
6209 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6213 template<
bool _OtherConst>
6214 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6215 friend constexpr bool
6216 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6217 {
return __x._M_inner == __y._M_inner; }
6219 template<
bool _OtherConst>
6220 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6221 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6222 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6223 {
return __x._M_inner - __y._M_inner; }
6225 template<
bool _OtherConst>
6226 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6227 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6228 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
6229 {
return __x._M_inner - __y._M_inner; }
6236 template<
size_t _Nm,
typename _Range,
typename _Fp>
6237 concept __can_adjacent_transform_view
6238 =
requires { adjacent_transform_view<all_t<_Range>,
decay_t<_Fp>, _Nm>
6242 template<
size_t _Nm>
6243 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6247 template<viewable_range _Range,
typename _Fp>
6248 requires ((_Nm == 0) && forward_range<_Range>)
6249 || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6251 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
6253 if constexpr (_Nm == 0)
6256 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6260 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6261 static constexpr int _S_arity = 2;
6262 static constexpr bool _S_has_simple_extra_args =
true;
6265 template<
size_t _Nm>
6266 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6268 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6272#ifdef __cpp_lib_ranges_chunk
6275 template<
typename _Tp>
6276 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6278 _Tp __r = __num / __denom;
6279 if (__num % __denom)
6290 range_difference_t<_Vp> _M_n;
6291 range_difference_t<_Vp> _M_remainder = 0;
6292 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6299 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6300 : _M_base(std::move(
__base)), _M_n(__n)
6301 { __glibcxx_assert(__n >= 0); }
6304 base() const & requires copy_constructible<_Vp>
6311 constexpr _OuterIter
6314 _M_current = ranges::begin(_M_base);
6315 _M_remainder = _M_n;
6316 return _OuterIter(*
this);
6319 constexpr default_sentinel_t
6320 end() const noexcept
6324 size()
requires sized_range<_Vp>
6326 return __detail::__to_unsigned_like(__detail::__div_ceil
6327 (ranges::distance(_M_base), _M_n));
6331 size() const requires sized_range<const _Vp>
6333 return __detail::__to_unsigned_like(__detail::__div_ceil
6334 (ranges::distance(_M_base), _M_n));
6338 template<
typename _Range>
6339 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6343 class chunk_view<_Vp>::_OuterIter
6345 chunk_view* _M_parent;
6348 _OuterIter(chunk_view& __parent) noexcept
6355 using iterator_concept = input_iterator_tag;
6356 using difference_type = range_difference_t<_Vp>;
6360 _OuterIter(_OuterIter&&) =
default;
6361 _OuterIter& operator=(_OuterIter&&) =
default;
6363 constexpr value_type
6366 __glibcxx_assert(*
this != default_sentinel);
6367 return value_type(*_M_parent);
6370 constexpr _OuterIter&
6373 __glibcxx_assert(*
this != default_sentinel);
6374 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6375 ranges::end(_M_parent->_M_base));
6376 _M_parent->_M_remainder = _M_parent->_M_n;
6384 friend constexpr bool
6385 operator==(
const _OuterIter& __x, default_sentinel_t)
6387 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6388 && __x._M_parent->_M_remainder != 0;
6391 friend constexpr difference_type
6392 operator-(default_sentinel_t,
const _OuterIter& __x)
6393 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6395 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6397 if (__dist < __x._M_parent->_M_remainder)
6398 return __dist == 0 ? 0 : 1;
6400 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6401 __x._M_parent->_M_n);
6404 friend constexpr difference_type
6405 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6406 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6407 {
return -(__y - __x); }
6412 struct chunk_view<_Vp>::_OuterIter::value_type :
view_interface<value_type>
6415 chunk_view* _M_parent;
6418 value_type(chunk_view& __parent) noexcept
6425 constexpr _InnerIter
6426 begin() const noexcept
6427 {
return _InnerIter(*_M_parent); }
6429 constexpr default_sentinel_t
6430 end() const noexcept
6435 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6437 return __detail::__to_unsigned_like
6438 (ranges::min(_M_parent->_M_remainder,
6439 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6445 class chunk_view<_Vp>::_InnerIter
6447 chunk_view* _M_parent;
6450 _InnerIter(chunk_view& __parent) noexcept
6454 friend _OuterIter::value_type;
6457 using iterator_concept = input_iterator_tag;
6458 using difference_type = range_difference_t<_Vp>;
6459 using value_type = range_value_t<_Vp>;
6461 _InnerIter(_InnerIter&&) =
default;
6462 _InnerIter& operator=(_InnerIter&&) =
default;
6464 constexpr const iterator_t<_Vp>&
6466 {
return *_M_parent->_M_current; }
6468 constexpr range_reference_t<_Vp>
6471 __glibcxx_assert(*
this != default_sentinel);
6472 return **_M_parent->_M_current;
6475 constexpr _InnerIter&
6478 __glibcxx_assert(*
this != default_sentinel);
6479 ++*_M_parent->_M_current;
6480 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6481 _M_parent->_M_remainder = 0;
6483 --_M_parent->_M_remainder;
6491 friend constexpr bool
6492 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6493 {
return __x._M_parent->_M_remainder == 0; }
6495 friend constexpr difference_type
6496 operator-(default_sentinel_t,
const _InnerIter& __x)
6497 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6499 return ranges::min(__x._M_parent->_M_remainder,
6500 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6503 friend constexpr difference_type
6504 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6505 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6506 {
return -(__y - __x); }
6510 friend constexpr range_rvalue_reference_t<_Vp>
6511 iter_move(
const _InnerIter& __i)
6512 noexcept(
noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6513 {
return ranges::iter_move(*__i._M_parent->_M_current); }
6515 friend constexpr void
6516 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
6517 noexcept(
noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6518 *__x._M_parent->_M_current)))
6519 requires indirectly_swappable<iterator_t<_Vp>>
6520 {
return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6528 range_difference_t<_Vp> _M_n;
6529 template<
bool>
class _Iterator;
6533 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6534 : _M_base(std::move(
__base)), _M_n(__n)
6535 { __glibcxx_assert(__n > 0); }
6538 base() const & requires copy_constructible<_Vp>
6546 begin()
requires (!__detail::__simple_view<_Vp>)
6547 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6550 begin() const requires forward_range<const _Vp>
6551 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6554 end()
requires (!__detail::__simple_view<_Vp>)
6556 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6558 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6559 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6561 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6562 return _Iterator<false>(
this, ranges::end(_M_base));
6568 end() const requires forward_range<const _Vp>
6570 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6572 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6573 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6575 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6576 return _Iterator<true>(
this, ranges::end(_M_base));
6582 size()
requires sized_range<_Vp>
6584 return __detail::__to_unsigned_like(__detail::__div_ceil
6585 (ranges::distance(_M_base), _M_n));
6589 size() const requires sized_range<const _Vp>
6591 return __detail::__to_unsigned_like(__detail::__div_ceil
6592 (ranges::distance(_M_base), _M_n));
6596 template<
typename _Vp>
6597 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6602 template<
bool _Const>
6603 class chunk_view<_Vp>::_Iterator
6605 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6606 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6608 iterator_t<_Base> _M_current = iterator_t<_Base>();
6609 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6610 range_difference_t<_Base> _M_n = 0;
6611 range_difference_t<_Base> _M_missing = 0;
6614 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6615 range_difference_t<_Base> __missing = 0)
6616 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6617 _M_n(__parent->_M_n), _M_missing(__missing)
6623 if constexpr (random_access_range<_Base>)
6624 return random_access_iterator_tag{};
6625 else if constexpr (bidirectional_range<_Base>)
6626 return bidirectional_iterator_tag{};
6628 return forward_iterator_tag{};
6634 using iterator_category = input_iterator_tag;
6635 using iterator_concept =
decltype(_S_iter_cat());
6636 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6637 using difference_type = range_difference_t<_Base>;
6639 _Iterator() =
default;
6641 constexpr _Iterator(_Iterator<!_Const> __i)
6643 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6644 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6646 _M_n(__i._M_n), _M_missing(__i._M_missing)
6649 constexpr iterator_t<_Base>
6651 {
return _M_current; }
6653 constexpr value_type
6656 __glibcxx_assert(_M_current != _M_end);
6657 return views::take(subrange(_M_current, _M_end), _M_n);
6660 constexpr _Iterator&
6663 __glibcxx_assert(_M_current != _M_end);
6664 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6676 constexpr _Iterator&
6677 operator--()
requires bidirectional_range<_Base>
6679 ranges::advance(_M_current, _M_missing - _M_n);
6685 operator--(
int)
requires bidirectional_range<_Base>
6692 constexpr _Iterator&
6693 operator+=(difference_type __x)
6694 requires random_access_range<_Base>
6698 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6699 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6703 ranges::advance(_M_current, _M_n * __x + _M_missing);
6709 constexpr _Iterator&
6710 operator-=(difference_type __x)
6711 requires random_access_range<_Base>
6712 {
return *
this += -__x; }
6714 constexpr value_type
6715 operator[](difference_type __n)
const
6716 requires random_access_range<_Base>
6717 {
return *(*
this + __n); }
6719 friend constexpr bool
6720 operator==(
const _Iterator& __x,
const _Iterator& __y)
6721 {
return __x._M_current == __y._M_current; }
6723 friend constexpr bool
6724 operator==(
const _Iterator& __x, default_sentinel_t)
6725 {
return __x._M_current == __x._M_end; }
6727 friend constexpr bool
6728 operator<(
const _Iterator& __x,
const _Iterator& __y)
6729 requires random_access_range<_Base>
6730 {
return __x._M_current > __y._M_current; }
6732 friend constexpr bool
6733 operator>(
const _Iterator& __x,
const _Iterator& __y)
6734 requires random_access_range<_Base>
6735 {
return __y < __x; }
6737 friend constexpr bool
6738 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6739 requires random_access_range<_Base>
6740 {
return !(__y < __x); }
6742 friend constexpr bool
6743 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6744 requires random_access_range<_Base>
6745 {
return !(__x < __y); }
6747 friend constexpr auto
6748 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6749 requires random_access_range<_Base>
6750 && three_way_comparable<iterator_t<_Base>>
6751 {
return __x._M_current <=> __y._M_current; }
6753 friend constexpr _Iterator
6754 operator+(
const _Iterator& __i, difference_type __n)
6755 requires random_access_range<_Base>
6762 friend constexpr _Iterator
6763 operator+(difference_type __n,
const _Iterator& __i)
6764 requires random_access_range<_Base>
6771 friend constexpr _Iterator
6772 operator-(
const _Iterator& __i, difference_type __n)
6773 requires random_access_range<_Base>
6780 friend constexpr difference_type
6781 operator-(
const _Iterator& __x,
const _Iterator& __y)
6782 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6784 return (__x._M_current - __y._M_current
6785 + __x._M_missing - __y._M_missing) / __x._M_n;
6788 friend constexpr difference_type
6789 operator-(default_sentinel_t,
const _Iterator& __x)
6790 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6791 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6793 friend constexpr difference_type
6794 operator-(
const _Iterator& __x, default_sentinel_t __y)
6795 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6796 {
return -(__y - __x); }
6803 template<
typename _Range,
typename _Dp>
6804 concept __can_chunk_view
6808 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6810 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6811 requires __detail::__can_chunk_view<_Range, _Dp>
6813 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6816 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6817 static constexpr int _S_arity = 2;
6818 static constexpr bool _S_has_simple_extra_args =
true;
6821 inline constexpr _Chunk chunk;
6825#ifdef __cpp_lib_ranges_slide
6828 template<
typename _Vp>
6829 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6831 template<
typename _Vp>
6832 concept __slide_caches_last
6833 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6835 template<
typename _Vp>
6836 concept __slide_caches_first
6837 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6840 template<forward_range _Vp>
6845 range_difference_t<_Vp> _M_n;
6846 [[no_unique_address]]
6847 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6848 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6849 [[no_unique_address]]
6850 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6851 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6853 template<
bool>
class _Iterator;
6858 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6859 : _M_base(std::move(
__base)), _M_n(__n)
6860 { __glibcxx_assert(__n > 0); }
6865 base() const & requires copy_constructible<_Vp>
6873 begin()
requires (!(__detail::__simple_view<_Vp>
6874 && __detail::__slide_caches_nothing<const _Vp>))
6876 if constexpr (__detail::__slide_caches_first<_Vp>)
6878 iterator_t<_Vp> __it;
6879 if (_M_cached_begin._M_has_value())
6880 __it = _M_cached_begin._M_get(_M_base);
6883 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6884 _M_cached_begin._M_set(_M_base, __it);
6886 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6889 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6893 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6894 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6897 end()
requires (!(__detail::__simple_view<_Vp>
6898 && __detail::__slide_caches_nothing<const _Vp>))
6900 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6901 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6903 else if constexpr (__detail::__slide_caches_last<_Vp>)
6905 iterator_t<_Vp> __it;
6906 if (_M_cached_end._M_has_value())
6907 __it = _M_cached_end._M_get(_M_base);
6910 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6911 _M_cached_end._M_set(_M_base, __it);
6913 return _Iterator<false>(
std::move(__it), _M_n);
6915 else if constexpr (common_range<_Vp>)
6916 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6918 return _Sentinel(ranges::end(_M_base));
6922 end() const requires __detail::__slide_caches_nothing<const _Vp>
6923 {
return begin() + range_difference_t<const _Vp>(size()); }
6926 size()
requires sized_range<_Vp>
6928 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6931 return __detail::__to_unsigned_like(__sz);
6935 size() const requires sized_range<const _Vp>
6937 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6940 return __detail::__to_unsigned_like(__sz);
6944 template<
typename _Range>
6945 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6947 template<
typename _Vp>
6948 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6949 = enable_borrowed_range<_Vp>;
6951 template<forward_range _Vp>
6953 template<
bool _Const>
6954 class slide_view<_Vp>::_Iterator
6956 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6957 static constexpr bool _S_last_elt_present
6958 = __detail::__slide_caches_first<_Base>;
6960 iterator_t<_Base> _M_current = iterator_t<_Base>();
6961 [[no_unique_address]]
6962 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6963 _M_last_elt =
decltype(_M_last_elt)();
6964 range_difference_t<_Base> _M_n = 0;
6967 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6968 requires (!_S_last_elt_present)
6969 : _M_current(__current), _M_n(__n)
6973 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6974 range_difference_t<_Base> __n)
6975 requires _S_last_elt_present
6976 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6982 if constexpr (random_access_range<_Base>)
6983 return random_access_iterator_tag{};
6984 else if constexpr (bidirectional_range<_Base>)
6985 return bidirectional_iterator_tag{};
6987 return forward_iterator_tag{};
6991 friend slide_view::_Sentinel;
6994 using iterator_category = input_iterator_tag;
6995 using iterator_concept =
decltype(_S_iter_concept());
6996 using value_type =
decltype(views::counted(_M_current, _M_n));
6997 using difference_type = range_difference_t<_Base>;
6999 _Iterator() =
default;
7002 _Iterator(_Iterator<!_Const> __i)
7003 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7004 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
7009 {
return views::counted(_M_current, _M_n); }
7011 constexpr _Iterator&
7015 if constexpr (_S_last_elt_present)
7028 constexpr _Iterator&
7029 operator--()
requires bidirectional_range<_Base>
7032 if constexpr (_S_last_elt_present)
7038 operator--(
int)
requires bidirectional_range<_Base>
7045 constexpr _Iterator&
7046 operator+=(difference_type __x)
7047 requires random_access_range<_Base>
7050 if constexpr (_S_last_elt_present)
7055 constexpr _Iterator&
7056 operator-=(difference_type __x)
7057 requires random_access_range<_Base>
7060 if constexpr (_S_last_elt_present)
7066 operator[](difference_type __n)
const
7067 requires random_access_range<_Base>
7068 {
return views::counted(_M_current + __n, _M_n); }
7070 friend constexpr bool
7071 operator==(
const _Iterator& __x,
const _Iterator& __y)
7073 if constexpr (_S_last_elt_present)
7074 return __x._M_last_elt == __y._M_last_elt;
7076 return __x._M_current == __y._M_current;
7079 friend constexpr bool
7080 operator<(
const _Iterator& __x,
const _Iterator& __y)
7081 requires random_access_range<_Base>
7082 {
return __x._M_current < __y._M_current; }
7084 friend constexpr bool
7085 operator>(
const _Iterator& __x,
const _Iterator& __y)
7086 requires random_access_range<_Base>
7087 {
return __y < __x; }
7089 friend constexpr bool
7090 operator<=(
const _Iterator& __x,
const _Iterator& __y)
7091 requires random_access_range<_Base>
7092 {
return !(__y < __x); }
7094 friend constexpr bool
7095 operator>=(
const _Iterator& __x,
const _Iterator& __y)
7096 requires random_access_range<_Base>
7097 {
return !(__x < __y); }
7099 friend constexpr auto
7100 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7101 requires random_access_range<_Base>
7102 && three_way_comparable<iterator_t<_Base>>
7103 {
return __x._M_current <=> __y._M_current; }
7105 friend constexpr _Iterator
7106 operator+(
const _Iterator& __i, difference_type __n)
7107 requires random_access_range<_Base>
7114 friend constexpr _Iterator
7115 operator+(difference_type __n,
const _Iterator& __i)
7116 requires random_access_range<_Base>
7123 friend constexpr _Iterator
7124 operator-(
const _Iterator& __i, difference_type __n)
7125 requires random_access_range<_Base>
7132 friend constexpr difference_type
7133 operator-(
const _Iterator& __x,
const _Iterator& __y)
7134 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7136 if constexpr (_S_last_elt_present)
7137 return __x._M_last_elt - __y._M_last_elt;
7139 return __x._M_current - __y._M_current;
7143 template<forward_range _Vp>
7145 class slide_view<_Vp>::_Sentinel
7147 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
7150 _Sentinel(sentinel_t<_Vp> __end)
7157 _Sentinel() =
default;
7159 friend constexpr bool
7160 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
7161 {
return __x._M_last_elt == __y._M_end; }
7163 friend constexpr range_difference_t<_Vp>
7164 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
7165 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7166 {
return __x._M_last_elt - __y._M_end; }
7168 friend constexpr range_difference_t<_Vp>
7169 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
7170 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7171 {
return __y._M_end -__x._M_last_elt; }
7178 template<
typename _Range,
typename _Dp>
7179 concept __can_slide_view
7183 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
7185 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
7186 requires __detail::__can_slide_view<_Range, _Dp>
7188 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
7191 using __adaptor::_RangeAdaptor<_Slide>::operator();
7192 static constexpr int _S_arity = 2;
7193 static constexpr bool _S_has_simple_extra_args =
true;
7196 inline constexpr _Slide slide;
7200#ifdef __cpp_lib_ranges_chunk_by
7202 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7203 requires view<_Vp> && is_object_v<_Pred>
7204 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
7206 _Vp _M_base = _Vp();
7207 __detail::__box<_Pred> _M_pred;
7208 __detail::_CachedPosition<_Vp> _M_cached_begin;
7210 constexpr iterator_t<_Vp>
7211 _M_find_next(iterator_t<_Vp> __current)
7213 __glibcxx_assert(_M_pred.has_value());
7214 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7217 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7218 return ranges::next(__it, 1, ranges::end(_M_base));
7221 constexpr iterator_t<_Vp>
7222 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
7224 __glibcxx_assert(_M_pred.has_value());
7225 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7230 __glibcxx_assert(__rbegin != __rend);
7231 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7232 return ranges::prev(__it, 1, ranges::begin(_M_base));
7238 chunk_by_view()
requires (default_initializable<_Vp>
7239 && default_initializable<_Pred>)
7243 chunk_by_view(_Vp __base, _Pred __pred)
7244 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
7248 base() const & requires copy_constructible<_Vp>
7255 constexpr const _Pred&
7257 {
return *_M_pred; }
7262 __glibcxx_assert(_M_pred.has_value());
7263 iterator_t<_Vp> __it;
7264 if (_M_cached_begin._M_has_value())
7265 __it = _M_cached_begin._M_get(_M_base);
7268 __it = _M_find_next(ranges::begin(_M_base));
7269 _M_cached_begin._M_set(_M_base, __it);
7271 return _Iterator(*
this, ranges::begin(_M_base), __it);
7277 if constexpr (common_range<_Vp>)
7278 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
7284 template<
typename _Range,
typename _Pred>
7285 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7288 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7289 requires view<_Vp> && is_object_v<_Pred>
7290 class chunk_by_view<_Vp, _Pred>::_Iterator
7292 chunk_by_view* _M_parent =
nullptr;
7293 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7294 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7297 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7298 : _M_parent(std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7304 if constexpr (bidirectional_range<_Vp>)
7305 return bidirectional_iterator_tag{};
7307 return forward_iterator_tag{};
7310 friend chunk_by_view;
7313 using value_type = subrange<iterator_t<_Vp>>;
7314 using difference_type = range_difference_t<_Vp>;
7315 using iterator_category = input_iterator_tag;
7316 using iterator_concept =
decltype(_S_iter_concept());
7318 _Iterator() =
default;
7320 constexpr value_type
7323 __glibcxx_assert(_M_current != _M_next);
7324 return ranges::subrange(_M_current, _M_next);
7327 constexpr _Iterator&
7330 __glibcxx_assert(_M_current != _M_next);
7331 _M_current = _M_next;
7332 _M_next = _M_parent->_M_find_next(_M_current);
7344 constexpr _Iterator&
7345 operator--()
requires bidirectional_range<_Vp>
7347 _M_next = _M_current;
7348 _M_current = _M_parent->_M_find_prev(_M_next);
7353 operator--(
int)
requires bidirectional_range<_Vp>
7360 friend constexpr bool
7361 operator==(
const _Iterator& __x,
const _Iterator& __y)
7362 {
return __x._M_current == __y._M_current; }
7364 friend constexpr bool
7365 operator==(
const _Iterator& __x, default_sentinel_t)
7366 {
return __x._M_current == __x._M_next; }
7373 template<
typename _Range,
typename _Pred>
7374 concept __can_chunk_by_view
7378 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7380 template<viewable_range _Range,
typename _Pred>
7381 requires __detail::__can_chunk_by_view<_Range, _Pred>
7383 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7386 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7387 static constexpr int _S_arity = 2;
7388 static constexpr bool _S_has_simple_extra_args =
true;
7391 inline constexpr _ChunkBy chunk_by;
7395#ifdef __cpp_lib_ranges_join_with
7398 template<
typename _Range>
7399 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7403 template<
typename... _Rs>
7406 template<
typename... _Rs>
7409 template<
typename... _Rs>
7410 using __concat_rvalue_reference_t
7413 template<
typename _Ref,
typename _RRef,
typename _It>
7414 concept __concat_indirectly_readable_impl =
requires(
const _It __it) {
7415 { *__it } -> convertible_to<_Ref>;
7416 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
7419 template<
typename... _Rs>
7420 concept __concat_indirectly_readable
7421 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
7422 && common_reference_with<__concat_reference_t<_Rs...>&&,
7423 __concat_rvalue_reference_t<_Rs...>&&>
7424 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
7425 __concat_value_t<_Rs...>
const&>
7426 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
7427 __concat_rvalue_reference_t<_Rs...>,
7431 template<
typename... _Rs>
7432 concept __concatable =
requires {
7433 typename __concat_reference_t<_Rs...>;
7434 typename __concat_value_t<_Rs...>;
7435 typename __concat_rvalue_reference_t<_Rs...>;
7436 } && __concat_indirectly_readable<_Rs...>;
7439 template<input_range _Vp, forward_range _Pattern>
7442 && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
7443 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7445 using _InnerRange = range_reference_t<_Vp>;
7447 _Vp _M_base = _Vp();
7448 [[no_unique_address]]
7449 __detail::__maybe_present_t<!forward_range<_Vp>,
7450 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7451 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7452 _Pattern _M_pattern = _Pattern();
7454 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7455 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7456 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7458 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7459 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7460 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7462 template<
bool _Const>
7463 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7465 template<
bool _Const>
7469 template<
bool _Const>
7470 requires _S_ref_is_glvalue<_Const>
7471 && forward_range<_Base<_Const>>
7472 && forward_range<_InnerBase<_Const>>
7473 struct __iter_cat<_Const>
7479 using _OuterIter = join_with_view::_OuterIter<_Const>;
7480 using _InnerIter = join_with_view::_InnerIter<_Const>;
7481 using _PatternIter = join_with_view::_PatternIter<_Const>;
7482 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7483 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7484 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7487 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7488 iter_reference_t<_PatternIter>>>)
7489 return input_iterator_tag{};
7490 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7491 && derived_from<_InnerCat, bidirectional_iterator_tag>
7492 && derived_from<_PatternCat, bidirectional_iterator_tag>
7493 && common_range<_InnerBase<_Const>>
7494 && common_range<_PatternBase<_Const>>)
7495 return bidirectional_iterator_tag{};
7496 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7497 && derived_from<_InnerCat, forward_iterator_tag>
7498 && derived_from<_PatternCat, forward_iterator_tag>)
7499 return forward_iterator_tag{};
7501 return input_iterator_tag{};
7504 using iterator_category =
decltype(_S_iter_cat());
7507 template<
bool>
class _Iterator;
7508 template<
bool>
class _Sentinel;
7511 join_with_view()
requires (default_initializable<_Vp>
7512 && default_initializable<_Pattern>)
7516 join_with_view(_Vp __base, _Pattern __pattern)
7517 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
7520 template<input_range _Range>
7521 requires constructible_from<_Vp, views::all_t<_Range>>
7522 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7524 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7525 : _M_base(views::all(std::
forward<_Range>(__r))),
7526 _M_pattern(views::single(std::move(__e)))
7530 base() const& requires copy_constructible<_Vp>
7540 if constexpr (forward_range<_Vp>)
7542 constexpr bool __use_const = is_reference_v<_InnerRange>
7543 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7544 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7548 _M_outer_it = ranges::begin(_M_base);
7549 return _Iterator<false>{*
this};
7555 requires forward_range<const _Vp>
7556 && forward_range<const _Pattern>
7557 && is_reference_v<range_reference_t<const _Vp>>
7558 && input_range<range_reference_t<const _Vp>>
7559 && __detail::__concatable<range_reference_t<const _Vp>, const _Pattern>
7560 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7565 constexpr bool __use_const
7566 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7567 if constexpr (is_reference_v<_InnerRange>
7568 && forward_range<_Vp> && common_range<_Vp>
7569 && forward_range<_InnerRange> && common_range<_InnerRange>)
7570 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7572 return _Sentinel<__use_const>{*
this};
7577 requires forward_range<const _Vp>
7578 && forward_range<const _Pattern>
7579 && is_reference_v<range_reference_t<const _Vp>>
7580 && input_range<range_reference_t<const _Vp>>
7581 && __detail::__concatable<range_reference_t<const _Vp>, const _Pattern>
7583 using _InnerConstRange = range_reference_t<const _Vp>;
7584 if constexpr (forward_range<_InnerConstRange>
7585 && common_range<const _Vp>
7586 && common_range<_InnerConstRange>)
7587 return _Iterator<true>{*
this, ranges::end(_M_base)};
7589 return _Sentinel<true>{*
this};
7593 template<
typename _Range,
typename _Pattern>
7594 join_with_view(_Range&&, _Pattern&&)
7595 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7597 template<input_range _Range>
7598 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7599 -> join_with_view<views::all_t<_Range>,
7602 template<input_range _Vp, forward_range _Pattern>
7605 && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
7606 template<
bool _Const>
7607 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7609 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7610 using _Base = join_with_view::_Base<_Const>;
7611 using _InnerBase = join_with_view::_InnerBase<_Const>;
7612 using _PatternBase = join_with_view::_PatternBase<_Const>;
7614 using _OuterIter = join_with_view::_OuterIter<_Const>;
7615 using _InnerIter = join_with_view::_InnerIter<_Const>;
7616 using _PatternIter = join_with_view::_PatternIter<_Const>;
7618 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7620 _Parent* _M_parent =
nullptr;
7621 [[no_unique_address]]
7622 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7623 =
decltype(_M_outer_it)();
7624 variant<_PatternIter, _InnerIter> _M_inner_it;
7626 constexpr _OuterIter&
7629 if constexpr (forward_range<_Base>)
7632 return *_M_parent->_M_outer_it;
7635 constexpr const _OuterIter&
7636 _M_get_outer()
const
7638 if constexpr (forward_range<_Base>)
7641 return *_M_parent->_M_outer_it;
7645 _Iterator(_Parent& __parent, _OuterIter __outer)
7646 requires forward_range<_Base>
7649 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7651 auto&& __inner = _M_update_inner();
7652 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7658 _Iterator(_Parent& __parent)
7659 requires (!forward_range<_Base>)
7662 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7664 auto&& __inner = _M_update_inner();
7665 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7673 _OuterIter& __outer = _M_get_outer();
7674 if constexpr (_S_ref_is_glvalue)
7675 return __detail::__as_lvalue(*__outer);
7677 return _M_parent->_M_inner._M_emplace_deref(__outer);
7683 if constexpr (_S_ref_is_glvalue)
7684 return __detail::__as_lvalue(*_M_get_outer());
7686 return *_M_parent->_M_inner;
7694 if (_M_inner_it.index() == 0)
7696 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7699 auto&& __inner = _M_update_inner();
7700 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7704 auto&& __inner = _M_get_inner();
7705 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7708 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7710 if constexpr (_S_ref_is_glvalue)
7711 _M_inner_it.template emplace<0>();
7715 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7723 if constexpr (_S_ref_is_glvalue
7724 && bidirectional_range<_Base>
7725 && __detail::__bidirectional_common<_InnerBase>
7726 && __detail::__bidirectional_common<_PatternBase>)
7727 return bidirectional_iterator_tag{};
7728 else if constexpr (_S_ref_is_glvalue
7729 && forward_range<_Base>
7730 && forward_range<_InnerBase>)
7731 return forward_iterator_tag{};
7733 return input_iterator_tag{};
7736 friend join_with_view;
7739 using iterator_concept =
decltype(_S_iter_concept());
7741 using value_type = common_type_t<iter_value_t<_InnerIter>,
7742 iter_value_t<_PatternIter>>;
7743 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7744 iter_difference_t<_InnerIter>,
7745 iter_difference_t<_PatternIter>>;
7747 _Iterator() =
default;
7750 _Iterator(_Iterator<!_Const> __i)
7752 && convertible_to<iterator_t<_Vp>, _OuterIter>
7753 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7754 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7755 : _M_parent(__i._M_parent),
7758 if (__i._M_inner_it.index() == 0)
7759 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7761 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7764 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7765 iter_reference_t<_PatternIter>>
7768 if (_M_inner_it.index() == 0)
7769 return *std::get<0>(_M_inner_it);
7771 return *std::get<1>(_M_inner_it);
7774 constexpr _Iterator&
7777 if (_M_inner_it.index() == 0)
7778 ++std::get<0>(_M_inner_it);
7780 ++std::get<1>(_M_inner_it);
7791 requires _S_ref_is_glvalue
7792 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7794 _Iterator __tmp = *
this;
7799 constexpr _Iterator&
7801 requires _S_ref_is_glvalue
7802 && bidirectional_range<_Base>
7803 && __detail::__bidirectional_common<_InnerBase>
7804 && __detail::__bidirectional_common<_PatternBase>
7806 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7808 auto&& __inner = *--_M_outer_it;
7809 _M_inner_it.template emplace<1>(ranges::end(__inner));
7814 if (_M_inner_it.index() == 0)
7816 auto& __it = std::get<0>(_M_inner_it);
7817 if (__it == ranges::begin(_M_parent->_M_pattern))
7819 auto&& __inner = *--_M_outer_it;
7820 _M_inner_it.template emplace<1>(ranges::end(__inner));
7827 auto& __it = std::get<1>(_M_inner_it);
7828 auto&& __inner = *_M_outer_it;
7829 if (__it == ranges::begin(__inner))
7830 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7836 if (_M_inner_it.index() == 0)
7837 --std::get<0>(_M_inner_it);
7839 --std::get<1>(_M_inner_it);
7845 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7846 && __detail::__bidirectional_common<_InnerBase>
7847 && __detail::__bidirectional_common<_PatternBase>
7849 _Iterator __tmp = *
this;
7854 friend constexpr bool
7855 operator==(
const _Iterator& __x,
const _Iterator& __y)
7856 requires _S_ref_is_glvalue
7857 && forward_range<_Base> && equality_comparable<_InnerIter>
7858 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7860 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7861 iter_rvalue_reference_t<_PatternIter>>
7862 iter_move(
const _Iterator& __x)
7864 if (__x._M_inner_it.index() == 0)
7865 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7867 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7870 friend constexpr void
7871 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7872 requires indirectly_swappable<_InnerIter, _PatternIter>
7874 if (__x._M_inner_it.index() == 0)
7876 if (__y._M_inner_it.index() == 0)
7877 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7879 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7883 if (__y._M_inner_it.index() == 0)
7884 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7886 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7891 template<input_range _Vp, forward_range _Pattern>
7894 && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
7895 template<
bool _Const>
7896 class join_with_view<_Vp, _Pattern>::_Sentinel
7898 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7899 using _Base = join_with_view::_Base<_Const>;
7901 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7904 _Sentinel(_Parent& __parent)
7905 : _M_end(ranges::end(__parent._M_base))
7908 friend join_with_view;
7911 _Sentinel() =
default;
7914 _Sentinel(_Sentinel<!_Const> __s)
7915 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7919 template<
bool _OtherConst>
7920 requires sentinel_for<sentinel_t<_Base>,
7921 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7922 friend constexpr bool
7923 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7924 {
return __x._M_get_outer() == __y._M_end; }
7931 template<
typename _Range,
typename _Pattern>
7932 concept __can_join_with_view
7936 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7938 template<viewable_range _Range,
typename _Pattern>
7939 requires __detail::__can_join_with_view<_Range, _Pattern>
7941 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7946 using _RangeAdaptor<_JoinWith>::operator();
7947 static constexpr int _S_arity = 2;
7948 template<
typename _Pattern>
7949 static constexpr bool _S_has_simple_extra_args
7950 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7953 inline constexpr _JoinWith join_with;
7957#ifdef __cpp_lib_ranges_repeat
7958 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7959 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7960 && (__detail::__is_signed_integer_like<_Bound>
7961 || (__detail::__is_integer_like<_Bound> && weakly_incrementable<_Bound>)
7962 || same_as<_Bound, unreachable_sentinel_t>)
7963 class repeat_view : public
view_interface<repeat_view<_Tp, _Bound>>
7966 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7967 using _Iterator = _Repeat_iterator<const _Tp, __index_type>;
7969 [[no_unique_address]] __detail::__box<_Tp> _M_value;
7970 [[no_unique_address]] _Bound _M_bound = _Bound();
7972 template<
typename _Range>
7973 friend constexpr auto
7974 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7976 template<
typename _Range>
7977 friend constexpr auto
7978 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7981 repeat_view()
requires default_initializable<_Tp> = default;
7984 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7985 requires copy_constructible<_Tp>
7986 : _M_value(__value), _M_bound(__bound)
7988 if constexpr (__detail::__is_signed_integer_like<_Bound>)
7989 __glibcxx_assert(__bound >= 0);
7993 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7994 : _M_value(std::move(__value)), _M_bound(__bound)
7996 if constexpr (__detail::__is_signed_integer_like<_Bound>)
7997 __glibcxx_assert(__bound >= 0);
8000 template<
typename... _Args,
typename... _BoundArgs>
8001 requires constructible_from<_Tp, _Args...>
8002 && constructible_from<_Bound, _BoundArgs...>
8004 repeat_view(piecewise_construct_t,
8005 tuple<_Args...> __args,
8006 tuple<_BoundArgs...> __bound_args = tuple<>{})
8007 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
8008 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
8010 if constexpr (__detail::__is_signed_integer_like<_Bound>)
8011 __glibcxx_assert(_M_bound >= 0);
8016 {
return std::__make_repeat_iterator(*_M_value, __index_type(0)); }
8019 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
8020 {
return std::__make_repeat_iterator(*_M_value, _M_bound); }
8022 constexpr unreachable_sentinel_t
8023 end() const noexcept
8024 {
return unreachable_sentinel; }
8027 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
8028 {
return __detail::__to_unsigned_like(_M_bound); }
8033 template<
typename _Tp,
typename _Bound = unreachable_sentinel_t>
8034 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
8040 template<
typename _Tp,
typename _Bound>
8041 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
8043 template<
typename _Tp>
8044 concept __can_repeat_view
8047 template<
typename _Tp,
typename _Bound>
8048 concept __can_bounded_repeat_view
8054 template<
typename _Tp>
8055 requires __detail::__can_repeat_view<_Tp>
8057 operator() [[nodiscard]] (_Tp&& __value)
const
8064 template<
typename _Tp,
typename _Bound>
8065 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
8067 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
8071 inline constexpr _Repeat repeat;
8075 template<
typename _Range>
8077 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8079 using _Tp = remove_cvref_t<_Range>;
8080 static_assert(__is_repeat_view<_Tp>);
8081 if constexpr (sized_range<_Tp>)
8083 std::min(ranges::distance(__r), __n));
8088 template<
typename _Range>
8090 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8092 using _Tp = remove_cvref_t<_Range>;
8093 static_assert(__is_repeat_view<_Tp>);
8094 if constexpr (sized_range<_Tp>)
8096 auto __sz = ranges::distance(__r);
8107#ifdef __cpp_lib_ranges_stride
8108 template<input_range _Vp>
8113 range_difference_t<_Vp> _M_stride;
8115 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8117 template<
bool _Const>
8121 template<
bool _Const>
8122 requires forward_range<_Base<_Const>>
8123 struct __iter_cat<_Const>
8129 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8130 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8131 return random_access_iterator_tag{};
8136 using iterator_category =
decltype(_S_iter_cat());
8139 template<
bool>
class _Iterator;
8143 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8144 : _M_base(std::move(
__base)), _M_stride(__stride)
8145 { __glibcxx_assert(__stride > 0); }
8148 base() const& requires copy_constructible<_Vp>
8155 constexpr range_difference_t<_Vp>
8156 stride() const noexcept
8157 {
return _M_stride; }
8160 begin()
requires (!__detail::__simple_view<_Vp>)
8161 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
8164 begin() const requires range<const _Vp>
8165 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
8168 end()
requires (!__detail::__simple_view<_Vp>)
8170 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8172 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8173 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
8175 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8176 return _Iterator<false>(
this, ranges::end(_M_base));
8182 end() const requires range<const _Vp>
8184 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8185 && forward_range<const _Vp>)
8187 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8188 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
8190 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8191 return _Iterator<true>(
this, ranges::end(_M_base));
8197 size()
requires sized_range<_Vp>
8199 return __detail::__to_unsigned_like
8200 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8204 size() const requires sized_range<const _Vp>
8206 return __detail::__to_unsigned_like
8207 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8211 template<
typename _Range>
8212 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8214 template<
typename _Vp>
8215 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8216 = enable_borrowed_range<_Vp>;
8218 template<input_range _Vp>
8220 template<
bool _Const>
8221 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8223 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8224 using _Base = stride_view::_Base<_Const>;
8226 iterator_t<_Base> _M_current = iterator_t<_Base>();
8227 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8228 range_difference_t<_Base> _M_stride = 0;
8229 range_difference_t<_Base> _M_missing = 0;
8232 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8233 range_difference_t<_Base> __missing = 0)
8234 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8235 _M_stride(__parent->_M_stride), _M_missing(__missing)
8241 if constexpr (random_access_range<_Base>)
8242 return random_access_iterator_tag{};
8243 else if constexpr (bidirectional_range<_Base>)
8244 return bidirectional_iterator_tag{};
8245 else if constexpr (forward_range<_Base>)
8246 return forward_iterator_tag{};
8248 return input_iterator_tag{};
8254 using difference_type = range_difference_t<_Base>;
8255 using value_type = range_value_t<_Base>;
8256 using iterator_concept =
decltype(_S_iter_concept());
8259 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8262 _Iterator(_Iterator<!_Const> __other)
8264 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8265 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8266 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8267 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8270 constexpr iterator_t<_Base>
8274 constexpr const iterator_t<_Base>&
8275 base() const & noexcept
8276 {
return _M_current; }
8278 constexpr decltype(
auto)
8280 {
return *_M_current; }
8282 constexpr _Iterator&
8285 __glibcxx_assert(_M_current != _M_end);
8286 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8295 operator++(
int)
requires forward_range<_Base>
8302 constexpr _Iterator&
8303 operator--()
requires bidirectional_range<_Base>
8305 ranges::advance(_M_current, _M_missing - _M_stride);
8311 operator--(
int)
requires bidirectional_range<_Base>
8318 constexpr _Iterator&
8319 operator+=(difference_type __n)
requires random_access_range<_Base>
8323 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8324 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8328 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8334 constexpr _Iterator&
8335 operator-=(difference_type __n)
requires random_access_range<_Base>
8336 {
return *
this += -__n; }
8338 constexpr decltype(
auto)
operator[](difference_type __n)
const
8339 requires random_access_range<_Base>
8340 {
return *(*
this + __n); }
8342 friend constexpr bool
8343 operator==(
const _Iterator& __x, default_sentinel_t)
8344 {
return __x._M_current == __x._M_end; }
8346 friend constexpr bool
8347 operator==(
const _Iterator& __x,
const _Iterator& __y)
8348 requires equality_comparable<iterator_t<_Base>>
8349 {
return __x._M_current == __y._M_current; }
8351 friend constexpr bool
8352 operator<(
const _Iterator& __x,
const _Iterator& __y)
8353 requires random_access_range<_Base>
8354 {
return __x._M_current < __y._M_current; }
8356 friend constexpr bool
8357 operator>(
const _Iterator& __x,
const _Iterator& __y)
8358 requires random_access_range<_Base>
8359 {
return __y._M_current < __x._M_current; }
8361 friend constexpr bool
8362 operator<=(
const _Iterator& __x,
const _Iterator& __y)
8363 requires random_access_range<_Base>
8364 {
return !(__y._M_current < __x._M_current); }
8366 friend constexpr bool
8367 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8368 requires random_access_range<_Base>
8369 {
return !(__x._M_current < __y._M_current); }
8371 friend constexpr auto
8372 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8373 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8374 {
return __x._M_current <=> __y._M_current; }
8376 friend constexpr _Iterator
8377 operator+(
const _Iterator& __i, difference_type __n)
8378 requires random_access_range<_Base>
8385 friend constexpr _Iterator
8386 operator+(difference_type __n,
const _Iterator& __i)
8387 requires random_access_range<_Base>
8388 {
return __i + __n; }
8390 friend constexpr _Iterator
8391 operator-(
const _Iterator& __i, difference_type __n)
8392 requires random_access_range<_Base>
8399 friend constexpr difference_type
8400 operator-(
const _Iterator& __x,
const _Iterator& __y)
8401 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8403 auto __n = __x._M_current - __y._M_current;
8404 if constexpr (forward_range<_Base>)
8405 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8407 return -__detail::__div_ceil(-__n, __x._M_stride);
8409 return __detail::__div_ceil(__n, __x._M_stride);
8412 friend constexpr difference_type
8413 operator-(default_sentinel_t,
const _Iterator& __x)
8414 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8415 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8417 friend constexpr difference_type
8418 operator-(
const _Iterator& __x, default_sentinel_t __y)
8419 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8420 {
return -(__y - __x); }
8422 friend constexpr range_rvalue_reference_t<_Base>
8423 iter_move(
const _Iterator& __i)
8424 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8425 {
return ranges::iter_move(__i._M_current); }
8427 friend constexpr void
8428 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8429 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8430 requires indirectly_swappable<iterator_t<_Base>>
8431 { ranges::iter_swap(__x._M_current, __y._M_current); }
8438 template<
typename _Range,
typename _Dp>
8439 concept __can_stride_view
8443 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8445 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8446 requires __detail::__can_stride_view<_Range, _Dp>
8448 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8451 using __adaptor::_RangeAdaptor<_Stride>::operator();
8452 static constexpr int _S_arity = 2;
8453 static constexpr bool _S_has_simple_extra_args =
true;
8456 inline constexpr _Stride stride;
8460#ifdef __cpp_lib_ranges_cartesian_product
8463 template<
bool _Const,
typename _First,
typename... _Vs>
8464 concept __cartesian_product_is_random_access
8465 = (random_access_range<__maybe_const_t<_Const, _First>>
8467 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8468 && sized_range<__maybe_const_t<_Const, _Vs>>));
8470 template<
typename _Range>
8471 concept __cartesian_product_common_arg
8472 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8474 template<
bool _Const,
typename _First,
typename... _Vs>
8475 concept __cartesian_product_is_bidirectional
8476 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8478 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8479 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8481 template<
typename _First,
typename... _Vs>
8482 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8484 template<
typename... _Vs>
8485 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8487 template<
bool _Const,
template<
typename>
class _FirstSent,
8488 typename _First,
typename... _Vs>
8489 concept __cartesian_is_sized_sentinel
8490 = (sized_sentinel_for<_FirstSent<__maybe_const_t<_Const, _First>>,
8491 iterator_t<__maybe_const_t<_Const, _First>>>
8493 && (sized_range<__maybe_const_t<_Const, _Vs>>
8494 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8495 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8497 template<__cartesian_product_common_arg _Range>
8499 __cartesian_common_arg_end(_Range& __r)
8501 if constexpr (common_range<_Range>)
8502 return ranges::end(__r);
8504 return ranges::begin(__r) + ranges::distance(__r);
8510 class cartesian_product_view : public
view_interface<cartesian_product_view<_First, _Vs...>>
8512 tuple<_First, _Vs...> _M_bases;
8514 template<
bool>
class _Iterator;
8517 _S_difference_type()
8523 range_difference_t<_First>,
8524 range_difference_t<_Vs>...>{};
8528 cartesian_product_view() =
default;
8531 cartesian_product_view(_First __first, _Vs... __rest)
8532 : _M_bases(std::move(__first), std::move(__rest)...)
8535 constexpr _Iterator<false>
8536 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8537 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8539 constexpr _Iterator<true>
8540 begin() const requires (
range<const _First> && ... &&
range<const _Vs>)
8541 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8543 constexpr _Iterator<false>
8544 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8545 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8548 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8549 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8550 auto& __first = std::get<0>(_M_bases);
8551 return _Ret{(__empty_tail
8552 ? ranges::begin(__first)
8553 : __detail::__cartesian_common_arg_end(__first)),
8554 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8557 return _Iterator<false>{*
this,
std::move(__its)};
8560 constexpr _Iterator<true>
8561 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8564 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8565 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8566 auto& __first = std::get<0>(_M_bases);
8567 return _Ret{(__empty_tail
8568 ? ranges::begin(__first)
8569 : __detail::__cartesian_common_arg_end(__first)),
8570 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8573 return _Iterator<true>{*
this,
std::move(__its)};
8576 constexpr default_sentinel_t
8577 end() const noexcept
8581 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8583 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8585 auto __size =
static_cast<_ST
>(1);
8586#ifdef _GLIBCXX_ASSERTIONS
8587 if constexpr (integral<_ST>)
8590 = (__builtin_mul_overflow(__size,
8591 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8594 __glibcxx_assert(!__overflow);
8598 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8604 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8606 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8608 auto __size =
static_cast<_ST
>(1);
8609#ifdef _GLIBCXX_ASSERTIONS
8610 if constexpr (integral<_ST>)
8613 = (__builtin_mul_overflow(__size,
8614 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8617 __glibcxx_assert(!__overflow);
8621 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8627 template<
typename... _Vs>
8628 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8632 template<bool _Const>
8633 class cartesian_product_view<_First, _Vs...>::_Iterator
8635 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8636 _Parent* _M_parent =
nullptr;
8637 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8638 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8641 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8643 _M_current(std::move(__current))
8649 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8650 return random_access_iterator_tag{};
8651 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8652 return bidirectional_iterator_tag{};
8654 return forward_iterator_tag{};
8656 return input_iterator_tag{};
8659 friend cartesian_product_view;
8662 using iterator_category = input_iterator_tag;
8663 using iterator_concept =
decltype(_S_iter_concept());
8665 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8666 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8668 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8669 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8670 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8672 _Iterator() =
default;
8675 _Iterator(_Iterator<!_Const> __i)
8677 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8678 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8680 _M_current(std::move(__i._M_current))
8686 auto __f = [](
auto& __i) ->
decltype(
auto) {
8689 return __detail::__tuple_transform(__f, _M_current);
8692 constexpr _Iterator&
8711 constexpr _Iterator&
8713 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8721 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8728 constexpr _Iterator&
8729 operator+=(difference_type __x)
8730 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8736 constexpr _Iterator&
8737 operator-=(difference_type __x)
8738 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8739 {
return *
this += -__x; }
8742 operator[](difference_type __n)
const
8743 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8744 {
return *((*this) + __n); }
8746 friend constexpr bool
8747 operator==(
const _Iterator& __x,
const _Iterator& __y)
8748 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8749 {
return __x._M_current == __y._M_current; }
8751 friend constexpr bool
8752 operator==(
const _Iterator& __x, default_sentinel_t)
8755 return ((std::get<_Is>(__x._M_current)
8756 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8761 friend constexpr auto
8762 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8763 requires __detail::__all_random_access<_Const, _First, _Vs...>
8764 {
return __x._M_current <=> __y._M_current; }
8766 friend constexpr _Iterator
8767 operator+(_Iterator __x, difference_type __y)
8768 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8769 {
return __x += __y; }
8771 friend constexpr _Iterator
8772 operator+(difference_type __x, _Iterator __y)
8773 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8774 {
return __y += __x; }
8776 friend constexpr _Iterator
8777 operator-(_Iterator __x, difference_type __y)
8778 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8779 {
return __x -= __y; }
8781 friend constexpr difference_type
8782 operator-(
const _Iterator& __x,
const _Iterator& __y)
8783 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8784 {
return __x._M_distance_from(__y._M_current); }
8786 friend constexpr difference_type
8787 operator-(
const _Iterator& __i, default_sentinel_t)
8788 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8791 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8792 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8794 return __i._M_distance_from(__end_tuple);
8797 friend constexpr difference_type
8798 operator-(default_sentinel_t,
const _Iterator& __i)
8799 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8802 friend constexpr auto
8803 iter_move(
const _Iterator& __i)
8804 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8806 friend constexpr void
8807 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8808 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8810 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8813 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8818 template<
size_t _Nm =
sizeof...(_Vs)>
8822 auto& __it = std::get<_Nm>(_M_current);
8824 if constexpr (_Nm > 0)
8825 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8827 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8832 template<
size_t _Nm =
sizeof...(_Vs)>
8836 auto& __it = std::get<_Nm>(_M_current);
8837 if constexpr (_Nm > 0)
8838 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8840 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8846 template<
size_t _Nm =
sizeof...(_Vs)>
8848 _M_advance(difference_type __x)
8849 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8858 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8859 auto& __it = std::get<_Nm>(_M_current);
8860 if constexpr (_Nm == 0)
8862#ifdef _GLIBCXX_ASSERTIONS
8865 auto __size = ranges::ssize(__r);
8866 auto __begin = ranges::begin(__r);
8867 auto __offset = __it - __begin;
8868 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8875 auto __size = ranges::ssize(__r);
8876 auto __begin = ranges::begin(__r);
8877 auto __offset = __it - __begin;
8879 __x = __offset / __size;
8883 __offset = __size + __offset;
8886 __it = __begin + __offset;
8887 _M_advance<_Nm - 1>(__x);
8892 template<
typename _Tuple>
8893 constexpr difference_type
8894 _M_distance_from(
const _Tuple& __t)
const
8897 auto __sum =
static_cast<difference_type
>(0);
8898#ifdef _GLIBCXX_ASSERTIONS
8899 if constexpr (integral<difference_type>)
8902 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8904 __glibcxx_assert(!__overflow);
8908 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8913 template<
size_t _Nm,
typename _Tuple>
8914 constexpr difference_type
8915 _M_scaled_distance(
const _Tuple& __t)
const
8917 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8918 - std::get<_Nm>(__t));
8919#ifdef _GLIBCXX_ASSERTIONS
8920 if constexpr (integral<difference_type>)
8922 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8923 __glibcxx_assert(!__overflow);
8927 __dist *= _M_scaled_size<_Nm+1>();
8931 template<
size_t _Nm>
8932 constexpr difference_type
8933 _M_scaled_size()
const
8935 if constexpr (_Nm <=
sizeof...(_Vs))
8937 auto __size =
static_cast<difference_type
>(ranges::size
8938 (std::get<_Nm>(_M_parent->_M_bases)));
8939#ifdef _GLIBCXX_ASSERTIONS
8940 if constexpr (integral<difference_type>)
8942 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8943 __glibcxx_assert(!__overflow);
8947 __size *= _M_scaled_size<_Nm+1>();
8951 return static_cast<difference_type
>(1);
8959 template<
typename... _Ts>
8960 concept __can_cartesian_product_view
8964 struct _CartesianProduct
8966 template<
typename... _Ts>
8967 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8969 operator() [[nodiscard]] (_Ts&&... __ts)
const
8971 if constexpr (
sizeof...(_Ts) == 0)
8972 return views::single(tuple{});
8978 inline constexpr _CartesianProduct cartesian_product;
8982#ifdef __cpp_lib_ranges_as_rvalue
8983 template<input_range _Vp>
8985 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
8987 _Vp _M_base = _Vp();
8990 as_rvalue_view()
requires default_initializable<_Vp> = default;
8993 as_rvalue_view(_Vp __base)
8994 : _M_base(std::move(__base))
8998 base() const& requires copy_constructible<_Vp>
9006 begin()
requires (!__detail::__simple_view<_Vp>)
9007 {
return move_iterator(ranges::begin(_M_base)); }
9010 begin() const requires range<const _Vp>
9011 {
return move_iterator(ranges::begin(_M_base)); }
9014 end()
requires (!__detail::__simple_view<_Vp>)
9016 if constexpr (common_range<_Vp>)
9017 return move_iterator(ranges::end(_M_base));
9019 return move_sentinel(ranges::end(_M_base));
9023 end() const requires range<const _Vp>
9025 if constexpr (common_range<const _Vp>)
9026 return move_iterator(ranges::end(_M_base));
9028 return move_sentinel(ranges::end(_M_base));
9032 size()
requires sized_range<_Vp>
9033 {
return ranges::size(_M_base); }
9036 size() const requires sized_range<const _Vp>
9037 {
return ranges::size(_M_base); }
9040 template<
typename _Range>
9041 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
9043 template<
typename _Tp>
9044 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
9045 = enable_borrowed_range<_Tp>;
9051 template<
typename _Tp>
9052 concept __can_as_rvalue_view =
requires { as_rvalue_view(
std::declval<_Tp>()); };
9055 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
9057 template<viewable_range _Range>
9058 requires __detail::__can_as_rvalue_view<_Range>
9060 operator() [[nodiscard]] (_Range&& __r)
const
9065 if constexpr (same_as<range_rvalue_reference_t<_Range>,
9066 range_reference_t<_Range>>)
9073 inline constexpr _AsRvalue as_rvalue;
9077#ifdef __cpp_lib_ranges_enumerate
9080 template<
typename _Range>
9081 concept __range_with_movable_reference = input_range<_Range>
9082 && move_constructible<range_reference_t<_Range>>
9083 && move_constructible<range_rvalue_reference_t<_Range>>;
9087 requires __detail::__range_with_movable_reference<_Vp>
9088 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
9090 _Vp _M_base = _Vp();
9092 template<
bool _Const>
class _Iterator;
9093 template<
bool _Const>
class _Sentinel;
9096 enumerate_view()
requires default_initializable<_Vp> = default;
9099 enumerate_view(_Vp __base)
9100 : _M_base(std::move(__base))
9104 begin()
requires (!__detail::__simple_view<_Vp>)
9105 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
9108 begin() const requires __detail::__range_with_movable_reference<const _Vp>
9109 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
9112 end()
requires (!__detail::__simple_view<_Vp>)
9114 if constexpr (common_range<_Vp> && sized_range<_Vp>)
9115 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
9117 return _Sentinel<false>(ranges::end(_M_base));
9121 end() const requires __detail::__range_with_movable_reference<const _Vp>
9123 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9124 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9126 return _Sentinel<true>(ranges::end(_M_base));
9130 size()
requires sized_range<_Vp>
9131 {
return ranges::size(_M_base); }
9134 size() const requires sized_range<const _Vp>
9135 {
return ranges::size(_M_base); }
9138 base() const & requires copy_constructible<_Vp>
9146 template<
typename _Range>
9147 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9149 template<
typename _Tp>
9150 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9151 = enable_borrowed_range<_Tp>;
9154 requires __detail::__range_with_movable_reference<_Vp>
9155 template<
bool _Const>
9156 class enumerate_view<_Vp>::_Iterator
9158 using _Base = __maybe_const_t<_Const, _Vp>;
9163 if constexpr (random_access_range<_Base>)
9164 return random_access_iterator_tag{};
9165 else if constexpr (bidirectional_range<_Base>)
9166 return bidirectional_iterator_tag{};
9167 else if constexpr (forward_range<_Base>)
9168 return forward_iterator_tag{};
9170 return input_iterator_tag{};
9173 friend enumerate_view;
9176 using iterator_category = input_iterator_tag;
9177 using iterator_concept =
decltype(_S_iter_concept());
9178 using difference_type = range_difference_t<_Base>;
9179 using value_type = tuple<difference_type, range_value_t<_Base>>;
9182 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9184 iterator_t<_Base> _M_current = iterator_t<_Base>();
9185 difference_type _M_pos = 0;
9188 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9189 : _M_current(std::move(__current)), _M_pos(__pos)
9193 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
9196 _Iterator(_Iterator<!_Const> __i)
9197 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9198 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9201 constexpr const iterator_t<_Base> &
9202 base() const & noexcept
9203 {
return _M_current; }
9205 constexpr iterator_t<_Base>
9209 constexpr difference_type
9210 index() const noexcept
9215 {
return __reference_type(_M_pos, *_M_current); }
9217 constexpr _Iterator&
9230 operator++(
int)
requires forward_range<_Base>
9237 constexpr _Iterator&
9238 operator--()
requires bidirectional_range<_Base>
9246 operator--(
int)
requires bidirectional_range<_Base>
9253 constexpr _Iterator&
9254 operator+=(difference_type __n)
requires random_access_range<_Base>
9261 constexpr _Iterator&
9262 operator-=(difference_type __n)
requires random_access_range<_Base>
9270 operator[](difference_type __n)
const requires random_access_range<_Base>
9271 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9273 friend constexpr bool
9274 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9275 {
return __x._M_pos == __y._M_pos; }
9277 friend constexpr strong_ordering
9278 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9279 {
return __x._M_pos <=> __y._M_pos; }
9281 friend constexpr _Iterator
9282 operator+(
const _Iterator& __x, difference_type __y)
9283 requires random_access_range<_Base>
9284 {
return (
auto(__x) += __y); }
9286 friend constexpr _Iterator
9287 operator+(difference_type __x,
const _Iterator& __y)
9288 requires random_access_range<_Base>
9289 {
return auto(__y) += __x; }
9291 friend constexpr _Iterator
9292 operator-(
const _Iterator& __x, difference_type __y)
9293 requires random_access_range<_Base>
9294 {
return auto(__x) -= __y; }
9296 friend constexpr difference_type
9297 operator-(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9298 {
return __x._M_pos - __y._M_pos; }
9300 friend constexpr auto
9301 iter_move(
const _Iterator& __i)
9302 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9303 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9305 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9306 (__i._M_pos, ranges::iter_move(__i._M_current));
9311 requires __detail::__range_with_movable_reference<_Vp>
9312 template<
bool _Const>
9313 class enumerate_view<_Vp>::_Sentinel
9315 using _Base = __maybe_const_t<_Const, _Vp>;
9317 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9320 _Sentinel(sentinel_t<_Base> __end)
9321 : _M_end(std::move(__end))
9324 friend enumerate_view;
9327 _Sentinel() =
default;
9330 _Sentinel(_Sentinel<!_Const> __other)
9331 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9335 constexpr sentinel_t<_Base>
9339 template<
bool _OtherConst>
9340 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9341 friend constexpr bool
9342 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9343 {
return __x._M_current == __y._M_end; }
9345 template<
bool _OtherConst>
9346 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9347 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9348 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9349 {
return __x._M_current - __y._M_end; }
9351 template<
bool _OtherConst>
9352 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9353 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9354 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9355 {
return __x._M_end - __y._M_current; }
9362 template<
typename _Tp>
9363 concept __can_enumerate_view
9367 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9369 template<viewable_range _Range>
9370 requires __detail::__can_enumerate_view<_Range>
9372 operator() [[nodiscard]] (_Range&& __r)
const
9376 inline constexpr _Enumerate enumerate;
9380#ifdef __cpp_lib_ranges_as_const
9385 _Vp _M_base = _Vp();
9388 as_const_view()
requires default_initializable<_Vp> = default;
9391 as_const_view(_Vp __base)
9392 noexcept(is_nothrow_move_constructible_v<_Vp>)
9393 : _M_base(std::move(__base))
9398 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9399 requires copy_constructible<_Vp>
9404 noexcept(is_nothrow_move_constructible_v<_Vp>)
9408 begin()
requires (!__detail::__simple_view<_Vp>)
9409 {
return ranges::cbegin(_M_base); }
9412 begin() const requires range<const _Vp>
9413 {
return ranges::cbegin(_M_base); }
9416 end()
requires (!__detail::__simple_view<_Vp>)
9417 {
return ranges::cend(_M_base); }
9420 end() const requires range<const _Vp>
9421 {
return ranges::cend(_M_base); }
9424 size()
requires sized_range<_Vp>
9425 {
return ranges::size(_M_base); }
9428 size() const requires sized_range<const _Vp>
9429 {
return ranges::size(_M_base); }
9432 template<
typename _Range>
9433 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9435 template<
typename _Tp>
9436 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9437 = enable_borrowed_range<_Tp>;
9443 template<
typename _Tp>
9444 inline constexpr bool __is_constable_ref_view =
false;
9446 template<
typename _Range>
9447 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9448 = constant_range<const _Range>;
9450 template<
typename _Range>
9454 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9456 template<viewable_range _Range>
9458 operator()(_Range&& __r)
const
9460 requires __detail::__can_as_const_view<_Range>
9462 using _Tp = remove_cvref_t<_Range>;
9463 using element_type = remove_reference_t<range_reference_t<_Range>>;
9464 if constexpr (constant_range<views::all_t<_Range>>)
9466 else if constexpr (__detail::__is_empty_view<_Tp>)
9467 return views::empty<const element_type>;
9468#if __cpp_lib_optional >= 202506L && __cpp_lib_optional_range_support
9469 else if constexpr (__is_optional_ref_v<_Tp>)
9470 return optional<const typename _Tp::value_type&>(__r);
9472 else if constexpr (std::__detail::__is_span<_Tp>)
9474 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9476 else if constexpr (is_lvalue_reference_v<_Range>
9477 && constant_range<const _Tp>
9479 return ref_view(
static_cast<const _Tp&
>(__r));
9485 inline constexpr _AsConst as_const;
9490 namespace views = ranges::views;
9492#if __cpp_lib_ranges_to_container
9498 template<
typename _Container>
9499 constexpr bool __reservable_container
9500 = sized_range<_Container>
9501 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9503 { __c.capacity() } -> same_as<
decltype(__n)>;
9504 { __c.max_size() } -> same_as<
decltype(__n)>;
9507 template<
typename _Cont,
typename _Range>
9508 constexpr bool __toable =
requires {
9509 requires (!input_range<_Cont>
9510 || convertible_to<range_reference_t<_Range>,
9511 range_value_t<_Cont>>);
9532 template<
typename _Cont, input_range _Rg,
typename... _Args>
9533 requires (!view<_Cont>)
9535 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9537 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9538 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9540 if constexpr (__detail::__toable<_Cont, _Rg>)
9542 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9545 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9548 else if constexpr (
requires {
requires common_range<_Rg>;
9549 typename __iter_category_t<iterator_t<_Rg>>;
9550 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9551 input_iterator_tag>;
9552 requires constructible_from<_Cont, iterator_t<_Rg>,
9553 sentinel_t<_Rg>, _Args...>;
9555 return _Cont(ranges::begin(__r), ranges::end(__r),
9559 static_assert(constructible_from<_Cont, _Args...>);
9561 if constexpr (sized_range<_Rg>
9562 && __detail::__reservable_container<_Cont>)
9563 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9567 auto __it = ranges::begin(__r);
9568 const auto __sent = ranges::end(__r);
9569 while (__it != __sent)
9571 if constexpr (
requires { __c.emplace_back(*__it); })
9572 __c.emplace_back(*__it);
9573 else if constexpr (
requires { __c.push_back(*__it); })
9574 __c.push_back(*__it);
9575 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9576 __c.emplace(__c.end(), *__it);
9578 __c.insert(__c.end(), *__it);
9586 static_assert(input_range<range_reference_t<_Rg>>);
9589 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9590 []<
typename _Elt>(_Elt&& __elem) {
9591 using _ValT = range_value_t<_Cont>;
9600 template<
typename _Rg>
9603 using iterator_category = input_iterator_tag;
9604 using value_type = range_value_t<_Rg>;
9605 using difference_type = ptrdiff_t;
9606 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9607 using reference = range_reference_t<_Rg>;
9609 pointer operator->()
const;
9610 _InputIter& operator++();
9611 _InputIter operator++(
int);
9612 bool operator==(
const _InputIter&)
const;
9615 template<
template<
typename...>
typename _Cont, input_range _Rg,
9620 template<
template<
typename...>
typename _Cont, input_range _Rg,
9626 template<
template<
typename...>
typename _Cont, input_range _Rg,
9636 template<
template<
typename...>
typename _Cont, input_range _Rg,
9639 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9641 using __detail::_DeduceExpr1;
9642 using __detail::_DeduceExpr2;
9643 using __detail::_DeduceExpr3;
9644 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9645 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9647 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9648 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9650 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9651 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9654 static_assert(
false);
9660 template<
typename _Cont>
9663 template<
typename _Range,
typename... _Args>
9667 operator()(_Range&& __r, _Args&&... __args)
const
9691 template<
typename _Cont,
typename... _Args>
9692 requires (!view<_Cont>)
9694 to [[nodiscard]] (_Args&&... __args)
9696 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9697 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9699 using __detail::_To;
9700 using views::__adaptor::_Partial;
9707 template<
template<
typename...>
typename _Cont>
9710 template<
typename _Range,
typename... _Args>
9714 operator()(_Range&& __r, _Args&&... __args)
const
9740 template<
template<
typename...>
typename _Cont,
typename... _Args>
9742 to [[nodiscard]] (_Args&&... __args)
9744 using __detail::_To2;
9745 using views::__adaptor::_Partial;
9752#if __cpp_lib_ranges_concat
9757 template<
bool _Const,
typename _Range,
typename... _Rs>
9758 struct __all_but_last_common
9760 static inline constexpr bool value
9761 =
requires {
requires (common_range<__maybe_const_t<_Const, _Range>>
9762 && __all_but_last_common<_Const, _Rs...>::value); };
9765 template<
bool _Const,
typename _Range>
9766 struct __all_but_last_common<_Const, _Range>
9767 {
static inline constexpr bool value =
true; };
9769 template<
bool _Const,
typename... _Rs>
9770 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9771 && __all_but_last_common<_Const, _Rs...>::value;
9773 template<
bool _Const,
typename... _Rs>
9774 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9775 && __all_but_last_common<_Const, _Rs...>::value;
9777 template<
typename _Range,
typename... _Rs>
9778 struct __all_but_first_sized
9779 {
static inline constexpr bool value = (sized_range<_Rs> && ...); };
9782 template<input_range... _Vs>
9783 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9784 class concat_view : public view_interface<concat_view<_Vs...>>
9786 tuple<_Vs...> _M_views;
9788 template<
bool _Const>
class _Iterator;
9791 constexpr concat_view() =
default;
9794 concat_view(_Vs... __views)
9795 : _M_views(std::move(__views)...)
9798 constexpr _Iterator<false>
9799 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
9801 _Iterator<false> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9802 __it.template _M_satisfy<0>();
9806 constexpr _Iterator<true>
9807 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9809 _Iterator<true> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9810 __it.template _M_satisfy<0>();
9815 end()
requires (!(__detail::__simple_view<_Vs> && ...))
9817 constexpr auto __n =
sizeof...(_Vs);
9818 if constexpr (__detail::__all_forward<
false, _Vs...>
9819 && common_range<_Vs...[__n - 1]>)
9820 return _Iterator<false>(
this, in_place_index<__n - 1>,
9821 ranges::end(std::get<__n - 1>(_M_views)));
9827 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9829 constexpr auto __n =
sizeof...(_Vs);
9830 if constexpr (__detail::__all_forward<
true, _Vs...>
9831 && common_range<
const _Vs...[__n - 1]>)
9832 return _Iterator<true>(
this, in_place_index<__n - 1>,
9833 ranges::end(std::get<__n - 1>(_M_views)));
9839 size()
requires (sized_range<_Vs>&&...)
9841 return std::apply([](
auto... __sizes) {
9842 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9843 return (_CT(__sizes) + ...);
9844 }, __detail::__tuple_transform(ranges::size, _M_views));
9848 size() const requires (sized_range<const _Vs>&&...)
9850 return std::apply([](
auto... __sizes) {
9851 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9852 return (_CT(__sizes) + ...);
9853 }, __detail::__tuple_transform(ranges::size, _M_views));
9857 template<
typename... _Rs>
9858 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9862 template<
bool _Const,
typename... _Vs>
9863 struct __concat_view_iter_cat
9866 template<
bool _Const,
typename... _Vs>
9867 requires __detail::__all_forward<_Const, _Vs...>
9868 struct __concat_view_iter_cat<_Const, _Vs...>
9873 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9874 return input_iterator_tag{};
9876 return []<
typename... _Cats>(_Cats... __cats) {
9877 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9878 && __concat_is_random_access<_Const, _Vs...>)
9879 return random_access_iterator_tag{};
9880 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9881 && __concat_is_bidirectional<_Const, _Vs...>)
9882 return bidirectional_iterator_tag{};
9883 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9884 return forward_iterator_tag{};
9886 return input_iterator_tag{};
9887 }(
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9888 ::iterator_category{}...);
9893 template<input_range... _Vs>
9894 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9895 template<bool _Const>
9896 class concat_view<_Vs...>::_Iterator
9897 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9902 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9903 return random_access_iterator_tag{};
9904 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9905 return bidirectional_iterator_tag{};
9906 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9907 return forward_iterator_tag{};
9909 return input_iterator_tag{};
9913 friend _Iterator<!_Const>;
9917 using iterator_concept =
decltype(_S_iter_concept());
9918 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9919 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9922 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9924 __maybe_const_t<_Const, concat_view>* _M_parent =
nullptr;
9927 template<
size_t _Nm>
9931 if constexpr (_Nm < (
sizeof...(_Vs) - 1))
9933 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9935 _M_it.template emplace<_Nm + 1>(ranges::begin
9936 (std::get<_Nm + 1>(_M_parent->_M_views)));
9937 _M_satisfy<_Nm + 1>();
9942 template<
size_t _Nm>
9946 if constexpr (_Nm == 0)
9947 --std::get<0>(_M_it);
9950 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9952 _M_it.template emplace<_Nm - 1>(ranges::end
9953 (std::get<_Nm - 1>(_M_parent->_M_views)));
9957 --std::get<_Nm>(_M_it);
9961 template<
size_t _Nm>
9963 _M_advance_fwd(difference_type __offset, difference_type __steps)
9965 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9966 if constexpr (_Nm ==
sizeof...(_Vs) - 1)
9967 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
9970 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9971 if (__offset + __steps < __n_size)
9972 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
9975 _M_it.template emplace<_Nm + 1>(ranges::begin
9976 (std::get<_Nm + 1>(_M_parent->_M_views)));
9977 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9982 template<
size_t _Nm>
9984 _M_advance_bwd(difference_type __offset, difference_type __steps)
9986 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9987 if constexpr (_Nm == 0)
9988 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
9990 if (__offset >= __steps)
9991 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
9994 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9995 _M_it.template emplace<_Nm - 1>(ranges::end
9996 (std::get<_Nm - 1>(_M_parent->_M_views)));
9997 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
10005 template<
typename _Fp>
10006 static constexpr auto
10007 _S_invoke_with_runtime_index(_Fp&& __f,
size_t __index)
10009 return [&__f, __index]<
size_t _Idx>(
this auto&& __self) {
10010 if (_Idx == __index)
10011 return __f.template operator()<_Idx>();
10012 if constexpr (_Idx + 1 <
sizeof...(_Vs))
10013 return __self.template
operator()<_Idx + 1>();
10014 __builtin_unreachable();
10015 }.template operator()<0>();
10018 template<
typename _Fp>
10020 _M_invoke_with_runtime_index(_Fp&& __f)
10021 {
return _S_invoke_with_runtime_index(
std::forward<_Fp>(__f), _M_it.index()); }
10023 template<
typename... _Args>
10025 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
10026 requires constructible_from<__base_iter, _Args&&...>
10031 _Iterator() =
default;
10034 _Iterator(_Iterator<!_Const> __it)
10035 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
10036 : _M_parent(__it._M_parent),
10037 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
10038 return __base_iter(in_place_index<_Idx>,
10039 std::get<_Idx>(
std::move(__it._M_it)));
10040 }, __it._M_it.index()))
10043 constexpr decltype(
auto)
10046 __glibcxx_assert(!_M_it.valueless_by_exception());
10047 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
10048 return std::visit([](
auto&& __it) -> reference {
return *__it; }, _M_it);
10051 constexpr _Iterator&
10054 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10055 ++std::get<_Idx>(_M_it);
10056 _M_satisfy<_Idx>();
10065 constexpr _Iterator
10067 requires __detail::__all_forward<_Const, _Vs...>
10069 auto __tmp = *
this;
10074 constexpr _Iterator&
10076 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10078 __glibcxx_assert(!_M_it.valueless_by_exception());
10079 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10085 constexpr _Iterator
10087 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10089 auto __tmp = *
this;
10094 constexpr _Iterator&
10095 operator+=(difference_type __n)
10096 requires __detail::__concat_is_random_access<_Const, _Vs...>
10098 __glibcxx_assert(!_M_it.valueless_by_exception());
10099 _M_invoke_with_runtime_index([
this, __n]<
size_t _Idx>() {
10100 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10102 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10104 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10109 constexpr _Iterator&
10110 operator-=(difference_type __n)
10111 requires __detail::__concat_is_random_access<_Const, _Vs...>
10117 constexpr decltype(
auto)
10118 operator[](difference_type __n)
const
10119 requires __detail::__concat_is_random_access<_Const, _Vs...>
10120 {
return *((*this) + __n); }
10122 friend constexpr bool
10123 operator==(
const _Iterator& __x,
const _Iterator& __y)
10124 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10126 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10127 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10128 return __x._M_it == __y._M_it;
10131 friend constexpr bool
10132 operator==(
const _Iterator& __it, default_sentinel_t)
10134 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10135 constexpr auto __last_idx =
sizeof...(_Vs) - 1;
10136 return (__it._M_it.index() == __last_idx
10137 && (std::get<__last_idx>(__it._M_it)
10138 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10141 friend constexpr bool
10142 operator<(
const _Iterator& __x,
const _Iterator& __y)
10143 requires __detail::__all_random_access<_Const, _Vs...>
10144 {
return __x._M_it < __y._M_it; }
10146 friend constexpr bool
10147 operator>(
const _Iterator& __x,
const _Iterator& __y)
10148 requires __detail::__all_random_access<_Const, _Vs...>
10149 {
return __x._M_it > __y._M_it; }
10151 friend constexpr bool
10152 operator<=(
const _Iterator& __x,
const _Iterator& __y)
10153 requires __detail::__all_random_access<_Const, _Vs...>
10154 {
return __x._M_it <= __y._M_it; }
10156 friend constexpr bool
10157 operator>=(
const _Iterator& __x,
const _Iterator& __y)
10158 requires __detail::__all_random_access<_Const, _Vs...>
10159 {
return __x._M_it >= __y._M_it; }
10161 friend constexpr auto
10162 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
10163 requires __detail::__all_random_access<_Const, _Vs...>
10164 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10165 {
return __x._M_it <=> __y._M_it; }
10167 friend constexpr _Iterator
10168 operator+(
const _Iterator& __it, difference_type __n)
10169 requires __detail::__concat_is_random_access<_Const, _Vs...>
10170 {
return auto(__it) += __n; }
10172 friend constexpr _Iterator
10173 operator+(difference_type __n,
const _Iterator& __it)
10174 requires __detail::__concat_is_random_access<_Const, _Vs...>
10175 {
return __it + __n; }
10177 friend constexpr _Iterator
10178 operator-(
const _Iterator& __it, difference_type __n)
10179 requires __detail::__concat_is_random_access<_Const, _Vs...>
10180 {
return auto(__it) -= __n; }
10182 friend constexpr difference_type
10183 operator-(
const _Iterator& __x,
const _Iterator& __y)
10184 requires __detail::__concat_is_random_access<_Const, _Vs...>
10186 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10187 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> difference_type {
10188 if constexpr (_Ix > _Iy)
10190 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10191 ranges::end(std::get<_Iy>(__y._M_parent
10193 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10195 std::get<_Ix>(__x._M_it));
10196 difference_type __s = 0;
10197 [&]<
size_t _Idx = _Iy + 1>(
this auto&& __self) {
10198 if constexpr (_Idx < _Ix)
10200 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10201 __self.template operator()<_Idx + 1>();
10204 return __dy + __s + __dx;
10206 else if constexpr (_Ix < _Iy)
10207 return -(__y - __x);
10209 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10210 }, __y._M_it.index());
10211 }, __x._M_it.index());
10214 friend constexpr difference_type
10215 operator-(
const _Iterator& __x, default_sentinel_t)
10216 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10217 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10218 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10220 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10221 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10222 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10223 difference_type __s = 0;
10224 [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) {
10225 if constexpr (_Idx <
sizeof...(_Vs))
10227 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10228 __self.template operator()<_Idx + 1>();
10231 return -(__dx + __s);
10232 }, __x._M_it.index());
10235 friend constexpr difference_type
10236 operator-(default_sentinel_t,
const _Iterator& __x)
10237 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10238 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10239 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10242 friend constexpr decltype(
auto)
10243 iter_move(
const _Iterator& __it)
10245 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10246 return std::visit([](
const auto& __i) -> _Res {
10247 return ranges::iter_move(__i);
10251 friend constexpr void
10252 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10253 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10254 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10256 std::visit([&]<
typename _Tp,
typename _Up>(
const _Tp& __it1,
const _Up& __it2) {
10257 if constexpr (is_same_v<_Tp, _Up>)
10258 ranges::iter_swap(__it1, __it2);
10260 ranges::swap(*__it1, *__it2);
10261 }, __x._M_it, __y._M_it);
10264 template<
typename _Fn>
10265 static constexpr _Iterator
10266 _S_for_each_segment(_Iterator __first, _Iterator __last, _Fn __func)
10268 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> _Iterator {
10269 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> _Iterator {
10270 if constexpr (_Ix == _Iy)
10272 auto __ret = __func(std::get<_Ix>(__first._M_it), std::get<_Iy>(__last._M_it));
10273 return _Iterator(__first._M_parent, std::in_place_index<_Ix>, __ret);
10275 else if constexpr (_Ix < _Iy)
10277 auto __first_range = std::get<_Ix>(__first._M_parent->_M_views);
10278 auto __ret = __func(std::get<_Ix>(__first._M_it),
10279 ranges::end(__first_range));
10280 if (__ret != ranges::end(__first_range))
10281 return _Iterator(__first._M_parent, std::in_place_index<_Ix>, __ret);
10283 return [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) -> _Iterator {
10284 if constexpr (_Idx < _Iy)
10286 auto __mid_range = std::get<_Idx>(__first._M_parent->_M_views);
10287 auto __mid_ret = __func(ranges::begin(__mid_range),
10288 ranges::end(__mid_range));
10289 if (__mid_ret != ranges::end(__mid_range))
10290 return _Iterator(__first._M_parent, std::in_place_index<_Idx>, __mid_ret);
10291 return __self.template operator()<_Idx + 1>();
10295 auto __last_range = std::get<_Iy>(__last._M_parent->_M_views);
10296 auto __last_ret = __func(ranges::begin(__last_range),
10297 std::get<_Iy>(__last._M_it));
10298 return _Iterator(__first._M_parent, std::in_place_index<_Iy>, __last_ret);
10304 __builtin_unreachable();
10305 __glibcxx_assert(
false);
10307 }, __last._M_it.index());
10308 }, __first._M_it.index());
10311 static constexpr bool _S_enable_for_each_segment =
true;
10318 template<
typename... _Ts>
10324 template<
typename... _Ts>
10325 requires __detail::__can_concat_view<_Ts...>
10327 operator() [[nodiscard]] (_Ts&&... __ts)
const
10330 template<input_range _Range>
10332 operator() [[nodiscard]] (_Range&& __t)
const
10336 inline constexpr _Concat concat;
10342#if __cpp_lib_ranges_cache_latest
10345 template<input_range _Vp>
10347 class cache_latest_view :
public view_interface<cache_latest_view<_Vp>>
10349 _Vp _M_base = _Vp();
10351 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10352 add_pointer_t<range_reference_t<_Vp>>,
10353 range_reference_t<_Vp>>;
10354 __detail::__non_propagating_cache<__cache_t> _M_cache;
10360 cache_latest_view()
requires default_initializable<_Vp> = default;
10363 cache_latest_view(_Vp __base)
10364 : _M_base(std::move(__base))
10368 base() const & requires copy_constructible<_Vp>
10369 {
return _M_base; }
10377 {
return _Iterator(*
this); }
10381 {
return _Sentinel(*
this); }
10384 size()
requires sized_range<_Vp>
10385 {
return ranges::size(_M_base); }
10388 size() const requires sized_range<const _Vp>
10389 {
return ranges::size(_M_base); }
10392 template<
typename _Range>
10393 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10395 template<input_range _Vp>
10397 class cache_latest_view<_Vp>::_Iterator
10399 cache_latest_view* _M_parent;
10400 iterator_t<_Vp> _M_current;
10403 _Iterator(cache_latest_view& __parent)
10405 _M_current(ranges::begin(__parent._M_base))
10408 friend class cache_latest_view;
10411 using difference_type = range_difference_t<_Vp>;
10412 using value_type = range_value_t<_Vp>;
10413 using iterator_concept = input_iterator_tag;
10415 _Iterator(_Iterator&&) =
default;
10418 operator=(_Iterator&&) =
default;
10420 constexpr iterator_t<_Vp>
10424 constexpr const iterator_t<_Vp>&
10425 base() const & noexcept
10426 {
return _M_current; }
10428 constexpr range_reference_t<_Vp>&
10431 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10433 if (!_M_parent->_M_cache)
10434 _M_parent->_M_cache =
std::__addressof(__detail::__as_lvalue(*_M_current));
10435 return **_M_parent->_M_cache;
10439 if (!_M_parent->_M_cache)
10440 _M_parent->_M_cache._M_emplace_deref(_M_current);
10441 return *_M_parent->_M_cache;
10445 constexpr _Iterator&
10448 _M_parent->_M_cache._M_reset();
10457 friend constexpr range_rvalue_reference_t<_Vp>
10458 iter_move(
const _Iterator& __i)
10459 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10460 {
return ranges::iter_move(__i._M_current); }
10462 friend constexpr void
10463 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10464 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10465 requires indirectly_swappable<iterator_t<_Vp>>
10466 { ranges::iter_swap(__x._M_current, __y._M_current); }
10469 template<input_range _Vp>
10471 class cache_latest_view<_Vp>::_Sentinel
10473 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10476 _Sentinel(cache_latest_view& __parent)
10477 : _M_end(ranges::end(__parent._M_base))
10480 friend class cache_latest_view;
10483 _Sentinel() =
default;
10485 constexpr sentinel_t<_Vp>
10489 friend constexpr bool
10490 operator==(
const _Iterator& __x,
const _Sentinel& __y)
10491 {
return __x._M_current == __y._M_end; }
10493 friend constexpr range_difference_t<_Vp>
10494 operator-(
const _Iterator& __x,
const _Sentinel& __y)
10495 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10496 {
return __x._M_current - __y._M_end; }
10498 friend constexpr range_difference_t<_Vp>
10499 operator-(
const _Sentinel& __x,
const _Iterator& __y)
10500 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10501 {
return __x._M_end - __y._M_current; }
10508 template<
typename _Tp>
10509 concept __can_cache_latest =
requires { cache_latest_view(
std::declval<_Tp>()); };
10512 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10514 template<viewable_range _Range>
10515 requires __detail::__can_cache_latest<_Range>
10517 operator() [[nodiscard]] (_Range&& __r)
const
10520 static constexpr bool _S_has_simple_call_op =
true;
10523 inline constexpr _CacheLatest cache_latest;
10528#if __cpp_lib_ranges_as_input
10531 template<input_range _Vp>
10533 class as_input_view :
public view_interface<as_input_view<_Vp>>
10535 _Vp _M_base = _Vp();
10537 template<
bool _Const>
10541 as_input_view()
requires default_initializable<_Vp> = default;
10544 as_input_view(_Vp __base)
10545 : _M_base(std::move(__base))
10549 base() const & requires copy_constructible<_Vp>
10550 {
return _M_base; }
10557 begin()
requires (!__detail::__simple_view<_Vp>)
10558 {
return _Iterator<false>(ranges::begin(_M_base)); }
10561 begin() const requires range<const _Vp>
10562 {
return _Iterator<true>(ranges::begin(_M_base)); }
10565 end()
requires (!__detail::__simple_view<_Vp>)
10566 {
return ranges::end(_M_base); }
10569 end() const requires range<const _Vp>
10570 {
return ranges::end(_M_base); }
10573 size()
requires sized_range<_Vp>
10574 {
return ranges::size(_M_base); }
10577 size() const requires sized_range<const _Vp>
10578 {
return ranges::size(_M_base); }
10581 template<
typename _Range>
10582 as_input_view(_Range&&) -> as_input_view<views::all_t<_Range>>;
10584 template<
typename _Vp>
10585 inline constexpr bool enable_borrowed_range<as_input_view<_Vp>>
10586 = enable_borrowed_range<_Vp>;
10588 template<input_range _Vp>
10590 template<
bool _Const>
10591 class as_input_view<_Vp>::_Iterator
10593 using _Base = __maybe_const_t<_Const, _Vp>;
10595 iterator_t<_Base> _M_current = iterator_t<_Base>();
10598 _Iterator(iterator_t<_Base> __current)
10599 : _M_current(std::move(__current))
10602 friend as_input_view;
10603 friend _Iterator<!_Const>;
10606 using difference_type = range_difference_t<_Base>;
10607 using value_type = range_value_t<_Base>;
10608 using iterator_concept = input_iterator_tag;
10610 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
10612 _Iterator(_Iterator&&) = default;
10613 _Iterator& operator=(_Iterator&&) = default;
10616 _Iterator(_Iterator<!_Const> __i)
10617 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10618 : _M_current(std::move(__i._M_current))
10621 constexpr iterator_t<_Base>
10625 constexpr const iterator_t<_Base>&
10626 base() const & noexcept
10627 {
return _M_current; }
10629 constexpr decltype(
auto)
10631 {
return *_M_current; }
10633 constexpr _Iterator&
10644 friend constexpr bool
10645 operator==(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10646 {
return __x._M_current == __y; }
10648 friend constexpr difference_type
10649 operator-(
const sentinel_t<_Base>& __y,
const _Iterator& __x)
10650 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10651 {
return __y - __x._M_current; }
10653 friend constexpr difference_type
10654 operator-(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10655 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10656 {
return __x._M_current - __y; }
10658 friend constexpr range_rvalue_reference_t<_Base>
10659 iter_move(
const _Iterator& __i)
10660 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10661 {
return ranges::iter_move(__i._M_current); }
10663 friend constexpr void
10664 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10665 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10666 requires indirectly_swappable<iterator_t<_Base>>
10667 { ranges::iter_swap(__x._M_current, __y._M_current); }
10674 template<
typename _Tp>
10678 struct _AsInput : __adaptor::_RangeAdaptorClosure<_AsInput>
10680 template<viewable_range _Range>
10681 requires __detail::__can_as_input<_Range>
10683 operator() [[nodiscard]] (_Range&& __r)
const
10685 if constexpr (input_range<_Range>
10686 && !common_range<_Range>
10687 && !forward_range<_Range>)
10693 static constexpr bool _S_has_simple_call_op =
true;
10696 inline constexpr _AsInput as_input;
10701_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 common_reference< _Tp... >::type common_reference_t
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.
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 end(_Container &__cont) noexcept(noexcept(__cont.end())) -> decltype(__cont.end())
Return an iterator pointing to one past the last element of the container.
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 auto begin(_Container &__cont) noexcept(noexcept(__cont.begin())) -> decltype(__cont.begin())
Return an iterator pointing to the first element of the 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.same], concept same_as
[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.