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>
506 constexpr auto __to_signed_like(_Wp __w)
noexcept
508 if constexpr (!integral<_Wp>)
509 return iter_difference_t<_Wp>();
510 else if constexpr (
sizeof(iter_difference_t<_Wp>) >
sizeof(_Wp))
511 return iter_difference_t<_Wp>(__w);
512 else if constexpr (
sizeof(ptrdiff_t) >
sizeof(_Wp))
513 return ptrdiff_t(__w);
514 else if constexpr (
sizeof(
long long) >
sizeof(_Wp))
515 return (
long long)(__w);
516#ifdef __SIZEOF_INT128__
517 else if constexpr (__SIZEOF_INT128__ >
sizeof(_Wp))
518 return __int128(__w);
521 return __max_diff_type(__w);
524 template<
typename _Wp>
527 template<
typename _It>
528 concept __decrementable = incrementable<_It>
531 { --__i } -> same_as<_It&>;
532 { __i-- } -> same_as<_It>;
535 template<
typename _It>
536 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
537 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
539 { __i += __n } -> same_as<_It&>;
540 { __i -= __n } -> same_as<_It&>;
544 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
547 template<
typename _Winc>
548 struct __iota_view_iter_cat
551 template<incrementable _Winc>
552 struct __iota_view_iter_cat<_Winc>
553 {
using iterator_category = input_iterator_tag; };
556 template<weakly_incrementable _Winc,
557 semiregular _Bound = unreachable_sentinel_t>
558 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
565 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
571 using namespace __detail;
572 if constexpr (__advanceable<_Winc>)
573 return random_access_iterator_tag{};
574 else if constexpr (__decrementable<_Winc>)
575 return bidirectional_iterator_tag{};
576 else if constexpr (incrementable<_Winc>)
577 return forward_iterator_tag{};
579 return input_iterator_tag{};
583 using iterator_concept =
decltype(_S_iter_concept());
585 using value_type = _Winc;
586 using difference_type = __detail::__iota_diff_t<_Winc>;
588 _Iterator()
requires default_initializable<_Winc> = default;
591 _Iterator(_Winc __value)
592 : _M_value(__value) { }
595 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
610 operator++(
int)
requires incrementable<_Winc>
618 operator--()
requires __detail::__decrementable<_Winc>
625 operator--(
int)
requires __detail::__decrementable<_Winc>
633 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
635 using __detail::__is_integer_like;
636 using __detail::__is_signed_integer_like;
637 if constexpr (__is_integer_like<_Winc>
638 && !__is_signed_integer_like<_Winc>)
640 if (__n >= difference_type(0))
641 _M_value +=
static_cast<_Winc
>(__n);
643 _M_value -=
static_cast<_Winc
>(-__n);
651 operator-=(difference_type __n)
requires __detail::__advanceable<_Winc>
653 using __detail::__is_integer_like;
654 using __detail::__is_signed_integer_like;
655 if constexpr (__is_integer_like<_Winc>
656 && !__is_signed_integer_like<_Winc>)
658 if (__n >= difference_type(0))
659 _M_value -=
static_cast<_Winc
>(__n);
661 _M_value +=
static_cast<_Winc
>(-__n);
669 operator[](difference_type __n)
const
670 requires __detail::__advanceable<_Winc>
671 {
return _Winc(_M_value + __n); }
673 friend constexpr bool
674 operator==(
const _Iterator& __x,
const _Iterator& __y)
675 requires equality_comparable<_Winc>
676 {
return __x._M_value == __y._M_value; }
678 friend constexpr bool
679 operator<(
const _Iterator& __x,
const _Iterator& __y)
680 requires totally_ordered<_Winc>
681 {
return __x._M_value < __y._M_value; }
683 friend constexpr bool
684 operator>(
const _Iterator& __x,
const _Iterator& __y)
685 requires totally_ordered<_Winc>
686 {
return __y < __x; }
688 friend constexpr bool
689 operator<=(
const _Iterator& __x,
const _Iterator& __y)
690 requires totally_ordered<_Winc>
691 {
return !(__y < __x); }
693 friend constexpr bool
694 operator>=(
const _Iterator& __x,
const _Iterator& __y)
695 requires totally_ordered<_Winc>
696 {
return !(__x < __y); }
698#ifdef __cpp_lib_three_way_comparison
699 friend constexpr auto
700 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
701 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
702 {
return __x._M_value <=> __y._M_value; }
705 friend constexpr _Iterator
706 operator+(_Iterator __i, difference_type __n)
707 requires __detail::__advanceable<_Winc>
713 friend constexpr _Iterator
714 operator+(difference_type __n, _Iterator __i)
715 requires __detail::__advanceable<_Winc>
716 {
return __i += __n; }
718 friend constexpr _Iterator
719 operator-(_Iterator __i, difference_type __n)
720 requires __detail::__advanceable<_Winc>
726 friend constexpr difference_type
727 operator-(
const _Iterator& __x,
const _Iterator& __y)
728 requires __detail::__advanceable<_Winc>
730 using __detail::__is_integer_like;
731 using __detail::__is_signed_integer_like;
732 using _Dt = difference_type;
733 if constexpr (__is_integer_like<_Winc>)
735 if constexpr (__is_signed_integer_like<_Winc>)
736 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
738 return (__y._M_value > __x._M_value)
739 ? _Dt(-_Dt(__y._M_value - __x._M_value))
740 : _Dt(__x._M_value - __y._M_value);
743 return __x._M_value - __y._M_value;
747 _Winc _M_value = _Winc();
756 _Bound _M_bound = _Bound();
759 _Sentinel() =
default;
762 _Sentinel(_Bound __bound)
763 : _M_bound(__bound) { }
765 friend constexpr bool
766 operator==(
const _Iterator& __x,
const _Sentinel& __y)
767 {
return __x._M_value == __y._M_bound; }
769 friend constexpr iter_difference_t<_Winc>
770 operator-(
const _Iterator& __x,
const _Sentinel& __y)
771 requires sized_sentinel_for<_Bound, _Winc>
772 {
return -(__y._M_bound - __x._M_value); }
774 friend constexpr iter_difference_t<_Winc>
775 operator-(
const _Sentinel& __x,
const _Iterator& __y)
776 requires sized_sentinel_for<_Bound, _Winc>
777 {
return __x._M_bound - __y._M_value; }
782 _Winc _M_value = _Winc();
783 [[no_unique_address]] _Bound _M_bound = _Bound();
786 iota_view()
requires default_initializable<_Winc> = default;
789 iota_view(_Winc __value)
794 iota_view(type_identity_t<_Winc> __value,
795 type_identity_t<_Bound> __bound)
796 : _M_value(__value), _M_bound(__bound)
798 if constexpr (totally_ordered_with<_Winc, _Bound>)
799 __glibcxx_assert(
bool(__value <= __bound) );
803 iota_view(_Iterator __first, _Iterator __last)
804 requires same_as<_Winc, _Bound>
805 : iota_view(__first._M_value, __last._M_value)
809 iota_view(_Iterator __first, unreachable_sentinel_t __last)
810 requires same_as<_Bound, unreachable_sentinel_t>
811 : iota_view(__first._M_value, __last)
815 iota_view(_Iterator __first, _Sentinel __last)
816 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
817 : iota_view(__first._M_value, __last._M_bound)
821 begin()
const {
return _Iterator{_M_value}; }
826 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
827 return unreachable_sentinel;
829 return _Sentinel{_M_bound};
833 end() const requires same_as<_Winc, _Bound>
834 {
return _Iterator{_M_bound}; }
840 {
return _M_value == _M_bound; }
844 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
845 || (integral<_Winc> && integral<_Bound>)
846 || sized_sentinel_for<_Bound, _Winc>
848 using __detail::__is_integer_like;
849 using __detail::__to_unsigned_like;
850 if constexpr (integral<_Winc> && integral<_Bound>)
853 return _Up(_M_bound) - _Up(_M_value);
855 else if constexpr (__is_integer_like<_Winc>)
856 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
858 return __to_unsigned_like(_M_bound - _M_value);
862 template<
typename _Winc,
typename _Bound>
863 requires (!__detail::__is_integer_like<_Winc>
864 || !__detail::__is_integer_like<_Bound>
865 || (__detail::__is_signed_integer_like<_Winc>
866 == __detail::__is_signed_integer_like<_Bound>))
867 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
869 template<
typename _Winc,
typename _Bound>
870 inline constexpr bool
871 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
875 template<
typename _Tp>
876 inline constexpr empty_view<_Tp> empty{};
880 template<
typename _Tp>
881 concept __can_single_view
887 template<__detail::__can_single_view _Tp>
889 operator() [[nodiscard]] (_Tp&& __e)
const
894 inline constexpr _Single single{};
898 template<
typename... _Args>
906 template<__detail::__can_iota_view _Tp>
907 constexpr iota_view<decay_t<_Tp>>
908 operator() [[nodiscard]] (_Tp&& __e)
const
911 template<
typename _Tp,
typename _Up>
912 requires __detail::__can_iota_view<_Tp, _Up>
914 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
918 inline constexpr _Iota iota{};
920#ifdef __cpp_lib_ranges_indices
923 template<ranges::__detail::__is_
integer_like _Tp>
924 requires __detail::__can_iota_view<_Tp>
925 [[nodiscard]]
constexpr auto
926 operator() (_Tp __e)
const noexcept
927 {
return iota(_Tp{}, __e); }
930 inline constexpr _Indices indices{};
937 template<
typename _Val,
typename _CharT,
typename _Traits>
938 concept __stream_extractable
939 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
942 template<movable _Val,
typename _CharT,
943 typename _Traits = char_traits<_CharT>>
944 requires default_initializable<_Val>
945 && __detail::__stream_extractable<_Val, _CharT, _Traits>
946 class basic_istream_view
947 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
951 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
958 *_M_stream >> _M_object;
959 return _Iterator{
this};
962 constexpr default_sentinel_t
967 basic_istream<_CharT, _Traits>* _M_stream;
968 _Val _M_object = _Val();
973 using iterator_concept = input_iterator_tag;
974 using difference_type = ptrdiff_t;
975 using value_type = _Val;
978 _Iterator(basic_istream_view* __parent) noexcept
979 : _M_parent(__parent)
982 _Iterator(
const _Iterator&) =
delete;
983 _Iterator(_Iterator&&) =
default;
984 _Iterator& operator=(
const _Iterator&) =
delete;
985 _Iterator& operator=(_Iterator&&) =
default;
990 *_M_parent->_M_stream >> _M_parent->_M_object;
1000 {
return _M_parent->_M_object; }
1003 operator==(
const _Iterator& __x, default_sentinel_t)
1004 {
return !*__x._M_parent->_M_stream; }
1007 basic_istream_view* _M_parent;
1013 template<
typename _Val>
1014 using istream_view = basic_istream_view<_Val, char>;
1016 template<
typename _Val>
1017 using wistream_view = basic_istream_view<_Val, wchar_t>;
1023 template<
typename _Tp,
typename _Up>
1024 concept __can_istream_view =
requires (_Up __e) {
1025 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
1029 template<
typename _Tp>
1032 template<
typename _CharT,
typename _Traits>
1034 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
1036 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
1039 template<
typename _Tp>
1040 inline constexpr _Istream<_Tp> istream;
1048 template<
typename _Tp,
int _Disc>
1057 template<
bool _Present,
typename _Tp,
int _Disc = 0>
1058 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
1061 template<
bool _Const,
typename _Tp>
1062 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
1067using __detail::__maybe_const_t;
1069namespace views::__adaptor
1072 template<
typename _Adaptor,
typename... _Args>
1073 concept __adaptor_invocable
1078 template<
typename _Adaptor,
typename... _Args>
1079 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
1080 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
1081 && (constructible_from<decay_t<_Args>, _Args> && ...);
1083 template<
typename _Adaptor,
typename... _Args>
1086 template<
typename _Lhs,
typename _Rhs>
1094 template<
typename _Derived>
1095 struct _RangeAdaptorClosure;
1097 template<
typename _Tp,
typename _Up>
1098 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
1099 void __is_range_adaptor_closure_fn
1100 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
1102 template<
typename _Tp>
1103 concept __is_range_adaptor_closure
1104 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
1106#pragma GCC diagnostic push
1107#pragma GCC diagnostic ignored "-Wdangling-reference"
1109 template<
typename _Self,
typename _Range>
1110 requires __is_range_adaptor_closure<_Self>
1111 && __adaptor_invocable<_Self, _Range>
1113 operator|(_Range&& __r, _Self&& __self)
1118 template<
typename _Lhs,
typename _Rhs>
1119 requires __is_range_adaptor_closure<_Lhs>
1120 && __is_range_adaptor_closure<_Rhs>
1122 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
1127#pragma GCC diagnostic pop
1129 template<
typename _Derived>
1130 struct _RangeAdaptorClosure
1136 template<
typename _Self,
typename _Range>
1137 requires __is_range_adaptor_closure<_Self>
1138 && __adaptor_invocable<_Self, _Range>
1139 friend constexpr auto
1140 operator|(_Range&& __r, _Self&& __self);
1142 template<
typename _Lhs,
typename _Rhs>
1143 requires __is_range_adaptor_closure<_Lhs>
1144 && __is_range_adaptor_closure<_Rhs>
1145 friend constexpr auto
1146 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1160 template<
typename _Derived>
1161 struct _RangeAdaptor
1165 template<
typename... _Args>
1166 requires __adaptor_partial_app_viable<_Derived, _Args...>
1168 operator()(_Args&&... __args)
const
1177 template<
typename _Adaptor>
1178 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1182 template<
typename _Adaptor,
typename... _Args>
1183 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1184 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1188 template<
typename _Adaptor,
typename... _Args>
1189 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1191 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1192 [[no_unique_address]] _Binder _M_binder;
1196 template<
typename... _Ts>
1198 _Partial(
int, _Ts&&... __args)
1199 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1204#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1205# pragma GCC diagnostic push
1206# pragma GCC diagnostic ignored "-Wc++23-extensions"
1207 template<
typename _Self,
typename _Range>
1208 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1210 operator()(
this _Self&& __self, _Range&& __r)
1212 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1215# pragma GCC diagnostic pop
1217 template<
typename _Range>
1218 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1220 operator()(_Range&& __r)
const &
1223 template<
typename _Range>
1224 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1226 operator()(_Range&& __r) &&
1229 template<
typename _Range>
1231 operator()(_Range&& __r)
const && =
delete;
1239 template<
typename _Adaptor,
typename... _Args>
1240 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1241 && (is_trivially_copy_constructible_v<_Args> && ...)
1242 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1244 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1245 [[no_unique_address]] _Binder _M_binder;
1247 template<
typename... _Ts>
1249 _Partial(
int, _Ts&&... __args)
1250 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1255 template<
typename _Range>
1256 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1258 operator()(_Range&& __r)
const
1261 static constexpr bool _S_has_simple_call_op =
true;
1264 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1265 concept __pipe_invocable
1270 template<
typename _Lhs,
typename _Rhs>
1271 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1273 [[no_unique_address]] _Lhs _M_lhs;
1274 [[no_unique_address]] _Rhs _M_rhs;
1276 template<
typename _Tp,
typename _Up>
1278 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1279 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1284#if _GLIBCXX_EXPLICIT_THIS_PARAMETER
1285# pragma GCC diagnostic push
1286# pragma GCC diagnostic ignored "-Wc++23-extensions"
1287 template<
typename _Self,
typename _Range>
1288 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1290 operator()(
this _Self&& __self, _Range&& __r)
1292 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1293 (__like_t<_Self, _Pipe>(__self)._M_lhs
1296# pragma GCC diagnostic pop
1298 template<
typename _Range>
1299 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1301 operator()(_Range&& __r)
const &
1304 template<
typename _Range>
1305 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1307 operator()(_Range&& __r) &&
1310 template<
typename _Range>
1312 operator()(_Range&& __r)
const && =
delete;
1320 template<
typename _Lhs,
typename _Rhs>
1321 requires __closure_has_simple_call_op<_Lhs>
1322 && __closure_has_simple_call_op<_Rhs>
1323 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1325 [[no_unique_address]] _Lhs _M_lhs;
1326 [[no_unique_address]] _Rhs _M_rhs;
1328 template<
typename _Tp,
typename _Up>
1330 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1331 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1334 template<
typename _Range>
1335 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1337 operator()(_Range&& __r)
const
1340 static constexpr bool _S_has_simple_call_op =
true;
1344#if __cpp_lib_ranges >= 202202L
1346 template<
typename _Derived>
1347 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1348 class range_adaptor_closure
1349 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1353 template<range _Range>
requires is_object_v<_Range>
1359 static void _S_fun(_Range&);
1360 static void _S_fun(_Range&&) =
delete;
1363 template<__detail::__different_from<ref_view> _Tp>
1364 requires convertible_to<_Tp, _Range&>
1376 constexpr iterator_t<_Range>
1378 {
return ranges::begin(*_M_r); }
1380 constexpr sentinel_t<_Range>
1382 {
return ranges::end(*_M_r); }
1385 empty() const requires requires { ranges::empty(*_M_r); }
1386 {
return ranges::empty(*_M_r); }
1389 size() const requires sized_range<_Range>
1390 {
return ranges::size(*_M_r); }
1393 data() const requires contiguous_range<_Range>
1394 {
return ranges::data(*_M_r); }
1397 template<
typename _Range>
1398 ref_view(_Range&) -> ref_view<_Range>;
1400 template<
typename _Tp>
1401 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1403 template<range _Range>
1404 requires movable<_Range>
1405 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1409 _Range _M_r = _Range();
1412 owning_view()
requires default_initializable<_Range> = default;
1415 owning_view(_Range&& __t)
1416 noexcept(is_nothrow_move_constructible_v<_Range>)
1417 : _M_r(std::move(__t))
1420 owning_view(owning_view&&) =
default;
1421 owning_view& operator=(owning_view&&) =
default;
1427 constexpr const _Range&
1428 base() const& noexcept
1435 constexpr const _Range&&
1436 base() const&& noexcept
1439 constexpr iterator_t<_Range>
1441 {
return ranges::begin(_M_r); }
1443 constexpr sentinel_t<_Range>
1445 {
return ranges::end(_M_r); }
1449 {
return ranges::begin(_M_r); }
1452 end() const requires
range<const _Range>
1453 {
return ranges::end(_M_r); }
1456 empty()
requires requires { ranges::empty(_M_r); }
1457 {
return ranges::empty(_M_r); }
1460 empty() const requires requires { ranges::empty(_M_r); }
1461 {
return ranges::empty(_M_r); }
1465 {
return ranges::size(_M_r); }
1469 {
return ranges::size(_M_r); }
1473 {
return ranges::data(_M_r); }
1477 {
return ranges::data(_M_r); }
1480 template<
typename _Tp>
1481 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1482 = enable_borrowed_range<_Tp>;
1488 template<
typename _Range>
1491 template<
typename _Range>
1495 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1497 template<
typename _Range>
1498 static constexpr bool
1501 if constexpr (view<decay_t<_Range>>)
1503 else if constexpr (__detail::__can_ref_view<_Range>)
1509 template<viewable_range _Range>
1510 requires view<decay_t<_Range>>
1511 || __detail::__can_ref_view<_Range>
1512 || __detail::__can_owning_view<_Range>
1514 operator() [[nodiscard]] (_Range&& __r)
const
1515 noexcept(_S_noexcept<_Range>())
1517 if constexpr (view<decay_t<_Range>>)
1519 else if constexpr (__detail::__can_ref_view<_Range>)
1525 static constexpr bool _S_has_simple_call_op =
true;
1528 inline constexpr _All all;
1530 template<viewable_range _Range>
1536 template<
typename _Tp>
1537 struct __non_propagating_cache
1545 template<
typename _Tp>
1546 requires is_object_v<_Tp>
1547 struct __non_propagating_cache<_Tp>
1548 :
protected _Optional_base<_Tp>
1550 __non_propagating_cache() =
default;
1553 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1557 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1558 { __other._M_reset(); }
1560 constexpr __non_propagating_cache&
1561 operator=(
const __non_propagating_cache& __other)
noexcept
1568 constexpr __non_propagating_cache&
1569 operator=(__non_propagating_cache&& __other)
noexcept
1576 constexpr __non_propagating_cache&
1577 operator=(_Tp __val)
1580 this->_M_payload._M_construct(
std::move(__val));
1585 operator bool() const noexcept
1586 {
return this->_M_is_engaged(); }
1590 {
return this->_M_get(); }
1592 constexpr const _Tp&
1594 {
return this->_M_get(); }
1596 template<
typename _Iter>
1598 _M_emplace_deref(
const _Iter& __i)
1601 auto __f = [] (
auto& __x) {
return *__x; };
1602 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1603 return this->_M_get();
1606 using _Optional_base<_Tp>::_M_reset;
1609 template<range _Range>
1610 struct _CachedPosition
1613 _M_has_value()
const
1616 constexpr iterator_t<_Range>
1617 _M_get(
const _Range&)
const
1619 __glibcxx_assert(
false);
1620 __builtin_unreachable();
1624 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1628 template<forward_range _Range>
1629 struct _CachedPosition<_Range>
1630 :
protected __non_propagating_cache<iterator_t<_Range>>
1633 _M_has_value()
const
1634 {
return this->_M_is_engaged(); }
1636 constexpr iterator_t<_Range>
1637 _M_get(
const _Range&)
const
1639 __glibcxx_assert(_M_has_value());
1644 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1646 __glibcxx_assert(!_M_has_value());
1649 this->_M_payload._M_engaged =
true;
1653 template<random_access_range _Range>
1654 struct _CachedPosition<_Range>
1657 range_difference_t<_Range> _M_offset = -1;
1660 _CachedPosition() =
default;
1663 _CachedPosition(
const _CachedPosition&) =
default;
1666 _CachedPosition(_CachedPosition&& __other)
noexcept
1669 constexpr _CachedPosition&
1670 operator=(
const _CachedPosition&) =
default;
1672 constexpr _CachedPosition&
1673 operator=(_CachedPosition&& __other)
noexcept
1676 _M_offset = __other._M_offset;
1677 __other._M_offset = -1;
1682 _M_has_value()
const
1683 {
return _M_offset >= 0; }
1685 constexpr iterator_t<_Range>
1686 _M_get(_Range& __r)
const
1688 __glibcxx_assert(_M_has_value());
1689 return ranges::begin(__r) + _M_offset;
1693 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1695 __glibcxx_assert(!_M_has_value());
1696 _M_offset = __it - ranges::begin(__r);
1703 template<
typename _Base>
1704 struct __filter_view_iter_cat
1707 template<forward_range _Base>
1708 struct __filter_view_iter_cat<_Base>
1714 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1715 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1716 return bidirectional_iterator_tag{};
1717 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1718 return forward_iterator_tag{};
1723 using iterator_category =
decltype(_S_iter_cat());
1728 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1729 requires view<_Vp> && is_object_v<_Pred>
1730 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1733 template<
bool _Const>
1736 template<
bool _Const>
1737 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1740 static constexpr auto
1743 if constexpr (_Const)
1744 return input_iterator_tag{};
1745 else if constexpr (bidirectional_range<_Vp>)
1746 return bidirectional_iterator_tag{};
1747 else if constexpr (forward_range<_Vp>)
1748 return forward_iterator_tag{};
1750 return input_iterator_tag{};
1754 friend _Iterator<!_Const>;
1756 using _Parent = __maybe_const_t<_Const, filter_view>;
1757 using _Base = __maybe_const_t<_Const, _Vp>;
1758 using _Base_iter = iterator_t<_Base>;
1760 _Base_iter _M_current = _Base_iter();
1761 _Parent* _M_parent =
nullptr;
1764 using iterator_concept =
decltype(_S_iter_concept());
1766 using value_type = range_value_t<_Base>;
1767 using difference_type = range_difference_t<_Base>;
1769 _Iterator()
requires default_initializable<_Base_iter> = default;
1772 _Iterator(_Parent* __parent, _Base_iter __current)
1773 : _M_current(std::move(__current)),
1778 _Iterator(_Iterator<!_Const> __i)
1779 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
1780 : _M_current(
std::move(__i._M_current)),
1784 constexpr const _Base_iter&
1785 base() const & noexcept
1786 {
return _M_current; }
1788 constexpr _Base_iter
1792 constexpr range_reference_t<_Base>
1794 {
return *_M_current; }
1796 constexpr _Base_iter
1798 requires __detail::__has_arrow<_Base_iter>
1799 && copyable<_Base_iter>
1800 {
return _M_current; }
1802 constexpr _Iterator&
1805 _M_current = ranges::find_if(
std::move(++_M_current),
1806 ranges::end(_M_parent->_M_base),
1816 operator++(
int)
requires forward_range<_Base>
1823 constexpr _Iterator&
1824 operator--()
requires bidirectional_range<_Base>
1833 operator--(
int)
requires bidirectional_range<_Base>
1840 friend constexpr bool
1841 operator==(
const _Iterator& __x,
const _Iterator& __y)
1842 requires equality_comparable<_Base_iter>
1843 {
return __x._M_current == __y._M_current; }
1845 friend constexpr range_rvalue_reference_t<_Base>
1846 iter_move(
const _Iterator& __i)
1847 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1848 {
return ranges::iter_move(__i._M_current); }
1850 friend constexpr void
1851 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1852 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1853 requires indirectly_swappable<_Base_iter>
1854 { ranges::iter_swap(__x._M_current, __y._M_current); }
1857 template<
bool _Const>
1861 using _Parent = __maybe_const_t<_Const, filter_view>;
1862 using _Base = __maybe_const_t<_Const, _Vp>;
1863 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1865 friend _Sentinel<!_Const>;
1868 _Sentinel() =
default;
1871 _Sentinel(_Parent* __parent)
1872 : _M_end(ranges::end(__parent->_M_base))
1876 _Sentinel(_Sentinel<!_Const> __i)
1877 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1881 constexpr sentinel_t<_Base>
1885 template<
bool _Const2>
1886 requires sentinel_for<sentinel_t<_Base>,
1887 iterator_t<__maybe_const_t<_Const2, _Vp>>>
1888 friend constexpr bool
1889 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
1890 {
return __x._M_current == __y._M_end; }
1893 _Vp _M_base = _Vp();
1894 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1895 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1898 filter_view()
requires (default_initializable<_Vp>
1899 && default_initializable<_Pred>)
1903 filter_view(_Vp __base, _Pred __pred)
1904 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
1908 base() const& requires copy_constructible<_Vp>
1915 constexpr const _Pred&
1917 {
return *_M_pred; }
1919 constexpr _Iterator<false>
1922 if (_M_cached_begin._M_has_value())
1923 return {
this, _M_cached_begin._M_get(_M_base)};
1925 __glibcxx_assert(_M_pred.has_value());
1926 auto __it = ranges::find_if(ranges::begin(_M_base),
1927 ranges::end(_M_base),
1929 _M_cached_begin._M_set(_M_base, __it);
1933 constexpr _Iterator<true>
1935 requires (input_range<const _Vp> && !forward_range<const _Vp>
1936 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1938 __glibcxx_assert(_M_pred.has_value());
1939 auto __it = ranges::find_if(ranges::begin(_M_base),
1940 ranges::end(_M_base),
1948 if constexpr (common_range<_Vp>)
1949 return _Iterator<false>{
this, ranges::end(_M_base)};
1951 return _Sentinel<false>{
this};
1954 constexpr _Sentinel<true>
1956 requires (input_range<const _Vp> && !forward_range<const _Vp>
1957 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>)
1958 {
return _Sentinel<true>{
this}; }
1961 template<
typename _Range,
typename _Pred>
1962 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1968 template<
typename _Range,
typename _Pred>
1969 concept __can_filter_view
1973 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1975 template<viewable_range _Range,
typename _Pred>
1976 requires __detail::__can_filter_view<_Range, _Pred>
1978 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1983 using _RangeAdaptor<_Filter>::operator();
1984 static constexpr int _S_arity = 2;
1985 static constexpr bool _S_has_simple_extra_args =
true;
1988 inline constexpr _Filter filter;
1991#if __cpp_lib_ranges >= 202207L
1992 template<input_range _Vp, move_constructible _Fp>
1994 template<input_range _Vp, copy_constructible _Fp>
1997 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1998 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1999 range_reference_t<_Vp>>>
2000 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
2003 template<
bool _Const>
2004 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2006 template<
bool _Const>
2010 template<
bool _Const>
2011 requires forward_range<_Base<_Const>>
2012 struct __iter_cat<_Const>
2021 using _Base = transform_view::_Base<_Const>;
2022 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2023 range_reference_t<_Base>>;
2026 if constexpr (is_reference_v<_Res>)
2029 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
2030 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
2031 return random_access_iterator_tag{};
2036 return input_iterator_tag{};
2039 using iterator_category =
decltype(_S_iter_cat());
2042 template<
bool _Const>
2045 template<
bool _Const>
2046 struct _Iterator : __iter_cat<_Const>
2049 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2050 using _Base = transform_view::_Base<_Const>;
2051 using _Base_iter = iterator_t<_Base>;
2052 using _Func_handle = __detail::__func_handle_t<
2053 __detail::__maybe_const_t<_Const, _Fp>,
2059 if constexpr (random_access_range<_Base>)
2060 return random_access_iterator_tag{};
2061 else if constexpr (bidirectional_range<_Base>)
2062 return bidirectional_iterator_tag{};
2063 else if constexpr (forward_range<_Base>)
2064 return forward_iterator_tag{};
2066 return input_iterator_tag{};
2069 _Base_iter _M_current = _Base_iter();
2070 [[no_unique_address]] _Func_handle _M_fun;
2073 using iterator_concept =
decltype(_S_iter_concept());
2076 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2077 range_reference_t<_Base>>>;
2078 using difference_type = range_difference_t<_Base>;
2080 _Iterator()
requires default_initializable<_Base_iter> = default;
2083 _Iterator(_Func_handle __fun, _Base_iter __current)
2084 : _M_current(std::move(__current)), _M_fun(__fun)
2088 _Iterator(_Parent* __parent, _Base_iter __current)
2089 : _M_current(std::move(__current)), _M_fun(*__parent->_M_fun)
2093 _Iterator(_Iterator<!_Const> __i)
2095 && convertible_to<iterator_t<_Vp>, _Base_iter>
2096 : _M_current(
std::move(__i._M_current)), _M_fun(__i._M_fun)
2099 constexpr const _Base_iter&
2100 base() const & noexcept
2101 {
return _M_current; }
2103 constexpr _Base_iter
2107 constexpr decltype(
auto)
2109 noexcept(
noexcept(_M_fun._M_call_deref(_M_current)))
2110 {
return _M_fun._M_call_deref(_M_current); }
2112 constexpr _Iterator&
2124 operator++(
int)
requires forward_range<_Base>
2131 constexpr _Iterator&
2132 operator--()
requires bidirectional_range<_Base>
2139 operator--(
int)
requires bidirectional_range<_Base>
2146 constexpr _Iterator&
2147 operator+=(difference_type __n)
requires random_access_range<_Base>
2153 constexpr _Iterator&
2154 operator-=(difference_type __n)
requires random_access_range<_Base>
2160 constexpr decltype(
auto)
2161 operator[](difference_type __n)
const
2162 requires random_access_range<_Base>
2163 {
return _M_fun._M_call_subscript(__n, _M_current); }
2165 friend constexpr bool
2166 operator==(
const _Iterator& __x,
const _Iterator& __y)
2167 requires equality_comparable<_Base_iter>
2168 {
return __x._M_current == __y._M_current; }
2170 friend constexpr bool
2171 operator<(
const _Iterator& __x,
const _Iterator& __y)
2172 requires random_access_range<_Base>
2173 {
return __x._M_current < __y._M_current; }
2175 friend constexpr bool
2176 operator>(
const _Iterator& __x,
const _Iterator& __y)
2177 requires random_access_range<_Base>
2178 {
return __y < __x; }
2180 friend constexpr bool
2181 operator<=(
const _Iterator& __x,
const _Iterator& __y)
2182 requires random_access_range<_Base>
2183 {
return !(__y < __x); }
2185 friend constexpr bool
2186 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2187 requires random_access_range<_Base>
2188 {
return !(__x < __y); }
2190#ifdef __cpp_lib_three_way_comparison
2191 friend constexpr auto
2192 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2193 requires random_access_range<_Base>
2194 && three_way_comparable<_Base_iter>
2195 {
return __x._M_current <=> __y._M_current; }
2198 friend constexpr _Iterator
2199 operator+(_Iterator __i, difference_type __n)
2200 requires random_access_range<_Base>
2201 {
return {__i._M_fun, __i._M_current + __n}; }
2203 friend constexpr _Iterator
2204 operator+(difference_type __n, _Iterator __i)
2205 requires random_access_range<_Base>
2206 {
return {__i._M_fun, __i._M_current + __n}; }
2208 friend constexpr _Iterator
2209 operator-(_Iterator __i, difference_type __n)
2210 requires random_access_range<_Base>
2211 {
return {__i._M_fun, __i._M_current - __n}; }
2215 friend constexpr difference_type
2216 operator-(
const _Iterator& __x,
const _Iterator& __y)
2217 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2218 {
return __x._M_current - __y._M_current; }
2220 friend constexpr decltype(
auto)
2221 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2223 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2229 friend _Iterator<!_Const>;
2230 template<
bool>
friend struct _Sentinel;
2233 template<
bool _Const>
2237 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2238 using _Base = transform_view::_Base<_Const>;
2240 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2243 _Sentinel() =
default;
2246 _Sentinel(sentinel_t<_Base> __end)
2251 _Sentinel(_Sentinel<!_Const> __i)
2253 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2257 constexpr sentinel_t<_Base>
2261 template<
bool _Const2>
2262 requires sentinel_for<sentinel_t<_Base>,
2263 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2264 friend constexpr bool
2265 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2266 {
return __x._M_current == __y._M_end; }
2268 template<
bool _Const2,
2269 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2270 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2271 friend constexpr range_difference_t<_Base2>
2272 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2273 {
return -(__y._M_end - __x._M_current); }
2275 template<
bool _Const2,
2276 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2277 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2278 friend constexpr range_difference_t<_Base2>
2279 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2280 {
return __y._M_end - __x._M_current; }
2282 friend _Sentinel<!_Const>;
2285 _Vp _M_base = _Vp();
2286 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2289 transform_view()
requires (default_initializable<_Vp>
2290 && default_initializable<_Fp>)
2294 transform_view(_Vp __base, _Fp __fun)
2295 : _M_base(std::move(
__base)), _M_fun(std::move(__fun))
2299 base() const& requires copy_constructible<_Vp>
2300 {
return _M_base ; }
2306 constexpr _Iterator<false>
2308 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2310 constexpr _Iterator<true>
2312 requires range<const _Vp>
2313 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2314 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2316 constexpr _Sentinel<false>
2318 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2320 constexpr _Iterator<false>
2321 end()
requires common_range<_Vp>
2322 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2324 constexpr _Sentinel<true>
2326 requires range<const _Vp>
2327 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2328 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2330 constexpr _Iterator<true>
2332 requires common_range<const _Vp>
2333 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2334 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2337 size()
requires sized_range<_Vp>
2338 {
return ranges::size(_M_base); }
2341 size() const requires sized_range<const _Vp>
2342 {
return ranges::size(_M_base); }
2345 template<
typename _Range,
typename _Fp>
2346 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2352 template<
typename _Range,
typename _Fp>
2353 concept __can_transform_view
2357 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2359 template<viewable_range _Range,
typename _Fp>
2360 requires __detail::__can_transform_view<_Range, _Fp>
2362 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2367 using _RangeAdaptor<_Transform>::operator();
2368 static constexpr int _S_arity = 2;
2369 static constexpr bool _S_has_simple_extra_args =
true;
2372 inline constexpr _Transform transform;
2379 template<
bool _Const>
2380 using _CI = counted_iterator<
2381 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2383 template<
bool _Const>
2387 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2388 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2391 _Sentinel() =
default;
2394 _Sentinel(sentinel_t<_Base> __end)
2399 _Sentinel(_Sentinel<!_Const> __s)
2400 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2404 constexpr sentinel_t<_Base>
2408 friend constexpr bool
2409 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2410 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2412 template<
bool _OtherConst = !_Const,
2413 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2414 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2415 friend constexpr bool
2416 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2417 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2419 friend _Sentinel<!_Const>;
2422 _Vp _M_base = _Vp();
2423 range_difference_t<_Vp> _M_count = 0;
2426 take_view()
requires default_initializable<_Vp> = default;
2429 take_view(_Vp __base, range_difference_t<_Vp> __count)
2430 : _M_base(std::move(__base)), _M_count(std::move(__count))
2434 base() const& requires copy_constructible<_Vp>
2442 begin()
requires (!__detail::__simple_view<_Vp>)
2444 if constexpr (sized_range<_Vp>)
2446 if constexpr (random_access_range<_Vp>)
2447 return ranges::begin(_M_base);
2451 return counted_iterator(ranges::begin(_M_base), __sz);
2455 return counted_iterator(ranges::begin(_M_base), _M_count);
2459 begin() const requires range<const _Vp>
2461 if constexpr (sized_range<const _Vp>)
2463 if constexpr (random_access_range<const _Vp>)
2464 return ranges::begin(_M_base);
2468 return counted_iterator(ranges::begin(_M_base), __sz);
2472 return counted_iterator(ranges::begin(_M_base), _M_count);
2476 end()
requires (!__detail::__simple_view<_Vp>)
2478 if constexpr (sized_range<_Vp>)
2480 if constexpr (random_access_range<_Vp>)
2481 return ranges::begin(_M_base) + size();
2486 return _Sentinel<false>{ranges::end(_M_base)};
2490 end() const requires range<const _Vp>
2492 if constexpr (sized_range<const _Vp>)
2494 if constexpr (random_access_range<const _Vp>)
2495 return ranges::begin(_M_base) + size();
2500 return _Sentinel<true>{ranges::end(_M_base)};
2504 size()
requires sized_range<_Vp>
2506 auto __n = ranges::size(_M_base);
2507 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2511 size() const requires sized_range<const _Vp>
2513 auto __n = ranges::size(_M_base);
2514 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2521 template<
typename _Range>
2522 take_view(_Range&&, range_difference_t<_Range>)
2523 -> take_view<views::all_t<_Range>>;
2525 template<
typename _Tp>
2526 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2527 = enable_borrowed_range<_Tp>;
2533 template<
typename _Range>
2534 inline constexpr bool __is_empty_view =
false;
2536 template<
typename _Tp>
2537 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2539 template<
typename _Range>
2540 inline constexpr bool __is_basic_string_view =
false;
2542 template<
typename _CharT,
typename _Traits>
2543 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2546 using ranges::__detail::__is_subrange;
2548 template<
typename _Range>
2549 inline constexpr bool __is_iota_view =
false;
2551 template<
typename _Winc,
typename _Bound>
2552 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2554 template<
typename _Range>
2555 inline constexpr bool __is_repeat_view =
false;
2557 template<
typename _Range>
2559 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2561 template<
typename _Range,
typename _Dp>
2562 concept __can_take_view
2566 struct _Take : __adaptor::_RangeAdaptor<_Take>
2568 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2569 requires __detail::__can_take_view<_Range, _Dp>
2571 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2573 using _Tp = remove_cvref_t<_Range>;
2574 if constexpr (__detail::__is_empty_view<_Tp>)
2576#ifdef __cpp_lib_optional_range_support
2577 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2580 else if constexpr (random_access_range<_Tp>
2582 && (std::__detail::__is_span<_Tp>
2583 || __detail::__is_basic_string_view<_Tp>
2584 || __detail::__is_subrange<_Tp>
2585 || __detail::__is_iota_view<_Tp>))
2588 auto __begin = ranges::begin(__r);
2589 auto __end = __begin + __n;
2590 if constexpr (std::__detail::__is_span<_Tp>)
2591 return span<typename _Tp::element_type>(__begin, __end);
2592 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2593 return _Tp(__begin, __end);
2594 else if constexpr (__detail::__is_subrange<_Tp>)
2595 return subrange<iterator_t<_Tp>>(__begin, __end);
2597 return iota_view(*__begin, *__end);
2599 else if constexpr (__detail::__is_repeat_view<_Tp>)
2605 using _RangeAdaptor<_Take>::operator();
2606 static constexpr int _S_arity = 2;
2610 template<
typename _Tp>
2611 static constexpr bool _S_has_simple_extra_args
2612 = ranges::__detail::__is_integer_like<_Tp>;
2615 inline constexpr _Take take;
2618 template<view _Vp,
typename _Pred>
2620 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2621 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2623 template<
bool _Const>
2627 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2629 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2630 const _Pred* _M_pred =
nullptr;
2633 _Sentinel() =
default;
2636 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2637 : _M_end(__end), _M_pred(__pred)
2641 _Sentinel(_Sentinel<!_Const> __s)
2642 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2643 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2646 constexpr sentinel_t<_Base>
2647 base()
const {
return _M_end; }
2649 friend constexpr bool
2650 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2651 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2653 template<
bool _OtherConst = !_Const,
2654 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2655 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2656 friend constexpr bool
2657 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2658 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2660 friend _Sentinel<!_Const>;
2663 _Vp _M_base = _Vp();
2664 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2667 take_while_view()
requires (default_initializable<_Vp>
2668 && default_initializable<_Pred>)
2672 take_while_view(_Vp __base, _Pred __pred)
2673 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2677 base() const& requires copy_constructible<_Vp>
2684 constexpr const _Pred&
2686 {
return *_M_pred; }
2689 begin()
requires (!__detail::__simple_view<_Vp>)
2690 {
return ranges::begin(_M_base); }
2693 begin() const requires range<const _Vp>
2694 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2695 {
return ranges::begin(_M_base); }
2698 end()
requires (!__detail::__simple_view<_Vp>)
2699 {
return _Sentinel<false>(ranges::end(_M_base),
2703 end() const requires range<const _Vp>
2704 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2705 {
return _Sentinel<true>(ranges::end(_M_base),
2709 template<
typename _Range,
typename _Pred>
2710 take_while_view(_Range&&, _Pred)
2711 -> take_while_view<views::all_t<_Range>, _Pred>;
2717 template<
typename _Range,
typename _Pred>
2718 concept __can_take_while_view
2722 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2724 template<viewable_range _Range,
typename _Pred>
2725 requires __detail::__can_take_while_view<_Range, _Pred>
2727 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2732 using _RangeAdaptor<_TakeWhile>::operator();
2733 static constexpr int _S_arity = 2;
2734 static constexpr bool _S_has_simple_extra_args =
true;
2737 inline constexpr _TakeWhile take_while;
2744 _Vp _M_base = _Vp();
2745 range_difference_t<_Vp> _M_count = 0;
2749 static constexpr bool _S_needs_cached_begin
2750 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2751 [[no_unique_address]]
2752 __detail::__maybe_present_t<_S_needs_cached_begin,
2753 __detail::_CachedPosition<_Vp>>
2757 drop_view()
requires default_initializable<_Vp> = default;
2760 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2761 : _M_base(std::move(__base)), _M_count(__count)
2762 { __glibcxx_assert(__count >= 0); }
2765 base() const& requires copy_constructible<_Vp>
2775 requires (!(__detail::__simple_view<_Vp>
2776 && random_access_range<const _Vp>
2777 && sized_range<const _Vp>))
2779 if constexpr (_S_needs_cached_begin)
2780 if (_M_cached_begin._M_has_value())
2781 return _M_cached_begin._M_get(_M_base);
2783 auto __it = ranges::next(ranges::begin(_M_base),
2784 _M_count, ranges::end(_M_base));
2785 if constexpr (_S_needs_cached_begin)
2786 _M_cached_begin._M_set(_M_base, __it);
2794 requires random_access_range<const _Vp> && sized_range<const _Vp>
2796 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2801 end()
requires (!__detail::__simple_view<_Vp>)
2802 {
return ranges::end(_M_base); }
2805 end() const requires range<const _Vp>
2806 {
return ranges::end(_M_base); }
2809 size()
requires sized_range<_Vp>
2811 const auto __s = ranges::size(_M_base);
2812 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2813 return __s < __c ? 0 : __s - __c;
2817 size() const requires sized_range<const _Vp>
2819 const auto __s = ranges::size(_M_base);
2820 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2821 return __s < __c ? 0 : __s - __c;
2825 template<
typename _Range>
2826 drop_view(_Range&&, range_difference_t<_Range>)
2827 -> drop_view<views::all_t<_Range>>;
2829 template<
typename _Tp>
2830 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2831 = enable_borrowed_range<_Tp>;
2837 template<
typename _Range>
2839 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2841 template<
typename _Range,
typename _Dp>
2842 concept __can_drop_view
2846 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2848 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2849 requires __detail::__can_drop_view<_Range, _Dp>
2851 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2853 using _Tp = remove_cvref_t<_Range>;
2854 if constexpr (__detail::__is_empty_view<_Tp>)
2856#ifdef __cpp_lib_optional_range_support
2857 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2860 else if constexpr (random_access_range<_Tp>
2862 && (std::__detail::__is_span<_Tp>
2863 || __detail::__is_basic_string_view<_Tp>
2864 || __detail::__is_iota_view<_Tp>
2865 || __detail::__is_subrange<_Tp>))
2868 auto __begin = ranges::begin(__r) + __n;
2869 auto __end = ranges::end(__r);
2870 if constexpr (std::__detail::__is_span<_Tp>)
2871 return span<typename _Tp::element_type>(__begin, __end);
2872 else if constexpr (__detail::__is_subrange<_Tp>)
2874 if constexpr (_Tp::_S_store_size)
2876 using ranges::__detail::__to_unsigned_like;
2877 auto __m = ranges::distance(__r) - __n;
2878 return _Tp(__begin, __end, __to_unsigned_like(__m));
2881 return _Tp(__begin, __end);
2884 return _Tp(__begin, __end);
2886 else if constexpr (__detail::__is_repeat_view<_Tp>)
2892 using _RangeAdaptor<_Drop>::operator();
2893 static constexpr int _S_arity = 2;
2894 template<
typename _Tp>
2895 static constexpr bool _S_has_simple_extra_args
2896 = _Take::_S_has_simple_extra_args<_Tp>;
2899 inline constexpr _Drop drop;
2902 template<view _Vp,
typename _Pred>
2904 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2905 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2908 _Vp _M_base = _Vp();
2909 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2910 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2913 drop_while_view()
requires (default_initializable<_Vp>
2914 && default_initializable<_Pred>)
2918 drop_while_view(_Vp __base, _Pred __pred)
2919 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
2923 base() const& requires copy_constructible<_Vp>
2930 constexpr const _Pred&
2932 {
return *_M_pred; }
2937 if (_M_cached_begin._M_has_value())
2938 return _M_cached_begin._M_get(_M_base);
2940 __glibcxx_assert(_M_pred.has_value());
2941 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2942 ranges::end(_M_base),
2944 _M_cached_begin._M_set(_M_base, __it);
2950 {
return ranges::end(_M_base); }
2953 template<
typename _Range,
typename _Pred>
2954 drop_while_view(_Range&&, _Pred)
2955 -> drop_while_view<views::all_t<_Range>, _Pred>;
2957 template<
typename _Tp,
typename _Pred>
2958 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2959 = enable_borrowed_range<_Tp>;
2965 template<
typename _Range,
typename _Pred>
2966 concept __can_drop_while_view
2970 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2972 template<viewable_range _Range,
typename _Pred>
2973 requires __detail::__can_drop_while_view<_Range, _Pred>
2975 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2981 using _RangeAdaptor<_DropWhile>::operator();
2982 static constexpr int _S_arity = 2;
2983 static constexpr bool _S_has_simple_extra_args =
true;
2986 inline constexpr _DropWhile drop_while;
2991 template<
typename _Tp>
2993 __as_lvalue(_Tp&& __t)
2994 {
return static_cast<_Tp&
>(__t); }
2997 template<input_range _Vp>
3002 using _InnerRange = range_reference_t<_Vp>;
3004 template<
bool _Const>
3005 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3007 template<
bool _Const>
3008 using _Outer_iter = iterator_t<_Base<_Const>>;
3010 template<
bool _Const>
3011 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
3013 template<
bool _Const>
3014 static constexpr bool _S_ref_is_glvalue
3015 = is_reference_v<range_reference_t<_Base<_Const>>>;
3017 template<
bool _Const>
3021 template<
bool _Const>
3022 requires _S_ref_is_glvalue<_Const>
3023 && forward_range<_Base<_Const>>
3024 && forward_range<range_reference_t<_Base<_Const>>>
3025 struct __iter_cat<_Const>
3028 static constexpr auto
3031 using _Outer_iter = join_view::_Outer_iter<_Const>;
3032 using _Inner_iter = join_view::_Inner_iter<_Const>;
3033 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
3034 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
3035 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
3036 && derived_from<_InnerCat, bidirectional_iterator_tag>
3037 && common_range<range_reference_t<_Base<_Const>>>)
3038 return bidirectional_iterator_tag{};
3039 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
3040 && derived_from<_InnerCat, forward_iterator_tag>)
3041 return forward_iterator_tag{};
3043 return input_iterator_tag{};
3046 using iterator_category =
decltype(_S_iter_cat());
3049 template<
bool _Const>
3052 template<
bool _Const>
3053 struct _Iterator : __iter_cat<_Const>
3056 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3057 using _Base = join_view::_Base<_Const>;
3061 static constexpr bool _S_ref_is_glvalue
3062 = join_view::_S_ref_is_glvalue<_Const>;
3067 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
3068 if constexpr (_S_ref_is_glvalue)
3071 return _M_parent->_M_inner._M_emplace_deref(__x);
3074 _Outer_iter& __outer = _M_get_outer();
3075 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
3077 auto&& __inner = __update_inner(__outer);
3078 _M_inner = ranges::begin(__inner);
3079 if (_M_inner != ranges::end(__inner))
3083 if constexpr (_S_ref_is_glvalue)
3085 if constexpr (forward_iterator<_Inner_iter>)
3086 _M_inner = _Inner_iter();
3092 static constexpr auto
3095 if constexpr (_S_ref_is_glvalue
3096 && bidirectional_range<_Base>
3097 && bidirectional_range<range_reference_t<_Base>>
3098 && common_range<range_reference_t<_Base>>)
3099 return bidirectional_iterator_tag{};
3100 else if constexpr (_S_ref_is_glvalue
3101 && forward_range<_Base>
3102 && forward_range<range_reference_t<_Base>>)
3103 return forward_iterator_tag{};
3105 return input_iterator_tag{};
3108 using _Outer_iter = join_view::_Outer_iter<_Const>;
3109 using _Inner_iter = join_view::_Inner_iter<_Const>;
3111 constexpr _Outer_iter&
3114 if constexpr (forward_range<_Base>)
3117 return *_M_parent->_M_outer;
3120 constexpr const _Outer_iter&
3121 _M_get_outer()
const
3123 if constexpr (forward_range<_Base>)
3126 return *_M_parent->_M_outer;
3129 constexpr _Inner_iter&
3130 _M_get_inner() noexcept
3132 if constexpr (forward_iterator<_Inner_iter>)
3138 constexpr const _Inner_iter&
3139 _M_get_inner() const noexcept
3141 if constexpr (forward_iterator<_Inner_iter>)
3148 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
3149 : _M_outer(
std::move(__outer)), _M_parent(__parent)
3153 _Iterator(_Parent* __parent, _Outer_iter __outer, _Inner_iter __inner)
3154 requires forward_range<_Base>
3160 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
3161 : _M_parent(__parent)
3164 [[no_unique_address]]
3165 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
3166 =
decltype(_M_outer)();
3167 __conditional_t<forward_iterator<_Inner_iter>,
3168 _Inner_iter, optional<_Inner_iter>> _M_inner
3169 =
decltype(_M_inner)();
3170 _Parent* _M_parent =
nullptr;
3173 using iterator_concept =
decltype(_S_iter_concept());
3175 using value_type = range_value_t<range_reference_t<_Base>>;
3176 using difference_type
3178 range_difference_t<range_reference_t<_Base>>>;
3180 _Iterator() =
default;
3183 _Iterator(_Iterator<!_Const> __i)
3185 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3186 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3188 _M_parent(__i._M_parent)
3191 constexpr decltype(
auto)
3193 {
return *_M_get_inner(); }
3197 constexpr _Inner_iter
3199 requires __detail::__has_arrow<_Inner_iter>
3200 && copyable<_Inner_iter>
3201 {
return _M_get_inner(); }
3203 constexpr _Iterator&
3206 auto&& __inner_range = [
this] () ->
auto&& {
3207 if constexpr (_S_ref_is_glvalue)
3208 return *_M_get_outer();
3210 return *_M_parent->_M_inner;
3212 if (++_M_get_inner() == ranges::end(__inner_range))
3226 requires _S_ref_is_glvalue && forward_range<_Base>
3227 && forward_range<range_reference_t<_Base>>
3234 constexpr _Iterator&
3236 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3237 && bidirectional_range<range_reference_t<_Base>>
3238 && common_range<range_reference_t<_Base>>
3240 if (_M_outer == ranges::end(_M_parent->_M_base))
3241 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3242 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3243 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3250 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3251 && bidirectional_range<range_reference_t<_Base>>
3252 && common_range<range_reference_t<_Base>>
3259 friend constexpr bool
3260 operator==(
const _Iterator& __x,
const _Iterator& __y)
3261 requires _S_ref_is_glvalue
3262 && forward_range<_Base>
3263 && equality_comparable<_Inner_iter>
3265 return (__x._M_outer == __y._M_outer
3266 && __x._M_inner == __y._M_inner);
3269 friend constexpr decltype(
auto)
3270 iter_move(
const _Iterator& __i)
3271 noexcept(
noexcept(ranges::iter_move(__i._M_get_inner())))
3272 {
return ranges::iter_move(__i._M_get_inner()); }
3274 friend constexpr void
3275 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3276 noexcept(
noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3277 requires indirectly_swappable<_Inner_iter>
3278 {
return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3280 friend _Iterator<!_Const>;
3281 template<
bool>
friend struct _Sentinel;
3283 template<
typename _Fn>
3284 static constexpr _Iterator
3285 _S_for_each_segment(_Iterator __first, _Iterator __last, _Fn __func)
3287 _Inner_iter __first_inner = __first._M_get_inner();
3288 _Outer_iter __first_outer = __first._M_get_outer();
3289 _Inner_iter __last_inner = __last._M_get_inner();
3290 _Outer_iter __last_outer = __last._M_get_outer();
3292 if (__first_outer == __last_outer)
3294 auto __ret = __func(__first_inner, __last_inner);
3295 return _Iterator(__first._M_parent, __first_outer, __ret);
3299 auto __end = ranges::end(*__first_outer);
3300 auto __ret = __func(__first_inner, __end);
3302 return _Iterator(__first._M_parent, __first_outer, __ret);
3304 while (++__first_outer != __last_outer)
3306 __end = ranges::end(*__first_outer);
3307 __ret = __func(ranges::begin(*__first_outer), __end);
3309 return _Iterator(__first._M_parent, __first_outer, __ret);
3312 if (__last != __last._M_parent->end())
3314 __end = __last_inner;
3315 __ret = __func(ranges::begin(*__last_outer), __end);
3317 return _Iterator(__first._M_parent, __first_outer, __ret);
3324 static constexpr bool _S_enable_for_each_segment
3325 = forward_iterator<_Iterator>;
3328 template<
bool _Const>
3332 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3333 using _Base = join_view::_Base<_Const>;
3335 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3338 _Sentinel() =
default;
3341 _Sentinel(_Parent* __parent)
3342 : _M_end(ranges::end(__parent->_M_base))
3346 _Sentinel(_Sentinel<!_Const> __s)
3347 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3351 template<
bool _Const2>
3352 requires sentinel_for<sentinel_t<_Base>,
3353 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3354 friend constexpr bool
3355 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3356 {
return __x._M_get_outer() == __y._M_end; }
3358 friend _Sentinel<!_Const>;
3361 _Vp _M_base = _Vp();
3362 [[no_unique_address]]
3363 __detail::__maybe_present_t<!forward_range<_Vp>,
3364 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3365 [[no_unique_address]]
3366 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3369 join_view()
requires default_initializable<_Vp> = default;
3372 join_view(_Vp __base)
3373 : _M_base(std::move(__base))
3377 base() const& requires copy_constructible<_Vp>
3387 if constexpr (forward_range<_Vp>)
3389 constexpr bool __use_const
3390 = (__detail::__simple_view<_Vp>
3391 && is_reference_v<range_reference_t<_Vp>>);
3392 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3396 _M_outer = ranges::begin(_M_base);
3397 return _Iterator<false>{
this};
3403 requires forward_range<const _Vp>
3404 && is_reference_v<range_reference_t<const _Vp>>
3405 && input_range<range_reference_t<const _Vp>>
3407 return _Iterator<true>{
this, ranges::begin(_M_base)};
3413 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3414 && forward_range<_InnerRange>
3415 && common_range<_Vp> && common_range<_InnerRange>)
3416 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3417 ranges::end(_M_base)};
3419 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3424 requires forward_range<const _Vp>
3425 && is_reference_v<range_reference_t<const _Vp>>
3426 && input_range<range_reference_t<const _Vp>>
3428 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3429 && forward_range<range_reference_t<const _Vp>>
3430 && common_range<const _Vp>
3431 && common_range<range_reference_t<const _Vp>>)
3432 return _Iterator<true>{
this, ranges::end(_M_base)};
3434 return _Sentinel<true>{
this};
3438 template<
typename _Range>
3439 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3445 template<
typename _Range>
3446 concept __can_join_view
3450 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3452 template<viewable_range _Range>
3453 requires __detail::__can_join_view<_Range>
3455 operator() [[nodiscard]] (_Range&& __r)
const
3462 static constexpr bool _S_has_simple_call_op =
true;
3465 inline constexpr _Join join;
3471 struct __require_constant;
3473 template<
typename _Range>
3474 concept __tiny_range = sized_range<_Range>
3476 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3477 && (remove_reference_t<_Range>::size() <= 1);
3479 template<
typename _Base>
3480 struct __lazy_split_view_outer_iter_cat
3483 template<forward_range _Base>
3484 struct __lazy_split_view_outer_iter_cat<_Base>
3485 {
using iterator_category = input_iterator_tag; };
3487 template<
typename _Base>
3488 struct __lazy_split_view_inner_iter_cat
3491 template<forward_range _Base>
3492 struct __lazy_split_view_inner_iter_cat<_Base>
3495 static constexpr auto
3498 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3499 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3500 return forward_iterator_tag{};
3505 using iterator_category =
decltype(_S_iter_cat());
3509 template<input_range _Vp, forward_range _Pattern>
3511 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3514 class lazy_split_view : public
view_interface<lazy_split_view<_Vp, _Pattern>>
3517 template<
bool _Const>
3518 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3520 template<
bool _Const>
3523 template<
bool _Const>
3525 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3528 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3529 using _Base = lazy_split_view::_Base<_Const>;
3536 __current() noexcept
3538 if constexpr (forward_range<_Vp>)
3541 return *_M_parent->_M_current;
3545 __current() const noexcept
3547 if constexpr (forward_range<_Vp>)
3550 return *_M_parent->_M_current;
3553 _Parent* _M_parent =
nullptr;
3555 [[no_unique_address]]
3556 __detail::__maybe_present_t<forward_range<_Vp>,
3557 iterator_t<_Base>> _M_current
3558 =
decltype(_M_current)();
3559 bool _M_trailing_empty =
false;
3562 using iterator_concept = __conditional_t<forward_range<_Base>,
3563 forward_iterator_tag,
3564 input_iterator_tag>;
3566 using difference_type = range_difference_t<_Base>;
3568 struct value_type : view_interface<value_type>
3571 _OuterIter _M_i = _OuterIter();
3577 value_type(_OuterIter __i)
3578 : _M_i(std::move(__i))
3584 constexpr _InnerIter<_Const>
3586 {
return _InnerIter<_Const>{_M_i}; }
3588 constexpr default_sentinel_t
3589 end() const noexcept
3593 _OuterIter() =
default;
3596 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3597 : _M_parent(__parent)
3601 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3602 requires forward_range<_Base>
3603 : _M_parent(__parent),
3608 _OuterIter(_OuterIter<!_Const> __i)
3610 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3611 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3612 _M_trailing_empty(__i._M_trailing_empty)
3615 constexpr value_type
3617 {
return value_type{*
this}; }
3619 constexpr _OuterIter&
3624 const auto __end = ranges::end(_M_parent->_M_base);
3625 if (__current() == __end)
3627 _M_trailing_empty =
false;
3630 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3631 if (__pbegin == __pend)
3633 else if constexpr (__detail::__tiny_range<_Pattern>)
3635 __current() = ranges::find(
std::move(__current()), __end,
3637 if (__current() != __end)
3640 if (__current() == __end)
3641 _M_trailing_empty =
true;
3648 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3652 if (__current() == __end)
3653 _M_trailing_empty =
true;
3656 }
while (++__current() != __end);
3660 constexpr decltype(
auto)
3663 if constexpr (forward_range<_Base>)
3673 friend constexpr bool
3674 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3675 requires forward_range<_Base>
3677 return __x._M_current == __y._M_current
3678 && __x._M_trailing_empty == __y._M_trailing_empty;
3681 friend constexpr bool
3682 operator==(
const _OuterIter& __x, default_sentinel_t)
3684 return __x.__current() == ranges::end(__x._M_parent->_M_base)
3685 && !__x._M_trailing_empty;
3688 friend _OuterIter<!_Const>;
3689 friend _InnerIter<_Const>;
3692 template<
bool _Const>
3694 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3697 using _Base = lazy_split_view::_Base<_Const>;
3702 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3703 auto __end = ranges::end(_M_i._M_parent->_M_base);
3704 if constexpr (__detail::__tiny_range<_Pattern>)
3706 const auto& __cur = _M_i_current();
3709 if (__pcur == __pend)
3710 return _M_incremented;
3711 return *__cur == *__pcur;
3715 auto __cur = _M_i_current();
3718 if (__pcur == __pend)
3719 return _M_incremented;
3722 if (*__cur != *__pcur)
3724 if (++__pcur == __pend)
3726 }
while (++__cur != __end);
3732 _M_i_current() noexcept
3733 {
return _M_i.__current(); }
3736 _M_i_current() const noexcept
3737 {
return _M_i.__current(); }
3739 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3740 bool _M_incremented =
false;
3743 using iterator_concept
3744 =
typename _OuterIter<_Const>::iterator_concept;
3746 using value_type = range_value_t<_Base>;
3747 using difference_type = range_difference_t<_Base>;
3749 _InnerIter() =
default;
3752 _InnerIter(_OuterIter<_Const> __i)
3753 : _M_i(std::move(__i))
3756 constexpr const iterator_t<_Base>&
3757 base() const& noexcept
3758 {
return _M_i_current(); }
3760 constexpr iterator_t<_Base>
3761 base() &&
requires forward_range<_Vp>
3764 constexpr decltype(
auto)
3766 {
return *_M_i_current(); }
3768 constexpr _InnerIter&
3771 _M_incremented =
true;
3772 if constexpr (!forward_range<_Base>)
3773 if constexpr (_Pattern::size() == 0)
3779 constexpr decltype(
auto)
3782 if constexpr (forward_range<_Base>)
3792 friend constexpr bool
3793 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3794 requires forward_range<_Base>
3795 {
return __x._M_i == __y._M_i; }
3797 friend constexpr bool
3798 operator==(
const _InnerIter& __x, default_sentinel_t)
3799 {
return __x.__at_end(); }
3801 friend constexpr decltype(
auto)
3802 iter_move(
const _InnerIter& __i)
3803 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3804 {
return ranges::iter_move(__i._M_i_current()); }
3806 friend constexpr void
3807 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3808 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3809 __y._M_i_current())))
3810 requires indirectly_swappable<iterator_t<_Base>>
3811 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3814 _Vp _M_base = _Vp();
3815 _Pattern _M_pattern = _Pattern();
3816 [[no_unique_address]]
3817 __detail::__maybe_present_t<!forward_range<_Vp>,
3818 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3822 lazy_split_view()
requires (default_initializable<_Vp>
3823 && default_initializable<_Pattern>)
3827 lazy_split_view(_Vp __base, _Pattern __pattern)
3828 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3831 template<input_range _Range>
3832 requires constructible_from<_Vp, views::all_t<_Range>>
3833 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3835 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3836 : _M_base(views::all(std::
forward<_Range>(__r))),
3837 _M_pattern(views::single(std::move(__e)))
3841 base() const& requires copy_constructible<_Vp>
3851 if constexpr (forward_range<_Vp>)
3853 constexpr bool __simple
3854 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3855 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3859 _M_current = ranges::begin(_M_base);
3860 return _OuterIter<false>{
this};
3868 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3869 && forward_range<const _Pattern>
3871 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3875 end()
requires forward_range<_Vp> && common_range<_Vp>
3877 constexpr bool __simple
3878 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3879 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3885 if constexpr (forward_range<_Vp>
3886 && forward_range<const _Vp>
3887 && common_range<const _Vp>
3888 && forward_range<const _Pattern>)
3889 return _OuterIter<true>{
this, ranges::end(_M_base)};
3895 template<
typename _Range,
typename _Pattern>
3896 lazy_split_view(_Range&&, _Pattern&&)
3897 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3899 template<input_range _Range>
3900 lazy_split_view(_Range&&, range_value_t<_Range>)
3907 template<
typename _Range,
typename _Pattern>
3908 concept __can_lazy_split_view
3912 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3914 template<viewable_range _Range,
typename _Pattern>
3915 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3917 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3922 using _RangeAdaptor<_LazySplit>::operator();
3923 static constexpr int _S_arity = 2;
3928 template<
typename _Pattern>
3929 static constexpr bool _S_has_simple_extra_args
3930 = is_scalar_v<_Pattern> || (view<_Pattern>
3931 && copy_constructible<_Pattern>);
3934 inline constexpr _LazySplit lazy_split;
3937 template<forward_range _Vp, forward_range _Pattern>
3939 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3941 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3944 _Vp _M_base = _Vp();
3945 _Pattern _M_pattern = _Pattern();
3946 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3952 split_view()
requires (default_initializable<_Vp>
3953 && default_initializable<_Pattern>)
3957 split_view(_Vp __base, _Pattern __pattern)
3958 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
3961 template<forward_range _Range>
3962 requires constructible_from<_Vp, views::all_t<_Range>>
3963 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3965 split_view(_Range&& __r, range_value_t<_Range> __e)
3966 : _M_base(views::all(std::
forward<_Range>(__r))),
3967 _M_pattern(views::single(std::move(__e)))
3971 base() const& requires copy_constructible<_Vp>
3981 if (!_M_cached_begin)
3982 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3983 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3989 if constexpr (common_range<_Vp>)
3990 return _Iterator{
this, ranges::end(_M_base), {}};
3992 return _Sentinel{
this};
3995 constexpr subrange<iterator_t<_Vp>>
3996 _M_find_next(iterator_t<_Vp> __it)
3998 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3999 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
4011 split_view* _M_parent =
nullptr;
4012 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
4013 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
4014 bool _M_trailing_empty =
false;
4016 friend struct _Sentinel;
4019 using iterator_concept = forward_iterator_tag;
4020 using iterator_category = input_iterator_tag;
4021 using value_type = subrange<iterator_t<_Vp>>;
4022 using difference_type = range_difference_t<_Vp>;
4024 _Iterator() =
default;
4027 _Iterator(split_view* __parent,
4028 iterator_t<_Vp> __current,
4029 subrange<iterator_t<_Vp>> __next)
4030 : _M_parent(__parent),
4031 _M_cur(std::move(__current)),
4032 _M_next(std::move(__next))
4035 constexpr iterator_t<_Vp>
4039 constexpr value_type
4041 {
return {_M_cur, _M_next.begin()}; }
4043 constexpr _Iterator&
4046 _M_cur = _M_next.begin();
4047 if (_M_cur != ranges::end(_M_parent->_M_base))
4049 _M_cur = _M_next.end();
4050 if (_M_cur == ranges::end(_M_parent->_M_base))
4052 _M_trailing_empty =
true;
4053 _M_next = {_M_cur, _M_cur};
4056 _M_next = _M_parent->_M_find_next(_M_cur);
4059 _M_trailing_empty =
false;
4071 friend constexpr bool
4072 operator==(
const _Iterator& __x,
const _Iterator& __y)
4074 return __x._M_cur == __y._M_cur
4075 && __x._M_trailing_empty == __y._M_trailing_empty;
4082 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
4085 _Sentinel() =
default;
4088 _Sentinel(split_view* __parent)
4089 : _M_end(ranges::end(__parent->_M_base))
4092 friend constexpr bool
4093 operator==(
const _Iterator& __x,
const _Sentinel& __y)
4094 {
return __x._M_cur == __y._M_end && !__x._M_trailing_empty; }
4098 template<
typename _Range,
typename _Pattern>
4099 split_view(_Range&&, _Pattern&&)
4100 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
4102 template<forward_range _Range>
4103 split_view(_Range&&, range_value_t<_Range>)
4110 template<
typename _Range,
typename _Pattern>
4111 concept __can_split_view
4115 struct _Split : __adaptor::_RangeAdaptor<_Split>
4117 template<viewable_range _Range,
typename _Pattern>
4118 requires __detail::__can_split_view<_Range, _Pattern>
4120 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
4125 using _RangeAdaptor<_Split>::operator();
4126 static constexpr int _S_arity = 2;
4127 template<
typename _Pattern>
4128 static constexpr bool _S_has_simple_extra_args
4129 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
4132 inline constexpr _Split split;
4139 template<input_or_output_iterator _Iter>
4141 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
4143 if constexpr (contiguous_iterator<_Iter>)
4145 else if constexpr (random_access_iterator<_Iter>)
4146 return subrange(__i, __i + __n);
4148 return subrange(counted_iterator(
std::move(__i), __n),
4153 inline constexpr _Counted counted{};
4161 _Vp _M_base = _Vp();
4164 common_view()
requires default_initializable<_Vp> = default;
4167 common_view(_Vp __r)
4168 : _M_base(std::move(__r))
4172 base() const& requires copy_constructible<_Vp>
4182 begin()
requires (!__detail::__simple_view<_Vp>)
4185 return ranges::begin(_M_base);
4187 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4188 (ranges::begin(_M_base));
4195 return ranges::begin(_M_base);
4197 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4198 (ranges::begin(_M_base));
4202 end()
requires (!__detail::__simple_view<_Vp>)
4205 return ranges::begin(_M_base) + ranges::size(_M_base);
4207 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4208 (ranges::end(_M_base));
4212 end() const requires
range<const _Vp>
4215 return ranges::begin(_M_base) + ranges::size(_M_base);
4217 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4218 (ranges::end(_M_base));
4223 {
return ranges::size(_M_base); }
4227 {
return ranges::size(_M_base); }
4230 template<
typename _Range>
4231 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4233 template<
typename _Tp>
4234 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4235 = enable_borrowed_range<_Tp>;
4241 template<
typename _Range>
4242 concept __already_common = common_range<_Range>
4245 template<
typename _Range>
4246 concept __can_common_view
4250 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4252 template<viewable_range _Range>
4253 requires __detail::__already_common<_Range>
4254 || __detail::__can_common_view<_Range>
4256 operator() [[nodiscard]] (_Range&& __r)
const
4258 if constexpr (__detail::__already_common<_Range>)
4264 static constexpr bool _S_has_simple_call_op =
true;
4267 inline constexpr _Common common;
4275 static constexpr bool _S_needs_cached_begin
4276 = !common_range<_Vp> && !(random_access_range<_Vp>
4277 && sized_sentinel_for<sentinel_t<_Vp>,
4280 _Vp _M_base = _Vp();
4281 [[no_unique_address]]
4282 __detail::__maybe_present_t<_S_needs_cached_begin,
4283 __detail::_CachedPosition<_Vp>>
4287 reverse_view()
requires default_initializable<_Vp> = default;
4290 reverse_view(_Vp __r)
4291 : _M_base(std::move(__r))
4295 base() const& requires copy_constructible<_Vp>
4302 constexpr reverse_iterator<iterator_t<_Vp>>
4305 if constexpr (_S_needs_cached_begin)
4306 if (_M_cached_begin._M_has_value())
4309 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4310 if constexpr (_S_needs_cached_begin)
4311 _M_cached_begin._M_set(_M_base, __it);
4316 begin()
requires common_range<_Vp>
4320 begin() const requires common_range<const _Vp>
4323 constexpr reverse_iterator<iterator_t<_Vp>>
4328 end() const requires common_range<const _Vp>
4332 size()
requires sized_range<_Vp>
4333 {
return ranges::size(_M_base); }
4336 size() const requires sized_range<const _Vp>
4337 {
return ranges::size(_M_base); }
4340 template<
typename _Range>
4341 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4343 template<
typename _Tp>
4344 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4345 = enable_borrowed_range<_Tp>;
4352 inline constexpr bool __is_reversible_subrange =
false;
4354 template<
typename _Iter, subrange_kind _Kind>
4355 inline constexpr bool
4356 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4357 reverse_iterator<_Iter>,
4361 inline constexpr bool __is_reverse_view =
false;
4363 template<
typename _Vp>
4364 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4366 template<
typename _Range>
4367 concept __can_reverse_view
4371 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4373 template<viewable_range _Range>
4374 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4375 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4376 || __detail::__can_reverse_view<_Range>
4378 operator() [[nodiscard]] (_Range&& __r)
const
4380 using _Tp = remove_cvref_t<_Range>;
4381 if constexpr (__detail::__is_reverse_view<_Tp>)
4383#ifdef __cpp_lib_optional_range_support
4384 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
4387 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4389 using _Iter =
decltype(ranges::begin(__r).base());
4390 if constexpr (sized_range<_Tp>)
4391 return subrange<_Iter, _Iter, subrange_kind::sized>
4392 {__r.end().base(), __r.begin().base(), __r.size()};
4394 return subrange<_Iter, _Iter, subrange_kind::unsized>
4395 {__r.end().base(), __r.begin().base()};
4401 static constexpr bool _S_has_simple_call_op =
true;
4404 inline constexpr _Reverse reverse;
4409#if __cpp_lib_tuple_like
4412 template<
typename _Tp,
size_t _Nm>
4413 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>
4414 &&
requires(_Tp __t)
4416 { std::get<_Nm>(__t) }
4417 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4420 template<
typename _Tp,
size_t _Nm>
4421 concept __has_tuple_element =
requires(_Tp __t)
4423 typename tuple_size<_Tp>::type;
4424 requires _Nm < tuple_size_v<_Tp>;
4425 typename tuple_element_t<_Nm, _Tp>;
4426 { std::get<_Nm>(__t) }
4427 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4431 template<
typename _Tp,
size_t _Nm>
4432 concept __returnable_element
4433 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4436 template<input_range _Vp,
size_t _Nm>
4438 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4439 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4441 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4442 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4445 elements_view()
requires default_initializable<_Vp> = default;
4448 elements_view(_Vp __base)
4449 : _M_base(std::move(__base))
4453 base() const& requires copy_constructible<_Vp>
4461 begin()
requires (!__detail::__simple_view<_Vp>)
4462 {
return _Iterator<false>(ranges::begin(_M_base)); }
4465 begin() const requires range<const _Vp>
4466 {
return _Iterator<true>(ranges::begin(_M_base)); }
4469 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4470 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4473 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4474 {
return _Iterator<false>{ranges::end(_M_base)}; }
4477 end() const requires range<const _Vp>
4478 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4481 end() const requires common_range<const _Vp>
4482 {
return _Iterator<true>{ranges::end(_M_base)}; }
4485 size()
requires sized_range<_Vp>
4486 {
return ranges::size(_M_base); }
4489 size() const requires sized_range<const _Vp>
4490 {
return ranges::size(_M_base); }
4493 template<
bool _Const>
4494 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4496 template<
bool _Const>
4500 template<
bool _Const>
4501 requires forward_range<_Base<_Const>>
4502 struct __iter_cat<_Const>
4505 static auto _S_iter_cat()
4507 using _Base = elements_view::_Base<_Const>;
4508 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4509 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4510 if constexpr (!is_lvalue_reference_v<_Res>)
4511 return input_iterator_tag{};
4512 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4513 return random_access_iterator_tag{};
4518 using iterator_category =
decltype(_S_iter_cat());
4521 template<
bool _Const>
4524 template<
bool _Const>
4525 struct _Iterator : __iter_cat<_Const>
4528 using _Base = elements_view::_Base<_Const>;
4530 iterator_t<_Base> _M_current = iterator_t<_Base>();
4532 static constexpr decltype(
auto)
4533 _S_get_element(
const iterator_t<_Base>& __i)
4535 if constexpr (is_reference_v<range_reference_t<_Base>>)
4536 return std::get<_Nm>(*__i);
4539 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4540 return static_cast<_Et
>(std::get<_Nm>(*__i));
4547 if constexpr (random_access_range<_Base>)
4548 return random_access_iterator_tag{};
4549 else if constexpr (bidirectional_range<_Base>)
4550 return bidirectional_iterator_tag{};
4551 else if constexpr (forward_range<_Base>)
4552 return forward_iterator_tag{};
4554 return input_iterator_tag{};
4557 friend _Iterator<!_Const>;
4560 using iterator_concept =
decltype(_S_iter_concept());
4563 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4564 using difference_type = range_difference_t<_Base>;
4566 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4569 _Iterator(iterator_t<_Base> __current)
4570 : _M_current(std::move(__current))
4574 _Iterator(_Iterator<!_Const> __i)
4575 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4579 constexpr const iterator_t<_Base>&
4580 base() const& noexcept
4581 {
return _M_current; }
4583 constexpr iterator_t<_Base>
4587 constexpr decltype(
auto)
4589 {
return _S_get_element(_M_current); }
4591 constexpr _Iterator&
4603 operator++(
int)
requires forward_range<_Base>
4610 constexpr _Iterator&
4611 operator--()
requires bidirectional_range<_Base>
4618 operator--(
int)
requires bidirectional_range<_Base>
4625 constexpr _Iterator&
4626 operator+=(difference_type __n)
4627 requires random_access_range<_Base>
4633 constexpr _Iterator&
4634 operator-=(difference_type __n)
4635 requires random_access_range<_Base>
4641 constexpr decltype(
auto)
4642 operator[](difference_type __n)
const
4643 requires random_access_range<_Base>
4644 {
return _S_get_element(_M_current + __n); }
4646 friend constexpr bool
4647 operator==(
const _Iterator& __x,
const _Iterator& __y)
4648 requires equality_comparable<iterator_t<_Base>>
4649 {
return __x._M_current == __y._M_current; }
4651 friend constexpr bool
4652 operator<(
const _Iterator& __x,
const _Iterator& __y)
4653 requires random_access_range<_Base>
4654 {
return __x._M_current < __y._M_current; }
4656 friend constexpr bool
4657 operator>(
const _Iterator& __x,
const _Iterator& __y)
4658 requires random_access_range<_Base>
4659 {
return __y._M_current < __x._M_current; }
4661 friend constexpr bool
4662 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4663 requires random_access_range<_Base>
4664 {
return !(__y._M_current > __x._M_current); }
4666 friend constexpr bool
4667 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4668 requires random_access_range<_Base>
4669 {
return !(__x._M_current > __y._M_current); }
4671#ifdef __cpp_lib_three_way_comparison
4672 friend constexpr auto
4673 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4674 requires random_access_range<_Base>
4675 && three_way_comparable<iterator_t<_Base>>
4676 {
return __x._M_current <=> __y._M_current; }
4679 friend constexpr _Iterator
4680 operator+(
const _Iterator& __x, difference_type __y)
4681 requires random_access_range<_Base>
4682 {
return _Iterator{__x} += __y; }
4684 friend constexpr _Iterator
4685 operator+(difference_type __x,
const _Iterator& __y)
4686 requires random_access_range<_Base>
4687 {
return __y + __x; }
4689 friend constexpr _Iterator
4690 operator-(
const _Iterator& __x, difference_type __y)
4691 requires random_access_range<_Base>
4692 {
return _Iterator{__x} -= __y; }
4696 friend constexpr difference_type
4697 operator-(
const _Iterator& __x,
const _Iterator& __y)
4698 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4699 {
return __x._M_current - __y._M_current; }
4701 template <
bool>
friend struct _Sentinel;
4704 template<
bool _Const>
4708 using _Base = elements_view::_Base<_Const>;
4709 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4712 _Sentinel() =
default;
4715 _Sentinel(sentinel_t<_Base> __end)
4716 : _M_end(std::move(__end))
4720 _Sentinel(_Sentinel<!_Const> __other)
4722 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4726 constexpr sentinel_t<_Base>
4730 template<
bool _Const2>
4731 requires sentinel_for<sentinel_t<_Base>,
4732 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4733 friend constexpr bool
4734 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4735 {
return __x._M_current == __y._M_end; }
4737 template<
bool _Const2,
4738 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4739 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4740 friend constexpr range_difference_t<_Base2>
4741 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4742 {
return -(__y._M_end - __x._M_current); }
4744 template<
bool _Const2,
4745 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4746 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4747 friend constexpr range_difference_t<_Base2>
4748 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4749 {
return __x._M_end - __y._M_current; }
4751 friend _Sentinel<!_Const>;
4754 _Vp _M_base = _Vp();
4757 template<
typename _Tp,
size_t _Nm>
4758 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4759 = enable_borrowed_range<_Tp>;
4763 template<
typename _Range>
4764 using keys_view = elements_view<_Range, 0>;
4766 template<
typename _Range>
4767 using values_view = elements_view<_Range, 1>;
4773 template<
size_t _Nm,
typename _Range>
4774 concept __can_elements_view
4778 template<
size_t _Nm>
4779 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4781 template<viewable_range _Range>
4782 requires __detail::__can_elements_view<_Nm, _Range>
4784 operator() [[nodiscard]] (_Range&& __r)
const
4789 static constexpr bool _S_has_simple_call_op =
true;
4792 template<
size_t _Nm>
4793 inline constexpr _Elements<_Nm> elements;
4794 inline constexpr auto keys = elements<0>;
4795 inline constexpr auto values = elements<1>;
4798#ifdef __cpp_lib_ranges_zip
4801 template<
typename... _Rs>
4802 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4803 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4804 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4806 template<
typename _Fp,
typename _Tuple>
4808 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4810 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4811 return tuple<invoke_result_t<_Fp&, _Ts>...>
4816 template<
typename _Fp,
typename _Tuple>
4818 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4820 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4827 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4830 tuple<_Vs...> _M_views;
4832 template<
bool>
class _Iterator;
4833 template<
bool>
class _Sentinel;
4836 zip_view() =
default;
4839 zip_view(_Vs... __views)
4840 : _M_views(std::move(__views)...)
4844 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4845 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4848 begin() const requires (
range<const _Vs> && ...)
4849 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4852 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4854 if constexpr (!__detail::__zip_is_common<_Vs...>)
4855 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4857 return begin() + iter_difference_t<_Iterator<false>>(
size());
4859 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4863 end() const requires (
range<const _Vs> && ...)
4865 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4866 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4868 return begin() + iter_difference_t<_Iterator<true>>(
size());
4870 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4876 return std::apply([](
auto... __sizes) {
4877 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4878 return ranges::min({_CT(__sizes)...});
4879 }, __detail::__tuple_transform(ranges::size, _M_views));
4885 return std::apply([](
auto... __sizes) {
4886 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
4887 return ranges::min({_CT(__sizes)...});
4888 }, __detail::__tuple_transform(ranges::size, _M_views));
4892 template<
typename... _Rs>
4893 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4895 template<
typename... _Views>
4896 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4897 = (enable_borrowed_range<_Views> && ...);
4901 template<
bool _Const,
typename... _Vs>
4902 concept __all_random_access
4903 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4905 template<
bool _Const,
typename... _Vs>
4906 concept __all_bidirectional
4907 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4909 template<
bool _Const,
typename... _Vs>
4910 concept __all_forward
4911 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4913 template<
bool _Const,
typename... _Views>
4914 struct __zip_view_iter_cat
4917 template<
bool _Const,
typename... _Views>
4918 requires __all_forward<_Const, _Views...>
4919 struct __zip_view_iter_cat<_Const, _Views...>
4920 {
using iterator_category = input_iterator_tag; };
4924 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4925 template<bool _Const>
4926 class zip_view<_Vs...>::_Iterator
4927 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4929#ifdef _GLIBCXX_CLANG
4932 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4935 _Iterator(
decltype(_M_current) __current)
4936 : _M_current(std::move(__current))
4942 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4943 return random_access_iterator_tag{};
4944 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4945 return bidirectional_iterator_tag{};
4946 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4947 return forward_iterator_tag{};
4949 return input_iterator_tag{};
4952#ifndef _GLIBCXX_CLANG
4953 template<move_constructible _Fp,
input_range... _Ws>
4954 requires (
view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4955 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4956 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4957 friend class zip_transform_view;
4962 using iterator_concept =
decltype(_S_iter_concept());
4964 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4965 using difference_type
4968 _Iterator() =
default;
4971 _Iterator(_Iterator<!_Const> __i)
4973 && (convertible_to<iterator_t<_Vs>,
4974 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4975 : _M_current(std::move(__i._M_current))
4981 auto __f = [](
auto& __i) ->
decltype(
auto) {
4984 return __detail::__tuple_transform(__f, _M_current);
4987 constexpr _Iterator&
4990 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
5000 requires __detail::__all_forward<_Const, _Vs...>
5007 constexpr _Iterator&
5009 requires __detail::__all_bidirectional<_Const, _Vs...>
5011 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
5017 requires __detail::__all_bidirectional<_Const, _Vs...>
5024 constexpr _Iterator&
5025 operator+=(difference_type __x)
5026 requires __detail::__all_random_access<_Const, _Vs...>
5028 auto __f = [&]<
typename _It>(_It& __i) {
5029 __i += iter_difference_t<_It>(__x);
5031 __detail::__tuple_for_each(__f, _M_current);
5035 constexpr _Iterator&
5036 operator-=(difference_type __x)
5037 requires __detail::__all_random_access<_Const, _Vs...>
5039 auto __f = [&]<
typename _It>(_It& __i) {
5040 __i -= iter_difference_t<_It>(__x);
5042 __detail::__tuple_for_each(__f, _M_current);
5047 operator[](difference_type __n)
const
5048 requires __detail::__all_random_access<_Const, _Vs...>
5050 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
5051 return __i[iter_difference_t<_It>(__n)];
5053 return __detail::__tuple_transform(__f, _M_current);
5056 friend constexpr bool
5057 operator==(
const _Iterator& __x,
const _Iterator& __y)
5058 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5060 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
5061 return __x._M_current == __y._M_current;
5064 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
5068 friend constexpr auto
5069 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5070 requires __detail::__all_random_access<_Const, _Vs...>
5071 {
return __x._M_current <=> __y._M_current; }
5073 friend constexpr _Iterator
5074 operator+(
const _Iterator& __i, difference_type __n)
5075 requires __detail::__all_random_access<_Const, _Vs...>
5082 friend constexpr _Iterator
5083 operator+(difference_type __n,
const _Iterator& __i)
5084 requires __detail::__all_random_access<_Const, _Vs...>
5091 friend constexpr _Iterator
5092 operator-(
const _Iterator& __i, difference_type __n)
5093 requires __detail::__all_random_access<_Const, _Vs...>
5100 friend constexpr difference_type
5101 operator-(
const _Iterator& __x,
const _Iterator& __y)
5102 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
5103 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5106 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
5107 - std::get<_Is>(__y._M_current))...},
5109 [](difference_type __i) {
5110 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5115 friend constexpr auto
5116 iter_move(
const _Iterator& __i)
5117 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5119 friend constexpr void
5120 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5121 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5124 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
5128 friend class zip_view;
5132 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
5133 template<bool _Const>
5134 class zip_view<_Vs...>::_Sentinel
5136 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
5139 _Sentinel(
decltype(_M_end) __end)
5143 friend class zip_view;
5146 _Sentinel() =
default;
5149 _Sentinel(_Sentinel<!_Const> __i)
5151 && (convertible_to<sentinel_t<_Vs>,
5152 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5153 : _M_end(std::move(__i._M_end))
5156 template<
bool _OtherConst>
5157 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5158 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5159 friend constexpr bool
5160 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5163 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
5167 template<
bool _OtherConst>
5168 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5169 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5170 friend constexpr auto
5171 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5176 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
5179 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5184 template<
bool _OtherConst>
5185 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5186 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5187 friend constexpr auto
5188 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5189 {
return -(__x - __y); }
5196 template<
typename... _Ts>
5197 concept __can_zip_view
5203 template<
typename... _Ts>
5204 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5206 operator() [[nodiscard]] (_Ts&&... __ts)
const
5208 if constexpr (
sizeof...(_Ts) == 0)
5209 return views::empty<tuple<>>;
5215 inline constexpr _Zip zip;
5220 template<
typename _Range,
bool _Const>
5221 using __range_iter_cat
5222 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5225 template<move_constructible _Fp,
input_range... _Vs>
5226 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5227 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5228 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5229 class zip_transform_view : public
view_interface<zip_transform_view<_Fp, _Vs...>>
5231 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5232 zip_view<_Vs...> _M_zip;
5234 using _InnerView = zip_view<_Vs...>;
5236 template<
bool _Const>
5237 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5239 template<
bool _Const>
5240 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5242 template<
bool _Const>
5243 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5245 template<
bool _Const>
5249 template<
bool _Const>
5251 struct __iter_cat<_Const>
5257 using __detail::__maybe_const_t;
5258 using __detail::__range_iter_cat;
5259 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5260 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5263 if constexpr (!is_reference_v<_Res>)
5264 return input_iterator_tag{};
5265 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5266 random_access_iterator_tag> && ...))
5267 return random_access_iterator_tag{};
5268 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5269 bidirectional_iterator_tag> && ...))
5270 return bidirectional_iterator_tag{};
5271 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5272 forward_iterator_tag> && ...))
5273 return forward_iterator_tag{};
5275 return input_iterator_tag{};
5278 using iterator_category =
decltype(_S_iter_cat());
5281 template<
bool>
class _Iterator;
5282 template<
bool>
class _Sentinel;
5285 zip_transform_view() =
default;
5288 zip_transform_view(_Fp __fun, _Vs... __views)
5289 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5294 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5298 requires
range<const _InnerView>
5299 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5300 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5306 return _Iterator<false>(*
this, _M_zip.end());
5308 return _Sentinel<false>(_M_zip.end());
5313 requires
range<const _InnerView>
5314 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5317 return _Iterator<true>(*
this, _M_zip.end());
5319 return _Sentinel<true>(_M_zip.end());
5324 {
return _M_zip.size(); }
5328 {
return _M_zip.size(); }
5331 template<
class _Fp,
class... _Rs>
5332 zip_transform_view(_Fp, _Rs&&...)
5333 -> zip_transform_view<_Fp, views::all_t<_Rs>...>;
5335 template<move_constructible _Fp,
input_range... _Vs>
5336 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5337 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5338 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5339 template<bool _Const>
5340 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5342 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5343 using _Fun_handle = __detail::__func_handle_t<
5344 __detail::__maybe_const_t<_Const, _Fp>,
5345 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
5347 [[no_unique_address]] _Fun_handle _M_fun;
5348 __ziperator<_Const> _M_inner;
5351 _Iterator(_Fun_handle __fun, __ziperator<_Const> __inner)
5352 : _M_fun(__fun), _M_inner(std::move(__inner))
5356 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5357 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
5360 friend class zip_transform_view;
5364 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5366 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5367 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5368 using difference_type = range_difference_t<_Base<_Const>>;
5370 _Iterator() =
default;
5373 _Iterator(_Iterator<!_Const> __i)
5374 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5375 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
5378 constexpr decltype(
auto)
5381 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5382 return _M_fun._M_call_deref(__iters...);
5383 }, _M_inner._M_current);
5386 constexpr _Iterator&
5405 constexpr _Iterator&
5420 constexpr _Iterator&
5427 constexpr _Iterator&
5434 constexpr decltype(
auto)
5437 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5438 return _M_fun._M_call_subscript(__n, __iters...);
5439 }, _M_inner._M_current);
5442 friend constexpr bool
5443 operator==(
const _Iterator& __x,
const _Iterator& __y)
5444 requires equality_comparable<__ziperator<_Const>>
5445 {
return __x._M_inner == __y._M_inner; }
5447 friend constexpr auto
5448 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5450 {
return __x._M_inner <=> __y._M_inner; }
5452 friend constexpr _Iterator
5453 operator+(
const _Iterator& __i, difference_type __n)
5455 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5457 friend constexpr _Iterator
5458 operator+(difference_type __n,
const _Iterator& __i)
5460 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5462 friend constexpr _Iterator
5463 operator-(
const _Iterator& __i, difference_type __n)
5465 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
5467 friend constexpr difference_type
5468 operator-(
const _Iterator& __x,
const _Iterator& __y)
5469 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5470 {
return __x._M_inner - __y._M_inner; }
5473 template<move_constructible _Fp,
input_range... _Vs>
5474 requires (
view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5475 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5476 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5477 template<bool _Const>
5478 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5480 __zentinel<_Const> _M_inner;
5483 _Sentinel(__zentinel<_Const> __inner)
5487 friend class zip_transform_view;
5490 _Sentinel() =
default;
5493 _Sentinel(_Sentinel<!_Const> __i)
5494 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5498 template<
bool _OtherConst>
5499 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5500 friend constexpr bool
5501 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5502 {
return __x._M_inner == __y._M_inner; }
5504 template<
bool _OtherConst>
5505 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5506 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5507 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5508 {
return __x._M_inner - __y._M_inner; }
5510 template<
bool _OtherConst>
5511 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5512 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5513 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5514 {
return __x._M_inner - __y._M_inner; }
5521 template<
typename _Fp,
typename... _Ts>
5522 concept __can_zip_transform_view
5526 struct _ZipTransform
5528 template<
typename _Fp>
5529 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5530 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5532 operator() [[nodiscard]] (_Fp&&)
const
5534 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5537 template<
typename _Fp,
typename... _Ts>
5538 requires (
sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5540 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5546 inline constexpr _ZipTransform zip_transform;
5549 template<forward_range _Vp,
size_t _Nm>
5551 class adjacent_view : public
view_interface<adjacent_view<_Vp, _Nm>>
5553 _Vp _M_base = _Vp();
5555 template<
bool>
class _Iterator;
5556 template<
bool>
class _Sentinel;
5558 struct __as_sentinel
5562 adjacent_view()
requires default_initializable<_Vp> = default;
5565 adjacent_view(_Vp __base)
5566 : _M_base(std::move(__base))
5572 base() const & requires copy_constructible<_Vp>
5580 begin()
requires (!__detail::__simple_view<_Vp>)
5581 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5585 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5588 end()
requires (!__detail::__simple_view<_Vp>)
5591 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5593 return _Sentinel<false>(ranges::end(_M_base));
5597 end() const requires
range<const _Vp>
5600 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5602 return _Sentinel<true>(ranges::end(_M_base));
5608 using _ST =
decltype(ranges::size(_M_base));
5610 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5612 return static_cast<_ST
>(__sz);
5618 using _ST =
decltype(ranges::size(_M_base));
5620 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5622 return static_cast<_ST
>(__sz);
5626 template<
typename _Vp,
size_t _Nm>
5627 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5628 = enable_borrowed_range<_Vp>;
5633 template<
typename _Tp,
size_t _Nm>
5634 using __repeated_tuple =
typename __make_tuple<array<_Tp, _Nm>>::__type;
5638 template<
typename _Fp,
size_t _Nm>
5641 template<
typename... _Ts>
5642 static invoke_result_t<_Fp, _Ts...>
5643 __tuple_apply(
const tuple<_Ts...>&);
5645 template<
typename _Tp>
5646 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5651 template<forward_range _Vp,
size_t _Nm>
5653 template<bool _Const>
5654 class adjacent_view<_Vp, _Nm>::_Iterator
5656#ifdef _GLIBCXX_CLANG
5659 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5660 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5663 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5665 for (
auto& __i : _M_current)
5668 ranges::advance(__first, 1, __last);
5673 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5676 for (
auto& __it : _M_current)
5679 for (
size_t __i = 0; __i < _Nm; ++__i)
5681 _M_current[_Nm - 1 - __i] = __last;
5682 ranges::advance(__last, -1, __first);
5690 return random_access_iterator_tag{};
5692 return bidirectional_iterator_tag{};
5694 return forward_iterator_tag{};
5697 friend class adjacent_view;
5699#ifndef _GLIBCXX_CLANG
5700 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5701 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5702 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5703 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5704 range_reference_t<_Wp>>>
5705 friend class adjacent_transform_view;
5709 using iterator_category = input_iterator_tag;
5710 using iterator_concept =
decltype(_S_iter_concept());
5711 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5712 using difference_type = range_difference_t<_Base>;
5714 _Iterator() =
default;
5717 _Iterator(_Iterator<!_Const> __i)
5718 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5720 for (
size_t __j = 0; __j < _Nm; ++__j)
5721 _M_current[__j] =
std::move(__i._M_current[__j]);
5727 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5728 return __detail::__tuple_transform(__f, _M_current);
5731 constexpr _Iterator&
5734 for (
auto& __i : _M_current)
5747 constexpr _Iterator&
5750 for (
auto& __i : _M_current)
5763 constexpr _Iterator&
5764 operator+=(difference_type __x)
5767 for (
auto& __i : _M_current)
5772 constexpr _Iterator&
5773 operator-=(difference_type __x)
5776 for (
auto& __i : _M_current)
5782 operator[](difference_type __n)
const
5785 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5786 return __detail::__tuple_transform(__f, _M_current);
5789 friend constexpr bool
5790 operator==(
const _Iterator& __x,
const _Iterator& __y)
5791 {
return __x._M_current.back() == __y._M_current.back(); }
5793 friend constexpr bool
5794 operator<(
const _Iterator& __x,
const _Iterator& __y)
5796 {
return __x._M_current.back() < __y._M_current.back(); }
5798 friend constexpr bool
5799 operator>(
const _Iterator& __x,
const _Iterator& __y)
5801 {
return __y < __x; }
5803 friend constexpr bool
5804 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5806 {
return !(__y < __x); }
5808 friend constexpr bool
5809 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5811 {
return !(__x < __y); }
5813 friend constexpr auto
5814 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5816 && three_way_comparable<iterator_t<_Base>>
5817 {
return __x._M_current.back() <=> __y._M_current.back(); }
5819 friend constexpr _Iterator
5820 operator+(
const _Iterator& __i, difference_type __n)
5828 friend constexpr _Iterator
5829 operator+(difference_type __n,
const _Iterator& __i)
5837 friend constexpr _Iterator
5838 operator-(
const _Iterator& __i, difference_type __n)
5846 friend constexpr difference_type
5847 operator-(
const _Iterator& __x,
const _Iterator& __y)
5848 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5849 {
return __x._M_current.back() - __y._M_current.back(); }
5851 friend constexpr auto
5852 iter_move(
const _Iterator& __i)
5853 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5855 friend constexpr void
5856 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5857 requires indirectly_swappable<iterator_t<_Base>>
5859 for (
size_t __i = 0; __i < _Nm; __i++)
5860 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5864 template<forward_range _Vp,
size_t _Nm>
5866 template<bool _Const>
5867 class adjacent_view<_Vp, _Nm>::_Sentinel
5869 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5871 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5874 _Sentinel(sentinel_t<_Base> __end)
5878 friend class adjacent_view;
5881 _Sentinel() =
default;
5884 _Sentinel(_Sentinel<!_Const> __i)
5885 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5889 template<
bool _OtherConst>
5890 requires sentinel_for<sentinel_t<_Base>,
5891 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5892 friend constexpr bool
5893 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5894 {
return __x._M_current.back() == __y._M_end; }
5896 template<
bool _OtherConst>
5897 requires sized_sentinel_for<sentinel_t<_Base>,
5898 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5899 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5900 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5901 {
return __x._M_current.back() - __y._M_end; }
5903 template<
bool _OtherConst>
5904 requires sized_sentinel_for<sentinel_t<_Base>,
5905 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5906 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5907 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5908 {
return __y._M_end - __x._M_current.back(); }
5915 template<
size_t _Nm,
typename _Range>
5916 concept __can_adjacent_view
5920 template<
size_t _Nm>
5921 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5925 template<viewable_range _Range>
5926 requires ((_Nm == 0) && forward_range<_Range>)
5927 || __detail::__can_adjacent_view<_Nm, _Range>
5929 operator() [[nodiscard]] (_Range&& __r)
const
5931 if constexpr (_Nm == 0)
5932 return views::empty<tuple<>>;
5938 template<
size_t _Nm>
5939 inline constexpr _Adjacent<_Nm> adjacent;
5941 inline constexpr auto pairwise = adjacent<2>;
5944 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5945 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5946 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5947 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5948 range_reference_t<_Vp>>>
5949 class adjacent_transform_view : public
view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5951 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5952 adjacent_view<_Vp, _Nm> _M_inner;
5954 using _InnerView = adjacent_view<_Vp, _Nm>;
5956 template<
bool _Const>
5957 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5959 template<
bool _Const>
5960 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5962 template<
bool>
class _Iterator;
5963 template<
bool>
class _Sentinel;
5966 adjacent_transform_view() =
default;
5969 adjacent_transform_view(_Vp __base, _Fp __fun)
5970 : _M_fun(std::move(__fun)), _M_inner(std::move(
__base))
5977 base() const & requires copy_constructible<_Vp>
5978 {
return _M_inner.base(); }
5986 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5990 requires
range<const _InnerView>
5991 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5992 range_reference_t<const _Vp>>
5993 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5999 return _Iterator<false>(*
this, _M_inner.end());
6001 return _Sentinel<false>(_M_inner.end());
6006 requires
range<const _InnerView>
6007 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
6008 range_reference_t<const _Vp>>
6011 return _Iterator<true>(*
this, _M_inner.end());
6013 return _Sentinel<true>(_M_inner.end());
6018 {
return _M_inner.size(); }
6022 {
return _M_inner.size(); }
6025 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6026 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6027 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6028 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6029 range_reference_t<_Vp>>>
6030 template<bool _Const>
6031 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
6033 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
6034 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6036 return __detail::__func_handle_t<
6037 __detail::__maybe_const_t<_Const, _Fp>,
6038 iterator_t<__detail::__maybe_const_t<(_Ids, _Const), _Vp>>...>();
6041 [[no_unique_address]] _Fun_handle _M_fun;
6042 _InnerIter<_Const> _M_inner;
6045 _Iterator(_Fun_handle __fun, _InnerIter<_Const> __inner)
6046 : _M_fun(__fun), _M_inner(std::move(__inner))
6050 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
6051 : _M_fun(*__parent._M_fun), _M_inner(std::move(__inner))
6057 using __detail::__maybe_const_t;
6058 using __detail::__unarize;
6059 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
6060 range_reference_t<_Base>>;
6061 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
6064 if constexpr (!is_reference_v<_Res>)
6065 return input_iterator_tag{};
6066 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
6067 return random_access_iterator_tag{};
6068 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
6069 return bidirectional_iterator_tag{};
6070 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
6071 return forward_iterator_tag{};
6073 return input_iterator_tag{};
6076 friend class adjacent_transform_view;
6079 using iterator_category =
decltype(_S_iter_cat());
6080 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
6082 = remove_cvref_t<invoke_result_t
6083 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
6084 range_reference_t<_Base>>>;
6085 using difference_type = range_difference_t<_Base>;
6087 _Iterator() =
default;
6090 _Iterator(_Iterator<!_Const> __i)
6091 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
6092 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
6095 constexpr decltype(
auto)
6098 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6099 return _M_fun._M_call_deref(__iters...);
6100 }, _M_inner._M_current);
6103 constexpr _Iterator&
6118 constexpr _Iterator&
6133 constexpr _Iterator&
6140 constexpr _Iterator&
6147 constexpr decltype(
auto)
6150 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6151 return _M_fun._M_call_subscript(__n, __iters...);
6152 }, _M_inner._M_current);
6155 friend constexpr bool
6156 operator==(
const _Iterator& __x,
const _Iterator& __y)
6157 {
return __x._M_inner == __y._M_inner; }
6159 friend constexpr bool
6160 operator<(
const _Iterator& __x,
const _Iterator& __y)
6162 {
return __x._M_inner < __y._M_inner; }
6164 friend constexpr bool
6165 operator>(
const _Iterator& __x,
const _Iterator& __y)
6167 {
return __x._M_inner > __y._M_inner; }
6169 friend constexpr bool
6170 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6172 {
return __x._M_inner <= __y._M_inner; }
6174 friend constexpr bool
6175 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6177 {
return __x._M_inner >= __y._M_inner; }
6179 friend constexpr auto
6180 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6182 three_way_comparable<_InnerIter<_Const>>
6183 {
return __x._M_inner <=> __y._M_inner; }
6185 friend constexpr _Iterator
6186 operator+(
const _Iterator& __i, difference_type __n)
6188 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6190 friend constexpr _Iterator
6191 operator+(difference_type __n,
const _Iterator& __i)
6193 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6195 friend constexpr _Iterator
6196 operator-(
const _Iterator& __i, difference_type __n)
6198 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
6200 friend constexpr difference_type
6201 operator-(
const _Iterator& __x,
const _Iterator& __y)
6202 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
6203 {
return __x._M_inner - __y._M_inner; }
6206 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6207 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6208 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6209 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6210 range_reference_t<_Vp>>>
6211 template<bool _Const>
6212 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6214 _InnerSent<_Const> _M_inner;
6217 _Sentinel(_InnerSent<_Const> __inner)
6221 friend class adjacent_transform_view;
6224 _Sentinel() =
default;
6227 _Sentinel(_Sentinel<!_Const> __i)
6228 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6232 template<
bool _OtherConst>
6233 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6234 friend constexpr bool
6235 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6236 {
return __x._M_inner == __y._M_inner; }
6238 template<
bool _OtherConst>
6239 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6240 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6241 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6242 {
return __x._M_inner - __y._M_inner; }
6244 template<
bool _OtherConst>
6245 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6246 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6247 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
6248 {
return __x._M_inner - __y._M_inner; }
6255 template<
size_t _Nm,
typename _Range,
typename _Fp>
6256 concept __can_adjacent_transform_view
6257 =
requires { adjacent_transform_view<all_t<_Range>,
decay_t<_Fp>, _Nm>
6261 template<
size_t _Nm>
6262 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6266 template<viewable_range _Range,
typename _Fp>
6267 requires ((_Nm == 0) && forward_range<_Range>)
6268 || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6270 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
6272 if constexpr (_Nm == 0)
6275 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6279 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6280 static constexpr int _S_arity = 2;
6281 static constexpr bool _S_has_simple_extra_args =
true;
6284 template<
size_t _Nm>
6285 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6287 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6291#ifdef __cpp_lib_ranges_chunk
6294 template<
typename _Tp>
6295 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6297 _Tp __r = __num / __denom;
6298 if (__num % __denom)
6309 range_difference_t<_Vp> _M_n;
6310 range_difference_t<_Vp> _M_remainder = 0;
6311 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6318 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6319 : _M_base(std::move(
__base)), _M_n(__n)
6320 { __glibcxx_assert(__n >= 0); }
6323 base() const & requires copy_constructible<_Vp>
6330 constexpr _OuterIter
6333 _M_current = ranges::begin(_M_base);
6334 _M_remainder = _M_n;
6335 return _OuterIter(*
this);
6338 constexpr default_sentinel_t
6339 end() const noexcept
6343 size()
requires sized_range<_Vp>
6345 return __detail::__to_unsigned_like(__detail::__div_ceil
6346 (ranges::distance(_M_base), _M_n));
6350 size() const requires sized_range<const _Vp>
6352 return __detail::__to_unsigned_like(__detail::__div_ceil
6353 (ranges::distance(_M_base), _M_n));
6357 template<
typename _Range>
6358 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6362 class chunk_view<_Vp>::_OuterIter
6364 chunk_view* _M_parent;
6367 _OuterIter(chunk_view& __parent) noexcept
6374 using iterator_concept = input_iterator_tag;
6375 using difference_type = range_difference_t<_Vp>;
6379 _OuterIter(_OuterIter&&) =
default;
6380 _OuterIter& operator=(_OuterIter&&) =
default;
6382 constexpr value_type
6385 __glibcxx_assert(*
this != default_sentinel);
6386 return value_type(*_M_parent);
6389 constexpr _OuterIter&
6392 __glibcxx_assert(*
this != default_sentinel);
6393 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6394 ranges::end(_M_parent->_M_base));
6395 _M_parent->_M_remainder = _M_parent->_M_n;
6403 friend constexpr bool
6404 operator==(
const _OuterIter& __x, default_sentinel_t)
6406 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6407 && __x._M_parent->_M_remainder != 0;
6410 friend constexpr difference_type
6411 operator-(default_sentinel_t,
const _OuterIter& __x)
6412 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6414 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6416 if (__dist < __x._M_parent->_M_remainder)
6417 return __dist == 0 ? 0 : 1;
6419 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6420 __x._M_parent->_M_n);
6423 friend constexpr difference_type
6424 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6425 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6426 {
return -(__y - __x); }
6431 struct chunk_view<_Vp>::_OuterIter::value_type :
view_interface<value_type>
6434 chunk_view* _M_parent;
6437 value_type(chunk_view& __parent) noexcept
6444 constexpr _InnerIter
6445 begin() const noexcept
6446 {
return _InnerIter(*_M_parent); }
6448 constexpr default_sentinel_t
6449 end() const noexcept
6454 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6456 return __detail::__to_unsigned_like
6457 (ranges::min(_M_parent->_M_remainder,
6458 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6464 class chunk_view<_Vp>::_InnerIter
6466 chunk_view* _M_parent;
6469 _InnerIter(chunk_view& __parent) noexcept
6473 friend _OuterIter::value_type;
6476 using iterator_concept = input_iterator_tag;
6477 using difference_type = range_difference_t<_Vp>;
6478 using value_type = range_value_t<_Vp>;
6480 _InnerIter(_InnerIter&&) =
default;
6481 _InnerIter& operator=(_InnerIter&&) =
default;
6483 constexpr const iterator_t<_Vp>&
6485 {
return *_M_parent->_M_current; }
6487 constexpr range_reference_t<_Vp>
6490 __glibcxx_assert(*
this != default_sentinel);
6491 return **_M_parent->_M_current;
6494 constexpr _InnerIter&
6497 __glibcxx_assert(*
this != default_sentinel);
6498 ++*_M_parent->_M_current;
6499 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6500 _M_parent->_M_remainder = 0;
6502 --_M_parent->_M_remainder;
6510 friend constexpr bool
6511 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6512 {
return __x._M_parent->_M_remainder == 0; }
6514 friend constexpr difference_type
6515 operator-(default_sentinel_t,
const _InnerIter& __x)
6516 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6518 return ranges::min(__x._M_parent->_M_remainder,
6519 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6522 friend constexpr difference_type
6523 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6524 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6525 {
return -(__y - __x); }
6529 friend constexpr range_rvalue_reference_t<_Vp>
6530 iter_move(
const _InnerIter& __i)
6531 noexcept(
noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6532 {
return ranges::iter_move(*__i._M_parent->_M_current); }
6534 friend constexpr void
6535 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
6536 noexcept(
noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6537 *__x._M_parent->_M_current)))
6538 requires indirectly_swappable<iterator_t<_Vp>>
6539 {
return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6547 range_difference_t<_Vp> _M_n;
6548 template<
bool>
class _Iterator;
6552 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6553 : _M_base(std::move(
__base)), _M_n(__n)
6554 { __glibcxx_assert(__n > 0); }
6557 base() const & requires copy_constructible<_Vp>
6565 begin()
requires (!__detail::__simple_view<_Vp>)
6566 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6569 begin() const requires forward_range<const _Vp>
6570 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6573 end()
requires (!__detail::__simple_view<_Vp>)
6575 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6577 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6578 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6580 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6581 return _Iterator<false>(
this, ranges::end(_M_base));
6587 end() const requires forward_range<const _Vp>
6589 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6591 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6592 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6594 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6595 return _Iterator<true>(
this, ranges::end(_M_base));
6601 size()
requires sized_range<_Vp>
6603 return __detail::__to_unsigned_like(__detail::__div_ceil
6604 (ranges::distance(_M_base), _M_n));
6608 size() const requires sized_range<const _Vp>
6610 return __detail::__to_unsigned_like(__detail::__div_ceil
6611 (ranges::distance(_M_base), _M_n));
6615 template<
typename _Vp>
6616 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6621 template<
bool _Const>
6622 class chunk_view<_Vp>::_Iterator
6624 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6625 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6627 iterator_t<_Base> _M_current = iterator_t<_Base>();
6628 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6629 range_difference_t<_Base> _M_n = 0;
6630 range_difference_t<_Base> _M_missing = 0;
6633 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6634 range_difference_t<_Base> __missing = 0)
6635 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6636 _M_n(__parent->_M_n), _M_missing(__missing)
6642 if constexpr (random_access_range<_Base>)
6643 return random_access_iterator_tag{};
6644 else if constexpr (bidirectional_range<_Base>)
6645 return bidirectional_iterator_tag{};
6647 return forward_iterator_tag{};
6653 using iterator_category = input_iterator_tag;
6654 using iterator_concept =
decltype(_S_iter_cat());
6655 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6656 using difference_type = range_difference_t<_Base>;
6658 _Iterator() =
default;
6660 constexpr _Iterator(_Iterator<!_Const> __i)
6662 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6663 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6665 _M_n(__i._M_n), _M_missing(__i._M_missing)
6668 constexpr iterator_t<_Base>
6670 {
return _M_current; }
6672 constexpr value_type
6675 __glibcxx_assert(_M_current != _M_end);
6676 return views::take(subrange(_M_current, _M_end), _M_n);
6679 constexpr _Iterator&
6682 __glibcxx_assert(_M_current != _M_end);
6683 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6695 constexpr _Iterator&
6696 operator--()
requires bidirectional_range<_Base>
6698 ranges::advance(_M_current, _M_missing - _M_n);
6704 operator--(
int)
requires bidirectional_range<_Base>
6711 constexpr _Iterator&
6712 operator+=(difference_type __x)
6713 requires random_access_range<_Base>
6717 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6718 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6722 ranges::advance(_M_current, _M_n * __x + _M_missing);
6728 constexpr _Iterator&
6729 operator-=(difference_type __x)
6730 requires random_access_range<_Base>
6731 {
return *
this += -__x; }
6733 constexpr value_type
6734 operator[](difference_type __n)
const
6735 requires random_access_range<_Base>
6736 {
return *(*
this + __n); }
6738 friend constexpr bool
6739 operator==(
const _Iterator& __x,
const _Iterator& __y)
6740 {
return __x._M_current == __y._M_current; }
6742 friend constexpr bool
6743 operator==(
const _Iterator& __x, default_sentinel_t)
6744 {
return __x._M_current == __x._M_end; }
6746 friend constexpr bool
6747 operator<(
const _Iterator& __x,
const _Iterator& __y)
6748 requires random_access_range<_Base>
6749 {
return __x._M_current > __y._M_current; }
6751 friend constexpr bool
6752 operator>(
const _Iterator& __x,
const _Iterator& __y)
6753 requires random_access_range<_Base>
6754 {
return __y < __x; }
6756 friend constexpr bool
6757 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6758 requires random_access_range<_Base>
6759 {
return !(__y < __x); }
6761 friend constexpr bool
6762 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6763 requires random_access_range<_Base>
6764 {
return !(__x < __y); }
6766 friend constexpr auto
6767 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6768 requires random_access_range<_Base>
6769 && three_way_comparable<iterator_t<_Base>>
6770 {
return __x._M_current <=> __y._M_current; }
6772 friend constexpr _Iterator
6773 operator+(
const _Iterator& __i, difference_type __n)
6774 requires random_access_range<_Base>
6781 friend constexpr _Iterator
6782 operator+(difference_type __n,
const _Iterator& __i)
6783 requires random_access_range<_Base>
6790 friend constexpr _Iterator
6791 operator-(
const _Iterator& __i, difference_type __n)
6792 requires random_access_range<_Base>
6799 friend constexpr difference_type
6800 operator-(
const _Iterator& __x,
const _Iterator& __y)
6801 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6803 return (__x._M_current - __y._M_current
6804 + __x._M_missing - __y._M_missing) / __x._M_n;
6807 friend constexpr difference_type
6808 operator-(default_sentinel_t,
const _Iterator& __x)
6809 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6810 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6812 friend constexpr difference_type
6813 operator-(
const _Iterator& __x, default_sentinel_t __y)
6814 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6815 {
return -(__y - __x); }
6822 template<
typename _Range,
typename _Dp>
6823 concept __can_chunk_view
6827 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6829 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6830 requires __detail::__can_chunk_view<_Range, _Dp>
6832 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6835 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6836 static constexpr int _S_arity = 2;
6837 static constexpr bool _S_has_simple_extra_args =
true;
6840 inline constexpr _Chunk chunk;
6844#ifdef __cpp_lib_ranges_slide
6847 template<
typename _Vp>
6848 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6850 template<
typename _Vp>
6851 concept __slide_caches_last
6852 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6854 template<
typename _Vp>
6855 concept __slide_caches_first
6856 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6859 template<forward_range _Vp>
6864 range_difference_t<_Vp> _M_n;
6865 [[no_unique_address]]
6866 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6867 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6868 [[no_unique_address]]
6869 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6870 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6872 template<
bool>
class _Iterator;
6877 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6878 : _M_base(std::move(
__base)), _M_n(__n)
6879 { __glibcxx_assert(__n > 0); }
6884 base() const & requires copy_constructible<_Vp>
6892 begin()
requires (!(__detail::__simple_view<_Vp>
6893 && __detail::__slide_caches_nothing<const _Vp>))
6895 if constexpr (__detail::__slide_caches_first<_Vp>)
6897 iterator_t<_Vp> __it;
6898 if (_M_cached_begin._M_has_value())
6899 __it = _M_cached_begin._M_get(_M_base);
6902 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6903 _M_cached_begin._M_set(_M_base, __it);
6905 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6908 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6912 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6913 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6916 end()
requires (!(__detail::__simple_view<_Vp>
6917 && __detail::__slide_caches_nothing<const _Vp>))
6919 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6920 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6922 else if constexpr (__detail::__slide_caches_last<_Vp>)
6924 iterator_t<_Vp> __it;
6925 if (_M_cached_end._M_has_value())
6926 __it = _M_cached_end._M_get(_M_base);
6929 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6930 _M_cached_end._M_set(_M_base, __it);
6932 return _Iterator<false>(
std::move(__it), _M_n);
6934 else if constexpr (common_range<_Vp>)
6935 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6937 return _Sentinel(ranges::end(_M_base));
6941 end() const requires __detail::__slide_caches_nothing<const _Vp>
6942 {
return begin() + range_difference_t<const _Vp>(size()); }
6945 size()
requires sized_range<_Vp>
6947 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6950 return __detail::__to_unsigned_like(__sz);
6954 size() const requires sized_range<const _Vp>
6956 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6959 return __detail::__to_unsigned_like(__sz);
6963 template<
typename _Range>
6964 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6966 template<
typename _Vp>
6967 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6968 = enable_borrowed_range<_Vp>;
6970 template<forward_range _Vp>
6972 template<
bool _Const>
6973 class slide_view<_Vp>::_Iterator
6975 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6976 static constexpr bool _S_last_elt_present
6977 = __detail::__slide_caches_first<_Base>;
6979 iterator_t<_Base> _M_current = iterator_t<_Base>();
6980 [[no_unique_address]]
6981 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6982 _M_last_elt =
decltype(_M_last_elt)();
6983 range_difference_t<_Base> _M_n = 0;
6986 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6987 requires (!_S_last_elt_present)
6988 : _M_current(__current), _M_n(__n)
6992 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6993 range_difference_t<_Base> __n)
6994 requires _S_last_elt_present
6995 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
7001 if constexpr (random_access_range<_Base>)
7002 return random_access_iterator_tag{};
7003 else if constexpr (bidirectional_range<_Base>)
7004 return bidirectional_iterator_tag{};
7006 return forward_iterator_tag{};
7010 friend slide_view::_Sentinel;
7013 using iterator_category = input_iterator_tag;
7014 using iterator_concept =
decltype(_S_iter_concept());
7015 using value_type =
decltype(views::counted(_M_current, _M_n));
7016 using difference_type = range_difference_t<_Base>;
7018 _Iterator() =
default;
7021 _Iterator(_Iterator<!_Const> __i)
7022 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7023 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
7028 {
return views::counted(_M_current, _M_n); }
7030 constexpr _Iterator&
7034 if constexpr (_S_last_elt_present)
7047 constexpr _Iterator&
7048 operator--()
requires bidirectional_range<_Base>
7051 if constexpr (_S_last_elt_present)
7057 operator--(
int)
requires bidirectional_range<_Base>
7064 constexpr _Iterator&
7065 operator+=(difference_type __x)
7066 requires random_access_range<_Base>
7069 if constexpr (_S_last_elt_present)
7074 constexpr _Iterator&
7075 operator-=(difference_type __x)
7076 requires random_access_range<_Base>
7079 if constexpr (_S_last_elt_present)
7085 operator[](difference_type __n)
const
7086 requires random_access_range<_Base>
7087 {
return views::counted(_M_current + __n, _M_n); }
7089 friend constexpr bool
7090 operator==(
const _Iterator& __x,
const _Iterator& __y)
7092 if constexpr (_S_last_elt_present)
7093 return __x._M_last_elt == __y._M_last_elt;
7095 return __x._M_current == __y._M_current;
7098 friend constexpr bool
7099 operator<(
const _Iterator& __x,
const _Iterator& __y)
7100 requires random_access_range<_Base>
7101 {
return __x._M_current < __y._M_current; }
7103 friend constexpr bool
7104 operator>(
const _Iterator& __x,
const _Iterator& __y)
7105 requires random_access_range<_Base>
7106 {
return __y < __x; }
7108 friend constexpr bool
7109 operator<=(
const _Iterator& __x,
const _Iterator& __y)
7110 requires random_access_range<_Base>
7111 {
return !(__y < __x); }
7113 friend constexpr bool
7114 operator>=(
const _Iterator& __x,
const _Iterator& __y)
7115 requires random_access_range<_Base>
7116 {
return !(__x < __y); }
7118 friend constexpr auto
7119 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7120 requires random_access_range<_Base>
7121 && three_way_comparable<iterator_t<_Base>>
7122 {
return __x._M_current <=> __y._M_current; }
7124 friend constexpr _Iterator
7125 operator+(
const _Iterator& __i, difference_type __n)
7126 requires random_access_range<_Base>
7133 friend constexpr _Iterator
7134 operator+(difference_type __n,
const _Iterator& __i)
7135 requires random_access_range<_Base>
7142 friend constexpr _Iterator
7143 operator-(
const _Iterator& __i, difference_type __n)
7144 requires random_access_range<_Base>
7151 friend constexpr difference_type
7152 operator-(
const _Iterator& __x,
const _Iterator& __y)
7153 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7155 if constexpr (_S_last_elt_present)
7156 return __x._M_last_elt - __y._M_last_elt;
7158 return __x._M_current - __y._M_current;
7162 template<forward_range _Vp>
7164 class slide_view<_Vp>::_Sentinel
7166 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
7169 _Sentinel(sentinel_t<_Vp> __end)
7176 _Sentinel() =
default;
7178 friend constexpr bool
7179 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
7180 {
return __x._M_last_elt == __y._M_end; }
7182 friend constexpr range_difference_t<_Vp>
7183 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
7184 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7185 {
return __x._M_last_elt - __y._M_end; }
7187 friend constexpr range_difference_t<_Vp>
7188 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
7189 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7190 {
return __y._M_end -__x._M_last_elt; }
7197 template<
typename _Range,
typename _Dp>
7198 concept __can_slide_view
7202 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
7204 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
7205 requires __detail::__can_slide_view<_Range, _Dp>
7207 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
7210 using __adaptor::_RangeAdaptor<_Slide>::operator();
7211 static constexpr int _S_arity = 2;
7212 static constexpr bool _S_has_simple_extra_args =
true;
7215 inline constexpr _Slide slide;
7219#ifdef __cpp_lib_ranges_chunk_by
7221 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7222 requires view<_Vp> && is_object_v<_Pred>
7223 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
7225 _Vp _M_base = _Vp();
7226 __detail::__box<_Pred> _M_pred;
7227 __detail::_CachedPosition<_Vp> _M_cached_begin;
7229 constexpr iterator_t<_Vp>
7230 _M_find_next(iterator_t<_Vp> __current)
7232 __glibcxx_assert(_M_pred.has_value());
7233 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7236 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7237 return ranges::next(__it, 1, ranges::end(_M_base));
7240 constexpr iterator_t<_Vp>
7241 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
7243 __glibcxx_assert(_M_pred.has_value());
7244 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7249 __glibcxx_assert(__rbegin != __rend);
7250 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7251 return ranges::prev(__it, 1, ranges::begin(_M_base));
7257 chunk_by_view()
requires (default_initializable<_Vp>
7258 && default_initializable<_Pred>)
7262 chunk_by_view(_Vp __base, _Pred __pred)
7263 : _M_base(std::move(
__base)), _M_pred(std::move(__pred))
7267 base() const & requires copy_constructible<_Vp>
7274 constexpr const _Pred&
7276 {
return *_M_pred; }
7281 __glibcxx_assert(_M_pred.has_value());
7282 iterator_t<_Vp> __it;
7283 if (_M_cached_begin._M_has_value())
7284 __it = _M_cached_begin._M_get(_M_base);
7287 __it = _M_find_next(ranges::begin(_M_base));
7288 _M_cached_begin._M_set(_M_base, __it);
7290 return _Iterator(*
this, ranges::begin(_M_base), __it);
7296 if constexpr (common_range<_Vp>)
7297 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
7303 template<
typename _Range,
typename _Pred>
7304 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7307 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7308 requires view<_Vp> && is_object_v<_Pred>
7309 class chunk_by_view<_Vp, _Pred>::_Iterator
7311 chunk_by_view* _M_parent =
nullptr;
7312 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7313 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7316 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7317 : _M_parent(std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7323 if constexpr (bidirectional_range<_Vp>)
7324 return bidirectional_iterator_tag{};
7326 return forward_iterator_tag{};
7329 friend chunk_by_view;
7332 using value_type = subrange<iterator_t<_Vp>>;
7333 using difference_type = range_difference_t<_Vp>;
7334 using iterator_category = input_iterator_tag;
7335 using iterator_concept =
decltype(_S_iter_concept());
7337 _Iterator() =
default;
7339 constexpr value_type
7342 __glibcxx_assert(_M_current != _M_next);
7343 return ranges::subrange(_M_current, _M_next);
7346 constexpr _Iterator&
7349 __glibcxx_assert(_M_current != _M_next);
7350 _M_current = _M_next;
7351 _M_next = _M_parent->_M_find_next(_M_current);
7363 constexpr _Iterator&
7364 operator--()
requires bidirectional_range<_Vp>
7366 _M_next = _M_current;
7367 _M_current = _M_parent->_M_find_prev(_M_next);
7372 operator--(
int)
requires bidirectional_range<_Vp>
7379 friend constexpr bool
7380 operator==(
const _Iterator& __x,
const _Iterator& __y)
7381 {
return __x._M_current == __y._M_current; }
7383 friend constexpr bool
7384 operator==(
const _Iterator& __x, default_sentinel_t)
7385 {
return __x._M_current == __x._M_next; }
7392 template<
typename _Range,
typename _Pred>
7393 concept __can_chunk_by_view
7397 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7399 template<viewable_range _Range,
typename _Pred>
7400 requires __detail::__can_chunk_by_view<_Range, _Pred>
7402 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7405 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7406 static constexpr int _S_arity = 2;
7407 static constexpr bool _S_has_simple_extra_args =
true;
7410 inline constexpr _ChunkBy chunk_by;
7414#ifdef __cpp_lib_ranges_join_with
7417 template<
typename _Range>
7418 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7422 template<
typename... _Rs>
7425 template<
typename... _Rs>
7428 template<
typename... _Rs>
7429 using __concat_rvalue_reference_t
7432 template<
typename _Ref,
typename _RRef,
typename _It>
7433 concept __concat_indirectly_readable_impl =
requires(
const _It __it) {
7434 { *__it } -> convertible_to<_Ref>;
7435 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
7438 template<
typename... _Rs>
7439 concept __concat_indirectly_readable
7440 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
7441 && common_reference_with<__concat_reference_t<_Rs...>&&,
7442 __concat_rvalue_reference_t<_Rs...>&&>
7443 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
7444 __concat_value_t<_Rs...>
const&>
7445 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
7446 __concat_rvalue_reference_t<_Rs...>,
7450 template<
typename... _Rs>
7451 concept __concatable =
requires {
7452 typename __concat_reference_t<_Rs...>;
7453 typename __concat_value_t<_Rs...>;
7454 typename __concat_rvalue_reference_t<_Rs...>;
7455 } && __concat_indirectly_readable<_Rs...>;
7458 template<input_range _Vp, forward_range _Pattern>
7461 && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
7462 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7464 using _InnerRange = range_reference_t<_Vp>;
7466 _Vp _M_base = _Vp();
7467 [[no_unique_address]]
7468 __detail::__maybe_present_t<!forward_range<_Vp>,
7469 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7470 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7471 _Pattern _M_pattern = _Pattern();
7473 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7474 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7475 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7477 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7478 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7479 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7481 template<
bool _Const>
7482 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7484 template<
bool _Const>
7488 template<
bool _Const>
7489 requires _S_ref_is_glvalue<_Const>
7490 && forward_range<_Base<_Const>>
7491 && forward_range<_InnerBase<_Const>>
7492 struct __iter_cat<_Const>
7498 using _OuterIter = join_with_view::_OuterIter<_Const>;
7499 using _InnerIter = join_with_view::_InnerIter<_Const>;
7500 using _PatternIter = join_with_view::_PatternIter<_Const>;
7501 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7502 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7503 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7506 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7507 iter_reference_t<_PatternIter>>>)
7508 return input_iterator_tag{};
7509 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7510 && derived_from<_InnerCat, bidirectional_iterator_tag>
7511 && derived_from<_PatternCat, bidirectional_iterator_tag>
7512 && common_range<_InnerBase<_Const>>
7513 && common_range<_PatternBase<_Const>>)
7514 return bidirectional_iterator_tag{};
7515 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7516 && derived_from<_InnerCat, forward_iterator_tag>
7517 && derived_from<_PatternCat, forward_iterator_tag>)
7518 return forward_iterator_tag{};
7520 return input_iterator_tag{};
7523 using iterator_category =
decltype(_S_iter_cat());
7526 template<
bool>
class _Iterator;
7527 template<
bool>
class _Sentinel;
7530 join_with_view()
requires (default_initializable<_Vp>
7531 && default_initializable<_Pattern>)
7535 join_with_view(_Vp __base, _Pattern __pattern)
7536 : _M_base(std::move(
__base)), _M_pattern(std::move(__pattern))
7539 template<input_range _Range>
7540 requires constructible_from<_Vp, views::all_t<_Range>>
7541 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7543 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7544 : _M_base(views::all(std::
forward<_Range>(__r))),
7545 _M_pattern(views::single(std::move(__e)))
7549 base() const& requires copy_constructible<_Vp>
7559 if constexpr (forward_range<_Vp>)
7561 constexpr bool __use_const = is_reference_v<_InnerRange>
7562 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7563 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7567 _M_outer_it = ranges::begin(_M_base);
7568 return _Iterator<false>{*
this};
7574 requires forward_range<const _Vp>
7575 && forward_range<const _Pattern>
7576 && is_reference_v<range_reference_t<const _Vp>>
7577 && input_range<range_reference_t<const _Vp>>
7578 && __detail::__concatable<range_reference_t<const _Vp>, const _Pattern>
7579 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7584 constexpr bool __use_const
7585 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7586 if constexpr (is_reference_v<_InnerRange>
7587 && forward_range<_Vp> && common_range<_Vp>
7588 && forward_range<_InnerRange> && common_range<_InnerRange>)
7589 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7591 return _Sentinel<__use_const>{*
this};
7596 requires forward_range<const _Vp>
7597 && forward_range<const _Pattern>
7598 && is_reference_v<range_reference_t<const _Vp>>
7599 && input_range<range_reference_t<const _Vp>>
7600 && __detail::__concatable<range_reference_t<const _Vp>, const _Pattern>
7602 using _InnerConstRange = range_reference_t<const _Vp>;
7603 if constexpr (forward_range<_InnerConstRange>
7604 && common_range<const _Vp>
7605 && common_range<_InnerConstRange>)
7606 return _Iterator<true>{*
this, ranges::end(_M_base)};
7608 return _Sentinel<true>{*
this};
7612 template<
typename _Range,
typename _Pattern>
7613 join_with_view(_Range&&, _Pattern&&)
7614 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7616 template<input_range _Range>
7617 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7618 -> join_with_view<views::all_t<_Range>,
7621 template<input_range _Vp, forward_range _Pattern>
7624 && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
7625 template<
bool _Const>
7626 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7628 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7629 using _Base = join_with_view::_Base<_Const>;
7630 using _InnerBase = join_with_view::_InnerBase<_Const>;
7631 using _PatternBase = join_with_view::_PatternBase<_Const>;
7633 using _OuterIter = join_with_view::_OuterIter<_Const>;
7634 using _InnerIter = join_with_view::_InnerIter<_Const>;
7635 using _PatternIter = join_with_view::_PatternIter<_Const>;
7637 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7639 _Parent* _M_parent =
nullptr;
7640 [[no_unique_address]]
7641 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7642 =
decltype(_M_outer_it)();
7643 variant<_PatternIter, _InnerIter> _M_inner_it;
7645 constexpr _OuterIter&
7648 if constexpr (forward_range<_Base>)
7651 return *_M_parent->_M_outer_it;
7654 constexpr const _OuterIter&
7655 _M_get_outer()
const
7657 if constexpr (forward_range<_Base>)
7660 return *_M_parent->_M_outer_it;
7664 _Iterator(_Parent& __parent, _OuterIter __outer)
7665 requires forward_range<_Base>
7668 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7670 auto&& __inner = _M_update_inner();
7671 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7677 _Iterator(_Parent& __parent)
7678 requires (!forward_range<_Base>)
7681 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7683 auto&& __inner = _M_update_inner();
7684 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7692 _OuterIter& __outer = _M_get_outer();
7693 if constexpr (_S_ref_is_glvalue)
7694 return __detail::__as_lvalue(*__outer);
7696 return _M_parent->_M_inner._M_emplace_deref(__outer);
7702 if constexpr (_S_ref_is_glvalue)
7703 return __detail::__as_lvalue(*_M_get_outer());
7705 return *_M_parent->_M_inner;
7713 if (_M_inner_it.index() == 0)
7715 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7718 auto&& __inner = _M_update_inner();
7719 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7723 auto&& __inner = _M_get_inner();
7724 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7727 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7729 if constexpr (_S_ref_is_glvalue)
7730 _M_inner_it.template emplace<0>();
7734 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7742 if constexpr (_S_ref_is_glvalue
7743 && bidirectional_range<_Base>
7744 && __detail::__bidirectional_common<_InnerBase>
7745 && __detail::__bidirectional_common<_PatternBase>)
7746 return bidirectional_iterator_tag{};
7747 else if constexpr (_S_ref_is_glvalue
7748 && forward_range<_Base>
7749 && forward_range<_InnerBase>)
7750 return forward_iterator_tag{};
7752 return input_iterator_tag{};
7755 friend join_with_view;
7758 using iterator_concept =
decltype(_S_iter_concept());
7760 using value_type = common_type_t<iter_value_t<_InnerIter>,
7761 iter_value_t<_PatternIter>>;
7762 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7763 iter_difference_t<_InnerIter>,
7764 iter_difference_t<_PatternIter>>;
7766 _Iterator() =
default;
7769 _Iterator(_Iterator<!_Const> __i)
7771 && convertible_to<iterator_t<_Vp>, _OuterIter>
7772 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7773 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7774 : _M_parent(__i._M_parent),
7777 if (__i._M_inner_it.index() == 0)
7778 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7780 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7783 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7784 iter_reference_t<_PatternIter>>
7787 if (_M_inner_it.index() == 0)
7788 return *std::get<0>(_M_inner_it);
7790 return *std::get<1>(_M_inner_it);
7793 constexpr _Iterator&
7796 if (_M_inner_it.index() == 0)
7797 ++std::get<0>(_M_inner_it);
7799 ++std::get<1>(_M_inner_it);
7810 requires _S_ref_is_glvalue
7811 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7813 _Iterator __tmp = *
this;
7818 constexpr _Iterator&
7820 requires _S_ref_is_glvalue
7821 && bidirectional_range<_Base>
7822 && __detail::__bidirectional_common<_InnerBase>
7823 && __detail::__bidirectional_common<_PatternBase>
7825 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7827 auto&& __inner = *--_M_outer_it;
7828 _M_inner_it.template emplace<1>(ranges::end(__inner));
7833 if (_M_inner_it.index() == 0)
7835 auto& __it = std::get<0>(_M_inner_it);
7836 if (__it == ranges::begin(_M_parent->_M_pattern))
7838 auto&& __inner = *--_M_outer_it;
7839 _M_inner_it.template emplace<1>(ranges::end(__inner));
7846 auto& __it = std::get<1>(_M_inner_it);
7847 auto&& __inner = *_M_outer_it;
7848 if (__it == ranges::begin(__inner))
7849 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7855 if (_M_inner_it.index() == 0)
7856 --std::get<0>(_M_inner_it);
7858 --std::get<1>(_M_inner_it);
7864 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7865 && __detail::__bidirectional_common<_InnerBase>
7866 && __detail::__bidirectional_common<_PatternBase>
7868 _Iterator __tmp = *
this;
7873 friend constexpr bool
7874 operator==(
const _Iterator& __x,
const _Iterator& __y)
7875 requires _S_ref_is_glvalue
7876 && forward_range<_Base> && equality_comparable<_InnerIter>
7877 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7879 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7880 iter_rvalue_reference_t<_PatternIter>>
7881 iter_move(
const _Iterator& __x)
7883 if (__x._M_inner_it.index() == 0)
7884 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7886 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7889 friend constexpr void
7890 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7891 requires indirectly_swappable<_InnerIter, _PatternIter>
7893 if (__x._M_inner_it.index() == 0)
7895 if (__y._M_inner_it.index() == 0)
7896 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7898 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7902 if (__y._M_inner_it.index() == 0)
7903 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7905 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7910 template<input_range _Vp, forward_range _Pattern>
7913 && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
7914 template<
bool _Const>
7915 class join_with_view<_Vp, _Pattern>::_Sentinel
7917 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7918 using _Base = join_with_view::_Base<_Const>;
7920 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7923 _Sentinel(_Parent& __parent)
7924 : _M_end(ranges::end(__parent._M_base))
7927 friend join_with_view;
7930 _Sentinel() =
default;
7933 _Sentinel(_Sentinel<!_Const> __s)
7934 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7938 template<
bool _OtherConst>
7939 requires sentinel_for<sentinel_t<_Base>,
7940 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7941 friend constexpr bool
7942 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7943 {
return __x._M_get_outer() == __y._M_end; }
7950 template<
typename _Range,
typename _Pattern>
7951 concept __can_join_with_view
7955 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7957 template<viewable_range _Range,
typename _Pattern>
7958 requires __detail::__can_join_with_view<_Range, _Pattern>
7960 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7965 using _RangeAdaptor<_JoinWith>::operator();
7966 static constexpr int _S_arity = 2;
7967 template<
typename _Pattern>
7968 static constexpr bool _S_has_simple_extra_args
7969 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7972 inline constexpr _JoinWith join_with;
7976#ifdef __cpp_lib_ranges_repeat
7977 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7978 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7979 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7980 class repeat_view : public
view_interface<repeat_view<_Tp, _Bound>>
7982 [[no_unique_address]] __detail::__box<_Tp> _M_value;
7983 [[no_unique_address]] _Bound _M_bound = _Bound();
7987 template<
typename _Range>
7988 friend constexpr auto
7989 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7991 template<
typename _Range>
7992 friend constexpr auto
7993 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7996 repeat_view()
requires default_initializable<_Tp> = default;
7999 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
8000 requires copy_constructible<_Tp>
8001 : _M_value(__value), _M_bound(__bound)
8003 if constexpr (__detail::__is_signed_integer_like<_Bound>)
8004 __glibcxx_assert(__bound >= 0);
8008 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
8009 : _M_value(std::move(__value)), _M_bound(__bound)
8011 if constexpr (__detail::__is_signed_integer_like<_Bound>)
8012 __glibcxx_assert(__bound >= 0);
8015 template<
typename... _Args,
typename... _BoundArgs>
8016 requires constructible_from<_Tp, _Args...>
8017 && constructible_from<_Bound, _BoundArgs...>
8019 repeat_view(piecewise_construct_t,
8020 tuple<_Args...> __args,
8021 tuple<_BoundArgs...> __bound_args = tuple<>{})
8022 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
8023 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
8025 if constexpr (__detail::__is_signed_integer_like<_Bound>)
8026 __glibcxx_assert(_M_bound >= 0);
8034 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
8037 constexpr unreachable_sentinel_t
8038 end() const noexcept
8039 {
return unreachable_sentinel; }
8042 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
8043 {
return __detail::__to_unsigned_like(_M_bound); }
8048 template<
typename _Tp,
typename _Bound = unreachable_sentinel_t>
8049 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
8051 template<move_constructible _Tp, semiregular _Bound>
8052 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
8053 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
8054 class repeat_view<_Tp, _Bound>::_Iterator
8057 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
8059 const _Tp* _M_value =
nullptr;
8060 __index_type _M_current = __index_type();
8063 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
8064 : _M_value(__value), _M_current(__bound)
8066 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8067 __glibcxx_assert(__bound >= 0);
8073 using iterator_concept = random_access_iterator_tag;
8074 using iterator_category = random_access_iterator_tag;
8075 using value_type = _Tp;
8076 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
8078 __detail::__iota_diff_t<__index_type>>;
8080 _Iterator() =
default;
8082 constexpr const _Tp&
8084 {
return *_M_value; }
8086 constexpr _Iterator&
8101 constexpr _Iterator&
8104 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8105 __glibcxx_assert(_M_current > 0);
8118 constexpr _Iterator&
8119 operator+=(difference_type __n)
8121 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8122 __glibcxx_assert(_M_current + __n >= 0);
8127 constexpr _Iterator&
8128 operator-=(difference_type __n)
8130 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8131 __glibcxx_assert(_M_current - __n >= 0);
8136 constexpr const _Tp&
8137 operator[](difference_type __n)
const noexcept
8138 {
return *(*
this + __n); }
8140 friend constexpr bool
8141 operator==(
const _Iterator& __x,
const _Iterator& __y)
8142 {
return __x._M_current == __y._M_current; }
8144 friend constexpr auto
8145 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8146 {
return __x._M_current <=> __y._M_current; }
8148 friend constexpr _Iterator
8149 operator+(_Iterator __i, difference_type __n)
8155 friend constexpr _Iterator
8156 operator+(difference_type __n, _Iterator __i)
8157 {
return __i + __n; }
8159 friend constexpr _Iterator
8160 operator-(_Iterator __i, difference_type __n)
8166 friend constexpr difference_type
8167 operator-(
const _Iterator& __x,
const _Iterator& __y)
8169 return (
static_cast<difference_type
>(__x._M_current)
8170 -
static_cast<difference_type
>(__y._M_current));
8178 template<
typename _Tp,
typename _Bound>
8179 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
8181 template<
typename _Tp>
8182 concept __can_repeat_view
8185 template<
typename _Tp,
typename _Bound>
8186 concept __can_bounded_repeat_view
8192 template<
typename _Tp>
8193 requires __detail::__can_repeat_view<_Tp>
8195 operator() [[nodiscard]] (_Tp&& __value)
const
8202 template<
typename _Tp,
typename _Bound>
8203 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
8205 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
8209 inline constexpr _Repeat repeat;
8213 template<
typename _Range>
8215 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8217 using _Tp = remove_cvref_t<_Range>;
8218 static_assert(__is_repeat_view<_Tp>);
8219 if constexpr (sized_range<_Tp>)
8221 std::min(ranges::distance(__r), __n));
8226 template<
typename _Range>
8228 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8230 using _Tp = remove_cvref_t<_Range>;
8231 static_assert(__is_repeat_view<_Tp>);
8232 if constexpr (sized_range<_Tp>)
8234 auto __sz = ranges::distance(__r);
8245#ifdef __cpp_lib_ranges_stride
8246 template<input_range _Vp>
8251 range_difference_t<_Vp> _M_stride;
8253 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8255 template<
bool _Const>
8259 template<
bool _Const>
8260 requires forward_range<_Base<_Const>>
8261 struct __iter_cat<_Const>
8267 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8268 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8269 return random_access_iterator_tag{};
8274 using iterator_category =
decltype(_S_iter_cat());
8277 template<
bool>
class _Iterator;
8281 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8282 : _M_base(std::move(
__base)), _M_stride(__stride)
8283 { __glibcxx_assert(__stride > 0); }
8286 base() const& requires copy_constructible<_Vp>
8293 constexpr range_difference_t<_Vp>
8294 stride() const noexcept
8295 {
return _M_stride; }
8298 begin()
requires (!__detail::__simple_view<_Vp>)
8299 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
8302 begin() const requires range<const _Vp>
8303 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
8306 end()
requires (!__detail::__simple_view<_Vp>)
8308 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8310 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8311 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
8313 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8314 return _Iterator<false>(
this, ranges::end(_M_base));
8320 end() const requires range<const _Vp>
8322 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8323 && forward_range<const _Vp>)
8325 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8326 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
8328 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8329 return _Iterator<true>(
this, ranges::end(_M_base));
8335 size()
requires sized_range<_Vp>
8337 return __detail::__to_unsigned_like
8338 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8342 size() const requires sized_range<const _Vp>
8344 return __detail::__to_unsigned_like
8345 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8349 template<
typename _Range>
8350 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8352 template<
typename _Vp>
8353 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8354 = enable_borrowed_range<_Vp>;
8356 template<input_range _Vp>
8358 template<
bool _Const>
8359 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8361 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8362 using _Base = stride_view::_Base<_Const>;
8364 iterator_t<_Base> _M_current = iterator_t<_Base>();
8365 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8366 range_difference_t<_Base> _M_stride = 0;
8367 range_difference_t<_Base> _M_missing = 0;
8370 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8371 range_difference_t<_Base> __missing = 0)
8372 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8373 _M_stride(__parent->_M_stride), _M_missing(__missing)
8379 if constexpr (random_access_range<_Base>)
8380 return random_access_iterator_tag{};
8381 else if constexpr (bidirectional_range<_Base>)
8382 return bidirectional_iterator_tag{};
8383 else if constexpr (forward_range<_Base>)
8384 return forward_iterator_tag{};
8386 return input_iterator_tag{};
8392 using difference_type = range_difference_t<_Base>;
8393 using value_type = range_value_t<_Base>;
8394 using iterator_concept =
decltype(_S_iter_concept());
8397 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8400 _Iterator(_Iterator<!_Const> __other)
8402 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8403 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8404 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8405 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8408 constexpr iterator_t<_Base>
8412 constexpr const iterator_t<_Base>&
8413 base() const & noexcept
8414 {
return _M_current; }
8416 constexpr decltype(
auto)
8418 {
return *_M_current; }
8420 constexpr _Iterator&
8423 __glibcxx_assert(_M_current != _M_end);
8424 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8433 operator++(
int)
requires forward_range<_Base>
8440 constexpr _Iterator&
8441 operator--()
requires bidirectional_range<_Base>
8443 ranges::advance(_M_current, _M_missing - _M_stride);
8449 operator--(
int)
requires bidirectional_range<_Base>
8456 constexpr _Iterator&
8457 operator+=(difference_type __n)
requires random_access_range<_Base>
8461 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8462 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8466 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8472 constexpr _Iterator&
8473 operator-=(difference_type __n)
requires random_access_range<_Base>
8474 {
return *
this += -__n; }
8476 constexpr decltype(
auto)
operator[](difference_type __n)
const
8477 requires random_access_range<_Base>
8478 {
return *(*
this + __n); }
8480 friend constexpr bool
8481 operator==(
const _Iterator& __x, default_sentinel_t)
8482 {
return __x._M_current == __x._M_end; }
8484 friend constexpr bool
8485 operator==(
const _Iterator& __x,
const _Iterator& __y)
8486 requires equality_comparable<iterator_t<_Base>>
8487 {
return __x._M_current == __y._M_current; }
8489 friend constexpr bool
8490 operator<(
const _Iterator& __x,
const _Iterator& __y)
8491 requires random_access_range<_Base>
8492 {
return __x._M_current < __y._M_current; }
8494 friend constexpr bool
8495 operator>(
const _Iterator& __x,
const _Iterator& __y)
8496 requires random_access_range<_Base>
8497 {
return __y._M_current < __x._M_current; }
8499 friend constexpr bool
8500 operator<=(
const _Iterator& __x,
const _Iterator& __y)
8501 requires random_access_range<_Base>
8502 {
return !(__y._M_current < __x._M_current); }
8504 friend constexpr bool
8505 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8506 requires random_access_range<_Base>
8507 {
return !(__x._M_current < __y._M_current); }
8509 friend constexpr auto
8510 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8511 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8512 {
return __x._M_current <=> __y._M_current; }
8514 friend constexpr _Iterator
8515 operator+(
const _Iterator& __i, difference_type __n)
8516 requires random_access_range<_Base>
8523 friend constexpr _Iterator
8524 operator+(difference_type __n,
const _Iterator& __i)
8525 requires random_access_range<_Base>
8526 {
return __i + __n; }
8528 friend constexpr _Iterator
8529 operator-(
const _Iterator& __i, difference_type __n)
8530 requires random_access_range<_Base>
8537 friend constexpr difference_type
8538 operator-(
const _Iterator& __x,
const _Iterator& __y)
8539 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8541 auto __n = __x._M_current - __y._M_current;
8542 if constexpr (forward_range<_Base>)
8543 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8545 return -__detail::__div_ceil(-__n, __x._M_stride);
8547 return __detail::__div_ceil(__n, __x._M_stride);
8550 friend constexpr difference_type
8551 operator-(default_sentinel_t,
const _Iterator& __x)
8552 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8553 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8555 friend constexpr difference_type
8556 operator-(
const _Iterator& __x, default_sentinel_t __y)
8557 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8558 {
return -(__y - __x); }
8560 friend constexpr range_rvalue_reference_t<_Base>
8561 iter_move(
const _Iterator& __i)
8562 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8563 {
return ranges::iter_move(__i._M_current); }
8565 friend constexpr void
8566 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8567 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8568 requires indirectly_swappable<iterator_t<_Base>>
8569 { ranges::iter_swap(__x._M_current, __y._M_current); }
8576 template<
typename _Range,
typename _Dp>
8577 concept __can_stride_view
8581 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8583 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8584 requires __detail::__can_stride_view<_Range, _Dp>
8586 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8589 using __adaptor::_RangeAdaptor<_Stride>::operator();
8590 static constexpr int _S_arity = 2;
8591 static constexpr bool _S_has_simple_extra_args =
true;
8594 inline constexpr _Stride stride;
8598#ifdef __cpp_lib_ranges_cartesian_product
8601 template<
bool _Const,
typename _First,
typename... _Vs>
8602 concept __cartesian_product_is_random_access
8603 = (random_access_range<__maybe_const_t<_Const, _First>>
8605 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8606 && sized_range<__maybe_const_t<_Const, _Vs>>));
8608 template<
typename _Range>
8609 concept __cartesian_product_common_arg
8610 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8612 template<
bool _Const,
typename _First,
typename... _Vs>
8613 concept __cartesian_product_is_bidirectional
8614 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8616 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8617 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8619 template<
typename _First,
typename... _Vs>
8620 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8622 template<
typename... _Vs>
8623 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8625 template<
bool _Const,
template<
typename>
class _FirstSent,
8626 typename _First,
typename... _Vs>
8627 concept __cartesian_is_sized_sentinel
8628 = (sized_sentinel_for<_FirstSent<__maybe_const_t<_Const, _First>>,
8629 iterator_t<__maybe_const_t<_Const, _First>>>
8631 && (sized_range<__maybe_const_t<_Const, _Vs>>
8632 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8633 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8635 template<__cartesian_product_common_arg _Range>
8637 __cartesian_common_arg_end(_Range& __r)
8639 if constexpr (common_range<_Range>)
8640 return ranges::end(__r);
8642 return ranges::begin(__r) + ranges::distance(__r);
8648 class cartesian_product_view : public
view_interface<cartesian_product_view<_First, _Vs...>>
8650 tuple<_First, _Vs...> _M_bases;
8652 template<
bool>
class _Iterator;
8655 _S_difference_type()
8661 range_difference_t<_First>,
8662 range_difference_t<_Vs>...>{};
8666 cartesian_product_view() =
default;
8669 cartesian_product_view(_First __first, _Vs... __rest)
8670 : _M_bases(std::move(__first), std::move(__rest)...)
8673 constexpr _Iterator<false>
8674 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8675 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8677 constexpr _Iterator<true>
8678 begin() const requires (
range<const _First> && ... &&
range<const _Vs>)
8679 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8681 constexpr _Iterator<false>
8682 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8683 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8686 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8687 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8688 auto& __first = std::get<0>(_M_bases);
8689 return _Ret{(__empty_tail
8690 ? ranges::begin(__first)
8691 : __detail::__cartesian_common_arg_end(__first)),
8692 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8695 return _Iterator<false>{*
this,
std::move(__its)};
8698 constexpr _Iterator<true>
8699 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8702 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8703 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8704 auto& __first = std::get<0>(_M_bases);
8705 return _Ret{(__empty_tail
8706 ? ranges::begin(__first)
8707 : __detail::__cartesian_common_arg_end(__first)),
8708 ranges::
begin(std::get<1 + _Is>(_M_bases))...};
8711 return _Iterator<true>{*
this,
std::move(__its)};
8714 constexpr default_sentinel_t
8715 end() const noexcept
8719 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8721 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8723 auto __size =
static_cast<_ST
>(1);
8724#ifdef _GLIBCXX_ASSERTIONS
8725 if constexpr (integral<_ST>)
8728 = (__builtin_mul_overflow(__size,
8729 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8732 __glibcxx_assert(!__overflow);
8736 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8742 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8744 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8746 auto __size =
static_cast<_ST
>(1);
8747#ifdef _GLIBCXX_ASSERTIONS
8748 if constexpr (integral<_ST>)
8751 = (__builtin_mul_overflow(__size,
8752 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8755 __glibcxx_assert(!__overflow);
8759 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8765 template<
typename... _Vs>
8766 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8770 template<bool _Const>
8771 class cartesian_product_view<_First, _Vs...>::_Iterator
8773 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8774 _Parent* _M_parent =
nullptr;
8775 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8776 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8779 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8781 _M_current(std::move(__current))
8787 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8788 return random_access_iterator_tag{};
8789 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8790 return bidirectional_iterator_tag{};
8792 return forward_iterator_tag{};
8794 return input_iterator_tag{};
8797 friend cartesian_product_view;
8800 using iterator_category = input_iterator_tag;
8801 using iterator_concept =
decltype(_S_iter_concept());
8803 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8804 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8806 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8807 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8808 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8810 _Iterator() =
default;
8813 _Iterator(_Iterator<!_Const> __i)
8815 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8816 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8818 _M_current(std::move(__i._M_current))
8824 auto __f = [](
auto& __i) ->
decltype(
auto) {
8827 return __detail::__tuple_transform(__f, _M_current);
8830 constexpr _Iterator&
8849 constexpr _Iterator&
8851 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8859 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8866 constexpr _Iterator&
8867 operator+=(difference_type __x)
8868 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8874 constexpr _Iterator&
8875 operator-=(difference_type __x)
8876 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8877 {
return *
this += -__x; }
8880 operator[](difference_type __n)
const
8881 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8882 {
return *((*this) + __n); }
8884 friend constexpr bool
8885 operator==(
const _Iterator& __x,
const _Iterator& __y)
8886 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8887 {
return __x._M_current == __y._M_current; }
8889 friend constexpr bool
8890 operator==(
const _Iterator& __x, default_sentinel_t)
8893 return ((std::get<_Is>(__x._M_current)
8894 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8899 friend constexpr auto
8900 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8901 requires __detail::__all_random_access<_Const, _First, _Vs...>
8902 {
return __x._M_current <=> __y._M_current; }
8904 friend constexpr _Iterator
8905 operator+(_Iterator __x, difference_type __y)
8906 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8907 {
return __x += __y; }
8909 friend constexpr _Iterator
8910 operator+(difference_type __x, _Iterator __y)
8911 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8912 {
return __y += __x; }
8914 friend constexpr _Iterator
8915 operator-(_Iterator __x, difference_type __y)
8916 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8917 {
return __x -= __y; }
8919 friend constexpr difference_type
8920 operator-(
const _Iterator& __x,
const _Iterator& __y)
8921 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8922 {
return __x._M_distance_from(__y._M_current); }
8924 friend constexpr difference_type
8925 operator-(
const _Iterator& __i, default_sentinel_t)
8926 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8929 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8930 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8932 return __i._M_distance_from(__end_tuple);
8935 friend constexpr difference_type
8936 operator-(default_sentinel_t,
const _Iterator& __i)
8937 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8940 friend constexpr auto
8941 iter_move(
const _Iterator& __i)
8942 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8944 friend constexpr void
8945 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8946 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8948 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8951 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8956 template<
size_t _Nm =
sizeof...(_Vs)>
8960 auto& __it = std::get<_Nm>(_M_current);
8962 if constexpr (_Nm > 0)
8963 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8965 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8970 template<
size_t _Nm =
sizeof...(_Vs)>
8974 auto& __it = std::get<_Nm>(_M_current);
8975 if constexpr (_Nm > 0)
8976 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8978 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8984 template<
size_t _Nm =
sizeof...(_Vs)>
8986 _M_advance(difference_type __x)
8987 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8996 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8997 auto& __it = std::get<_Nm>(_M_current);
8998 if constexpr (_Nm == 0)
9000#ifdef _GLIBCXX_ASSERTIONS
9003 auto __size = ranges::ssize(__r);
9004 auto __begin = ranges::begin(__r);
9005 auto __offset = __it - __begin;
9006 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
9013 auto __size = ranges::ssize(__r);
9014 auto __begin = ranges::begin(__r);
9015 auto __offset = __it - __begin;
9017 __x = __offset / __size;
9021 __offset = __size + __offset;
9024 __it = __begin + __offset;
9025 _M_advance<_Nm - 1>(__x);
9030 template<
typename _Tuple>
9031 constexpr difference_type
9032 _M_distance_from(
const _Tuple& __t)
const
9035 auto __sum =
static_cast<difference_type
>(0);
9036#ifdef _GLIBCXX_ASSERTIONS
9037 if constexpr (integral<difference_type>)
9040 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
9042 __glibcxx_assert(!__overflow);
9046 __sum = (_M_scaled_distance<_Is>(__t) + ...);
9051 template<
size_t _Nm,
typename _Tuple>
9052 constexpr difference_type
9053 _M_scaled_distance(
const _Tuple& __t)
const
9055 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
9056 - std::get<_Nm>(__t));
9057#ifdef _GLIBCXX_ASSERTIONS
9058 if constexpr (integral<difference_type>)
9060 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
9061 __glibcxx_assert(!__overflow);
9065 __dist *= _M_scaled_size<_Nm+1>();
9069 template<
size_t _Nm>
9070 constexpr difference_type
9071 _M_scaled_size()
const
9073 if constexpr (_Nm <=
sizeof...(_Vs))
9075 auto __size =
static_cast<difference_type
>(ranges::size
9076 (std::get<_Nm>(_M_parent->_M_bases)));
9077#ifdef _GLIBCXX_ASSERTIONS
9078 if constexpr (integral<difference_type>)
9080 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
9081 __glibcxx_assert(!__overflow);
9085 __size *= _M_scaled_size<_Nm+1>();
9089 return static_cast<difference_type
>(1);
9097 template<
typename... _Ts>
9098 concept __can_cartesian_product_view
9102 struct _CartesianProduct
9104 template<
typename... _Ts>
9105 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
9107 operator() [[nodiscard]] (_Ts&&... __ts)
const
9109 if constexpr (
sizeof...(_Ts) == 0)
9110 return views::single(tuple{});
9116 inline constexpr _CartesianProduct cartesian_product;
9120#ifdef __cpp_lib_ranges_as_rvalue
9121 template<input_range _Vp>
9123 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
9125 _Vp _M_base = _Vp();
9128 as_rvalue_view()
requires default_initializable<_Vp> = default;
9131 as_rvalue_view(_Vp __base)
9132 : _M_base(std::move(__base))
9136 base() const& requires copy_constructible<_Vp>
9144 begin()
requires (!__detail::__simple_view<_Vp>)
9145 {
return move_iterator(ranges::begin(_M_base)); }
9148 begin() const requires range<const _Vp>
9149 {
return move_iterator(ranges::begin(_M_base)); }
9152 end()
requires (!__detail::__simple_view<_Vp>)
9154 if constexpr (common_range<_Vp>)
9155 return move_iterator(ranges::end(_M_base));
9157 return move_sentinel(ranges::end(_M_base));
9161 end() const requires range<const _Vp>
9163 if constexpr (common_range<const _Vp>)
9164 return move_iterator(ranges::end(_M_base));
9166 return move_sentinel(ranges::end(_M_base));
9170 size()
requires sized_range<_Vp>
9171 {
return ranges::size(_M_base); }
9174 size() const requires sized_range<const _Vp>
9175 {
return ranges::size(_M_base); }
9178 template<
typename _Range>
9179 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
9181 template<
typename _Tp>
9182 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
9183 = enable_borrowed_range<_Tp>;
9189 template<
typename _Tp>
9190 concept __can_as_rvalue_view =
requires { as_rvalue_view(
std::declval<_Tp>()); };
9193 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
9195 template<viewable_range _Range>
9196 requires __detail::__can_as_rvalue_view<_Range>
9198 operator() [[nodiscard]] (_Range&& __r)
const
9203 if constexpr (same_as<range_rvalue_reference_t<_Range>,
9204 range_reference_t<_Range>>)
9211 inline constexpr _AsRvalue as_rvalue;
9215#ifdef __cpp_lib_ranges_enumerate
9218 template<
typename _Range>
9219 concept __range_with_movable_reference = input_range<_Range>
9220 && move_constructible<range_reference_t<_Range>>
9221 && move_constructible<range_rvalue_reference_t<_Range>>;
9225 requires __detail::__range_with_movable_reference<_Vp>
9226 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
9228 _Vp _M_base = _Vp();
9230 template<
bool _Const>
class _Iterator;
9231 template<
bool _Const>
class _Sentinel;
9234 enumerate_view()
requires default_initializable<_Vp> = default;
9237 enumerate_view(_Vp __base)
9238 : _M_base(std::move(__base))
9242 begin()
requires (!__detail::__simple_view<_Vp>)
9243 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
9246 begin() const requires __detail::__range_with_movable_reference<const _Vp>
9247 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
9250 end()
requires (!__detail::__simple_view<_Vp>)
9252 if constexpr (common_range<_Vp> && sized_range<_Vp>)
9253 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
9255 return _Sentinel<false>(ranges::end(_M_base));
9259 end() const requires __detail::__range_with_movable_reference<const _Vp>
9261 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9262 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9264 return _Sentinel<true>(ranges::end(_M_base));
9268 size()
requires sized_range<_Vp>
9269 {
return ranges::size(_M_base); }
9272 size() const requires sized_range<const _Vp>
9273 {
return ranges::size(_M_base); }
9276 base() const & requires copy_constructible<_Vp>
9284 template<
typename _Range>
9285 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9287 template<
typename _Tp>
9288 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9289 = enable_borrowed_range<_Tp>;
9292 requires __detail::__range_with_movable_reference<_Vp>
9293 template<
bool _Const>
9294 class enumerate_view<_Vp>::_Iterator
9296 using _Base = __maybe_const_t<_Const, _Vp>;
9301 if constexpr (random_access_range<_Base>)
9302 return random_access_iterator_tag{};
9303 else if constexpr (bidirectional_range<_Base>)
9304 return bidirectional_iterator_tag{};
9305 else if constexpr (forward_range<_Base>)
9306 return forward_iterator_tag{};
9308 return input_iterator_tag{};
9311 friend enumerate_view;
9314 using iterator_category = input_iterator_tag;
9315 using iterator_concept =
decltype(_S_iter_concept());
9316 using difference_type = range_difference_t<_Base>;
9317 using value_type = tuple<difference_type, range_value_t<_Base>>;
9320 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9322 iterator_t<_Base> _M_current = iterator_t<_Base>();
9323 difference_type _M_pos = 0;
9326 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9327 : _M_current(std::move(__current)), _M_pos(__pos)
9331 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
9334 _Iterator(_Iterator<!_Const> __i)
9335 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9336 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9339 constexpr const iterator_t<_Base> &
9340 base() const & noexcept
9341 {
return _M_current; }
9343 constexpr iterator_t<_Base>
9347 constexpr difference_type
9348 index() const noexcept
9353 {
return __reference_type(_M_pos, *_M_current); }
9355 constexpr _Iterator&
9368 operator++(
int)
requires forward_range<_Base>
9375 constexpr _Iterator&
9376 operator--()
requires bidirectional_range<_Base>
9384 operator--(
int)
requires bidirectional_range<_Base>
9391 constexpr _Iterator&
9392 operator+=(difference_type __n)
requires random_access_range<_Base>
9399 constexpr _Iterator&
9400 operator-=(difference_type __n)
requires random_access_range<_Base>
9408 operator[](difference_type __n)
const requires random_access_range<_Base>
9409 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9411 friend constexpr bool
9412 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9413 {
return __x._M_pos == __y._M_pos; }
9415 friend constexpr strong_ordering
9416 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9417 {
return __x._M_pos <=> __y._M_pos; }
9419 friend constexpr _Iterator
9420 operator+(
const _Iterator& __x, difference_type __y)
9421 requires random_access_range<_Base>
9422 {
return (
auto(__x) += __y); }
9424 friend constexpr _Iterator
9425 operator+(difference_type __x,
const _Iterator& __y)
9426 requires random_access_range<_Base>
9427 {
return auto(__y) += __x; }
9429 friend constexpr _Iterator
9430 operator-(
const _Iterator& __x, difference_type __y)
9431 requires random_access_range<_Base>
9432 {
return auto(__x) -= __y; }
9434 friend constexpr difference_type
9435 operator-(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9436 {
return __x._M_pos - __y._M_pos; }
9438 friend constexpr auto
9439 iter_move(
const _Iterator& __i)
9440 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9441 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9443 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9444 (__i._M_pos, ranges::iter_move(__i._M_current));
9449 requires __detail::__range_with_movable_reference<_Vp>
9450 template<
bool _Const>
9451 class enumerate_view<_Vp>::_Sentinel
9453 using _Base = __maybe_const_t<_Const, _Vp>;
9455 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9458 _Sentinel(sentinel_t<_Base> __end)
9459 : _M_end(std::move(__end))
9462 friend enumerate_view;
9465 _Sentinel() =
default;
9468 _Sentinel(_Sentinel<!_Const> __other)
9469 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9473 constexpr sentinel_t<_Base>
9477 template<
bool _OtherConst>
9478 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9479 friend constexpr bool
9480 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9481 {
return __x._M_current == __y._M_end; }
9483 template<
bool _OtherConst>
9484 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9485 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9486 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9487 {
return __x._M_current - __y._M_end; }
9489 template<
bool _OtherConst>
9490 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9491 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9492 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9493 {
return __x._M_end - __y._M_current; }
9500 template<
typename _Tp>
9501 concept __can_enumerate_view
9505 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9507 template<viewable_range _Range>
9508 requires __detail::__can_enumerate_view<_Range>
9510 operator() [[nodiscard]] (_Range&& __r)
const
9514 inline constexpr _Enumerate enumerate;
9518#ifdef __cpp_lib_ranges_as_const
9523 _Vp _M_base = _Vp();
9526 as_const_view()
requires default_initializable<_Vp> = default;
9529 as_const_view(_Vp __base)
9530 noexcept(is_nothrow_move_constructible_v<_Vp>)
9531 : _M_base(std::move(__base))
9536 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9537 requires copy_constructible<_Vp>
9542 noexcept(is_nothrow_move_constructible_v<_Vp>)
9546 begin()
requires (!__detail::__simple_view<_Vp>)
9547 {
return ranges::cbegin(_M_base); }
9550 begin() const requires range<const _Vp>
9551 {
return ranges::cbegin(_M_base); }
9554 end()
requires (!__detail::__simple_view<_Vp>)
9555 {
return ranges::cend(_M_base); }
9558 end() const requires range<const _Vp>
9559 {
return ranges::cend(_M_base); }
9562 size()
requires sized_range<_Vp>
9563 {
return ranges::size(_M_base); }
9566 size() const requires sized_range<const _Vp>
9567 {
return ranges::size(_M_base); }
9570 template<
typename _Range>
9571 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9573 template<
typename _Tp>
9574 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9575 = enable_borrowed_range<_Tp>;
9581 template<
typename _Tp>
9582 inline constexpr bool __is_constable_ref_view =
false;
9584 template<
typename _Range>
9585 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9586 = constant_range<const _Range>;
9588 template<
typename _Range>
9592 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9594 template<viewable_range _Range>
9596 operator()(_Range&& __r)
const
9598 requires __detail::__can_as_const_view<_Range>
9600 using _Tp = remove_cvref_t<_Range>;
9601 using element_type = remove_reference_t<range_reference_t<_Range>>;
9602 if constexpr (constant_range<views::all_t<_Range>>)
9604 else if constexpr (__detail::__is_empty_view<_Tp>)
9605 return views::empty<const element_type>;
9606#if __cpp_lib_optional >= 202506L && __cpp_lib_optional_range_support
9607 else if constexpr (__is_optional_ref_v<_Tp>)
9608 return optional<const typename _Tp::value_type&>(__r);
9610 else if constexpr (std::__detail::__is_span<_Tp>)
9612 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9614 else if constexpr (is_lvalue_reference_v<_Range>
9615 && constant_range<const _Tp>
9617 return ref_view(
static_cast<const _Tp&
>(__r));
9623 inline constexpr _AsConst as_const;
9628 namespace views = ranges::views;
9630#if __cpp_lib_ranges_to_container
9636 template<
typename _Container>
9637 constexpr bool __reservable_container
9638 = sized_range<_Container>
9639 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9641 { __c.capacity() } -> same_as<
decltype(__n)>;
9642 { __c.max_size() } -> same_as<
decltype(__n)>;
9645 template<
typename _Cont,
typename _Range>
9646 constexpr bool __toable =
requires {
9647 requires (!input_range<_Cont>
9648 || convertible_to<range_reference_t<_Range>,
9649 range_value_t<_Cont>>);
9670 template<
typename _Cont, input_range _Rg,
typename... _Args>
9671 requires (!view<_Cont>)
9673 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9675 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9676 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9678 if constexpr (__detail::__toable<_Cont, _Rg>)
9680 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9683 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9686 else if constexpr (
requires {
requires common_range<_Rg>;
9687 typename __iter_category_t<iterator_t<_Rg>>;
9688 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9689 input_iterator_tag>;
9690 requires constructible_from<_Cont, iterator_t<_Rg>,
9691 sentinel_t<_Rg>, _Args...>;
9693 return _Cont(ranges::begin(__r), ranges::end(__r),
9697 static_assert(constructible_from<_Cont, _Args...>);
9699 if constexpr (sized_range<_Rg>
9700 && __detail::__reservable_container<_Cont>)
9701 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9705 auto __it = ranges::begin(__r);
9706 const auto __sent = ranges::end(__r);
9707 while (__it != __sent)
9709 if constexpr (
requires { __c.emplace_back(*__it); })
9710 __c.emplace_back(*__it);
9711 else if constexpr (
requires { __c.push_back(*__it); })
9712 __c.push_back(*__it);
9713 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9714 __c.emplace(__c.end(), *__it);
9716 __c.insert(__c.end(), *__it);
9724 static_assert(input_range<range_reference_t<_Rg>>);
9727 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9728 []<
typename _Elt>(_Elt&& __elem) {
9729 using _ValT = range_value_t<_Cont>;
9738 template<
typename _Rg>
9741 using iterator_category = input_iterator_tag;
9742 using value_type = range_value_t<_Rg>;
9743 using difference_type = ptrdiff_t;
9744 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9745 using reference = range_reference_t<_Rg>;
9747 pointer operator->()
const;
9748 _InputIter& operator++();
9749 _InputIter operator++(
int);
9750 bool operator==(
const _InputIter&)
const;
9753 template<
template<
typename...>
typename _Cont, input_range _Rg,
9758 template<
template<
typename...>
typename _Cont, input_range _Rg,
9764 template<
template<
typename...>
typename _Cont, input_range _Rg,
9774 template<
template<
typename...>
typename _Cont, input_range _Rg,
9777 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9779 using __detail::_DeduceExpr1;
9780 using __detail::_DeduceExpr2;
9781 using __detail::_DeduceExpr3;
9782 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9783 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9785 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9786 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9788 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9789 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9792 static_assert(
false);
9798 template<
typename _Cont>
9801 template<
typename _Range,
typename... _Args>
9805 operator()(_Range&& __r, _Args&&... __args)
const
9829 template<
typename _Cont,
typename... _Args>
9830 requires (!view<_Cont>)
9832 to [[nodiscard]] (_Args&&... __args)
9834 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9835 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9837 using __detail::_To;
9838 using views::__adaptor::_Partial;
9845 template<
template<
typename...>
typename _Cont>
9848 template<
typename _Range,
typename... _Args>
9852 operator()(_Range&& __r, _Args&&... __args)
const
9878 template<
template<
typename...>
typename _Cont,
typename... _Args>
9880 to [[nodiscard]] (_Args&&... __args)
9882 using __detail::_To2;
9883 using views::__adaptor::_Partial;
9890#if __cpp_lib_ranges_concat
9895 template<
bool _Const,
typename _Range,
typename... _Rs>
9896 struct __all_but_last_common
9898 static inline constexpr bool value
9899 =
requires {
requires (common_range<__maybe_const_t<_Const, _Range>>
9900 && __all_but_last_common<_Const, _Rs...>::value); };
9903 template<
bool _Const,
typename _Range>
9904 struct __all_but_last_common<_Const, _Range>
9905 {
static inline constexpr bool value =
true; };
9907 template<
bool _Const,
typename... _Rs>
9908 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9909 && __all_but_last_common<_Const, _Rs...>::value;
9911 template<
bool _Const,
typename... _Rs>
9912 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9913 && __all_but_last_common<_Const, _Rs...>::value;
9915 template<
typename _Range,
typename... _Rs>
9916 struct __all_but_first_sized
9917 {
static inline constexpr bool value = (sized_range<_Rs> && ...); };
9920 template<input_range... _Vs>
9921 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9922 class concat_view : public view_interface<concat_view<_Vs...>>
9924 tuple<_Vs...> _M_views;
9926 template<
bool _Const>
class _Iterator;
9929 constexpr concat_view() =
default;
9932 concat_view(_Vs... __views)
9933 : _M_views(std::move(__views)...)
9936 constexpr _Iterator<false>
9937 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
9939 _Iterator<false> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9940 __it.template _M_satisfy<0>();
9944 constexpr _Iterator<true>
9945 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9947 _Iterator<true> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9948 __it.template _M_satisfy<0>();
9953 end()
requires (!(__detail::__simple_view<_Vs> && ...))
9955 constexpr auto __n =
sizeof...(_Vs);
9956 if constexpr (__detail::__all_forward<
false, _Vs...>
9957 && common_range<_Vs...[__n - 1]>)
9958 return _Iterator<false>(
this, in_place_index<__n - 1>,
9959 ranges::end(std::get<__n - 1>(_M_views)));
9965 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9967 constexpr auto __n =
sizeof...(_Vs);
9968 if constexpr (__detail::__all_forward<
true, _Vs...>
9969 && common_range<
const _Vs...[__n - 1]>)
9970 return _Iterator<true>(
this, in_place_index<__n - 1>,
9971 ranges::end(std::get<__n - 1>(_M_views)));
9977 size()
requires (sized_range<_Vs>&&...)
9979 return std::apply([](
auto... __sizes) {
9980 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9981 return (_CT(__sizes) + ...);
9982 }, __detail::__tuple_transform(ranges::size, _M_views));
9986 size() const requires (sized_range<const _Vs>&&...)
9988 return std::apply([](
auto... __sizes) {
9989 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9990 return (_CT(__sizes) + ...);
9991 }, __detail::__tuple_transform(ranges::size, _M_views));
9995 template<
typename... _Rs>
9996 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
10000 template<
bool _Const,
typename... _Vs>
10001 struct __concat_view_iter_cat
10004 template<
bool _Const,
typename... _Vs>
10005 requires __detail::__all_forward<_Const, _Vs...>
10006 struct __concat_view_iter_cat<_Const, _Vs...>
10011 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
10012 return input_iterator_tag{};
10014 return []<
typename... _Cats>(_Cats... __cats) {
10015 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
10016 && __concat_is_random_access<_Const, _Vs...>)
10017 return random_access_iterator_tag{};
10018 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
10019 && __concat_is_bidirectional<_Const, _Vs...>)
10020 return bidirectional_iterator_tag{};
10021 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
10022 return forward_iterator_tag{};
10024 return input_iterator_tag{};
10025 }(
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
10026 ::iterator_category{}...);
10031 template<input_range... _Vs>
10032 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
10033 template<bool _Const>
10034 class concat_view<_Vs...>::_Iterator
10035 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
10040 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
10041 return random_access_iterator_tag{};
10042 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
10043 return bidirectional_iterator_tag{};
10044 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
10045 return forward_iterator_tag{};
10047 return input_iterator_tag{};
10050 friend concat_view;
10051 friend _Iterator<!_Const>;
10055 using iterator_concept =
decltype(_S_iter_concept());
10056 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
10057 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
10060 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
10062 __maybe_const_t<_Const, concat_view>* _M_parent =
nullptr;
10065 template<
size_t _Nm>
10069 if constexpr (_Nm < (
sizeof...(_Vs) - 1))
10071 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
10073 _M_it.template emplace<_Nm + 1>(ranges::begin
10074 (std::get<_Nm + 1>(_M_parent->_M_views)));
10075 _M_satisfy<_Nm + 1>();
10080 template<
size_t _Nm>
10084 if constexpr (_Nm == 0)
10085 --std::get<0>(_M_it);
10088 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
10090 _M_it.template emplace<_Nm - 1>(ranges::end
10091 (std::get<_Nm - 1>(_M_parent->_M_views)));
10092 _M_prev<_Nm - 1>();
10095 --std::get<_Nm>(_M_it);
10099 template<
size_t _Nm>
10101 _M_advance_fwd(difference_type __offset, difference_type __steps)
10103 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10104 if constexpr (_Nm ==
sizeof...(_Vs) - 1)
10105 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10108 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
10109 if (__offset + __steps < __n_size)
10110 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10113 _M_it.template emplace<_Nm + 1>(ranges::begin
10114 (std::get<_Nm + 1>(_M_parent->_M_views)));
10115 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
10120 template<
size_t _Nm>
10122 _M_advance_bwd(difference_type __offset, difference_type __steps)
10124 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10125 if constexpr (_Nm == 0)
10126 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10128 if (__offset >= __steps)
10129 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10132 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
10133 _M_it.template emplace<_Nm - 1>(ranges::end
10134 (std::get<_Nm - 1>(_M_parent->_M_views)));
10135 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
10143 template<
typename _Fp>
10144 static constexpr auto
10145 _S_invoke_with_runtime_index(_Fp&& __f,
size_t __index)
10147 return [&__f, __index]<
size_t _Idx>(
this auto&& __self) {
10148 if (_Idx == __index)
10149 return __f.template operator()<_Idx>();
10150 if constexpr (_Idx + 1 <
sizeof...(_Vs))
10151 return __self.template
operator()<_Idx + 1>();
10152 __builtin_unreachable();
10153 }.template operator()<0>();
10156 template<
typename _Fp>
10158 _M_invoke_with_runtime_index(_Fp&& __f)
10159 {
return _S_invoke_with_runtime_index(
std::forward<_Fp>(__f), _M_it.index()); }
10161 template<
typename... _Args>
10163 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
10164 requires constructible_from<__base_iter, _Args&&...>
10169 _Iterator() =
default;
10172 _Iterator(_Iterator<!_Const> __it)
10173 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
10174 : _M_parent(__it._M_parent),
10175 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
10176 return __base_iter(in_place_index<_Idx>,
10177 std::get<_Idx>(
std::move(__it._M_it)));
10178 }, __it._M_it.index()))
10181 constexpr decltype(
auto)
10184 __glibcxx_assert(!_M_it.valueless_by_exception());
10185 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
10186 return std::visit([](
auto&& __it) -> reference {
return *__it; }, _M_it);
10189 constexpr _Iterator&
10192 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10193 ++std::get<_Idx>(_M_it);
10194 _M_satisfy<_Idx>();
10203 constexpr _Iterator
10205 requires __detail::__all_forward<_Const, _Vs...>
10207 auto __tmp = *
this;
10212 constexpr _Iterator&
10214 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10216 __glibcxx_assert(!_M_it.valueless_by_exception());
10217 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10223 constexpr _Iterator
10225 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10227 auto __tmp = *
this;
10232 constexpr _Iterator&
10233 operator+=(difference_type __n)
10234 requires __detail::__concat_is_random_access<_Const, _Vs...>
10236 __glibcxx_assert(!_M_it.valueless_by_exception());
10237 _M_invoke_with_runtime_index([
this, __n]<
size_t _Idx>() {
10238 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10240 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10242 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10247 constexpr _Iterator&
10248 operator-=(difference_type __n)
10249 requires __detail::__concat_is_random_access<_Const, _Vs...>
10255 constexpr decltype(
auto)
10256 operator[](difference_type __n)
const
10257 requires __detail::__concat_is_random_access<_Const, _Vs...>
10258 {
return *((*this) + __n); }
10260 friend constexpr bool
10261 operator==(
const _Iterator& __x,
const _Iterator& __y)
10262 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10264 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10265 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10266 return __x._M_it == __y._M_it;
10269 friend constexpr bool
10270 operator==(
const _Iterator& __it, default_sentinel_t)
10272 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10273 constexpr auto __last_idx =
sizeof...(_Vs) - 1;
10274 return (__it._M_it.index() == __last_idx
10275 && (std::get<__last_idx>(__it._M_it)
10276 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10279 friend constexpr bool
10280 operator<(
const _Iterator& __x,
const _Iterator& __y)
10281 requires __detail::__all_random_access<_Const, _Vs...>
10282 {
return __x._M_it < __y._M_it; }
10284 friend constexpr bool
10285 operator>(
const _Iterator& __x,
const _Iterator& __y)
10286 requires __detail::__all_random_access<_Const, _Vs...>
10287 {
return __x._M_it > __y._M_it; }
10289 friend constexpr bool
10290 operator<=(
const _Iterator& __x,
const _Iterator& __y)
10291 requires __detail::__all_random_access<_Const, _Vs...>
10292 {
return __x._M_it <= __y._M_it; }
10294 friend constexpr bool
10295 operator>=(
const _Iterator& __x,
const _Iterator& __y)
10296 requires __detail::__all_random_access<_Const, _Vs...>
10297 {
return __x._M_it >= __y._M_it; }
10299 friend constexpr auto
10300 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
10301 requires __detail::__all_random_access<_Const, _Vs...>
10302 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10303 {
return __x._M_it <=> __y._M_it; }
10305 friend constexpr _Iterator
10306 operator+(
const _Iterator& __it, difference_type __n)
10307 requires __detail::__concat_is_random_access<_Const, _Vs...>
10308 {
return auto(__it) += __n; }
10310 friend constexpr _Iterator
10311 operator+(difference_type __n,
const _Iterator& __it)
10312 requires __detail::__concat_is_random_access<_Const, _Vs...>
10313 {
return __it + __n; }
10315 friend constexpr _Iterator
10316 operator-(
const _Iterator& __it, difference_type __n)
10317 requires __detail::__concat_is_random_access<_Const, _Vs...>
10318 {
return auto(__it) -= __n; }
10320 friend constexpr difference_type
10321 operator-(
const _Iterator& __x,
const _Iterator& __y)
10322 requires __detail::__concat_is_random_access<_Const, _Vs...>
10324 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10325 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> difference_type {
10326 if constexpr (_Ix > _Iy)
10328 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10329 ranges::end(std::get<_Iy>(__y._M_parent
10331 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10333 std::get<_Ix>(__x._M_it));
10334 difference_type __s = 0;
10335 [&]<
size_t _Idx = _Iy + 1>(
this auto&& __self) {
10336 if constexpr (_Idx < _Ix)
10338 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10339 __self.template operator()<_Idx + 1>();
10342 return __dy + __s + __dx;
10344 else if constexpr (_Ix < _Iy)
10345 return -(__y - __x);
10347 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10348 }, __y._M_it.index());
10349 }, __x._M_it.index());
10352 friend constexpr difference_type
10353 operator-(
const _Iterator& __x, default_sentinel_t)
10354 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10355 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10356 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10358 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10359 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10360 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10361 difference_type __s = 0;
10362 [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) {
10363 if constexpr (_Idx <
sizeof...(_Vs))
10365 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10366 __self.template operator()<_Idx + 1>();
10369 return -(__dx + __s);
10370 }, __x._M_it.index());
10373 friend constexpr difference_type
10374 operator-(default_sentinel_t,
const _Iterator& __x)
10375 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10376 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10377 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10380 friend constexpr decltype(
auto)
10381 iter_move(
const _Iterator& __it)
10383 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10384 return std::visit([](
const auto& __i) -> _Res {
10385 return ranges::iter_move(__i);
10389 friend constexpr void
10390 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10391 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10392 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10394 std::visit([&]<
typename _Tp,
typename _Up>(
const _Tp& __it1,
const _Up& __it2) {
10395 if constexpr (is_same_v<_Tp, _Up>)
10396 ranges::iter_swap(__it1, __it2);
10398 ranges::swap(*__it1, *__it2);
10399 }, __x._M_it, __y._M_it);
10402 template<
typename _Fn>
10403 static constexpr _Iterator
10404 _S_for_each_segment(_Iterator __first, _Iterator __last, _Fn __func)
10406 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> _Iterator {
10407 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> _Iterator {
10408 if constexpr (_Ix == _Iy)
10410 auto __ret = __func(std::get<_Ix>(__first._M_it), std::get<_Iy>(__last._M_it));
10411 return _Iterator(__first._M_parent, std::in_place_index<_Ix>, __ret);
10413 else if constexpr (_Ix < _Iy)
10415 auto __first_range = std::get<_Ix>(__first._M_parent->_M_views);
10416 auto __ret = __func(std::get<_Ix>(__first._M_it),
10417 ranges::end(__first_range));
10418 if (__ret != ranges::end(__first_range))
10419 return _Iterator(__first._M_parent, std::in_place_index<_Ix>, __ret);
10421 return [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) -> _Iterator {
10422 if constexpr (_Idx < _Iy)
10424 auto __mid_range = std::get<_Idx>(__first._M_parent->_M_views);
10425 auto __mid_ret = __func(ranges::begin(__mid_range),
10426 ranges::end(__mid_range));
10427 if (__mid_ret != ranges::end(__mid_range))
10428 return _Iterator(__first._M_parent, std::in_place_index<_Idx>, __mid_ret);
10429 return __self.template operator()<_Idx + 1>();
10433 auto __last_range = std::get<_Iy>(__last._M_parent->_M_views);
10434 auto __last_ret = __func(ranges::begin(__last_range),
10435 std::get<_Iy>(__last._M_it));
10436 return _Iterator(__first._M_parent, std::in_place_index<_Iy>, __last_ret);
10442 __builtin_unreachable();
10443 __glibcxx_assert(
false);
10445 }, __last._M_it.index());
10446 }, __first._M_it.index());
10449 static constexpr bool _S_enable_for_each_segment =
true;
10456 template<
typename... _Ts>
10462 template<
typename... _Ts>
10463 requires __detail::__can_concat_view<_Ts...>
10465 operator() [[nodiscard]] (_Ts&&... __ts)
const
10468 template<input_range _Range>
10470 operator() [[nodiscard]] (_Range&& __t)
const
10474 inline constexpr _Concat concat;
10480#if __cpp_lib_ranges_cache_latest
10483 template<input_range _Vp>
10485 class cache_latest_view :
public view_interface<cache_latest_view<_Vp>>
10487 _Vp _M_base = _Vp();
10489 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10490 add_pointer_t<range_reference_t<_Vp>>,
10491 range_reference_t<_Vp>>;
10492 __detail::__non_propagating_cache<__cache_t> _M_cache;
10498 cache_latest_view()
requires default_initializable<_Vp> = default;
10501 cache_latest_view(_Vp __base)
10502 : _M_base(std::move(__base))
10506 base() const & requires copy_constructible<_Vp>
10507 {
return _M_base; }
10515 {
return _Iterator(*
this); }
10519 {
return _Sentinel(*
this); }
10522 size()
requires sized_range<_Vp>
10523 {
return ranges::size(_M_base); }
10526 size() const requires sized_range<const _Vp>
10527 {
return ranges::size(_M_base); }
10530 template<
typename _Range>
10531 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10533 template<input_range _Vp>
10535 class cache_latest_view<_Vp>::_Iterator
10537 cache_latest_view* _M_parent;
10538 iterator_t<_Vp> _M_current;
10541 _Iterator(cache_latest_view& __parent)
10543 _M_current(ranges::begin(__parent._M_base))
10546 friend class cache_latest_view;
10549 using difference_type = range_difference_t<_Vp>;
10550 using value_type = range_value_t<_Vp>;
10551 using iterator_concept = input_iterator_tag;
10553 _Iterator(_Iterator&&) =
default;
10556 operator=(_Iterator&&) =
default;
10558 constexpr iterator_t<_Vp>
10562 constexpr const iterator_t<_Vp>&
10563 base() const & noexcept
10564 {
return _M_current; }
10566 constexpr range_reference_t<_Vp>&
10569 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10571 if (!_M_parent->_M_cache)
10572 _M_parent->_M_cache =
std::__addressof(__detail::__as_lvalue(*_M_current));
10573 return **_M_parent->_M_cache;
10577 if (!_M_parent->_M_cache)
10578 _M_parent->_M_cache._M_emplace_deref(_M_current);
10579 return *_M_parent->_M_cache;
10583 constexpr _Iterator&
10586 _M_parent->_M_cache._M_reset();
10595 friend constexpr range_rvalue_reference_t<_Vp>
10596 iter_move(
const _Iterator& __i)
10597 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10598 {
return ranges::iter_move(__i._M_current); }
10600 friend constexpr void
10601 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10602 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10603 requires indirectly_swappable<iterator_t<_Vp>>
10604 { ranges::iter_swap(__x._M_current, __y._M_current); }
10607 template<input_range _Vp>
10609 class cache_latest_view<_Vp>::_Sentinel
10611 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10614 _Sentinel(cache_latest_view& __parent)
10615 : _M_end(ranges::end(__parent._M_base))
10618 friend class cache_latest_view;
10621 _Sentinel() =
default;
10623 constexpr sentinel_t<_Vp>
10627 friend constexpr bool
10628 operator==(
const _Iterator& __x,
const _Sentinel& __y)
10629 {
return __x._M_current == __y._M_end; }
10631 friend constexpr range_difference_t<_Vp>
10632 operator-(
const _Iterator& __x,
const _Sentinel& __y)
10633 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10634 {
return __x._M_current - __y._M_end; }
10636 friend constexpr range_difference_t<_Vp>
10637 operator-(
const _Sentinel& __x,
const _Iterator& __y)
10638 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10639 {
return __x._M_end - __y._M_current; }
10646 template<
typename _Tp>
10647 concept __can_cache_latest =
requires { cache_latest_view(
std::declval<_Tp>()); };
10650 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10652 template<viewable_range _Range>
10653 requires __detail::__can_cache_latest<_Range>
10655 operator() [[nodiscard]] (_Range&& __r)
const
10658 static constexpr bool _S_has_simple_call_op =
true;
10661 inline constexpr _CacheLatest cache_latest;
10666#if __cpp_lib_ranges_as_input
10669 template<input_range _Vp>
10671 class as_input_view :
public view_interface<as_input_view<_Vp>>
10673 _Vp _M_base = _Vp();
10675 template<
bool _Const>
10679 as_input_view()
requires default_initializable<_Vp> = default;
10682 as_input_view(_Vp __base)
10683 : _M_base(std::move(__base))
10687 base() const & requires copy_constructible<_Vp>
10688 {
return _M_base; }
10695 begin()
requires (!__detail::__simple_view<_Vp>)
10696 {
return _Iterator<false>(ranges::begin(_M_base)); }
10699 begin() const requires range<const _Vp>
10700 {
return _Iterator<true>(ranges::begin(_M_base)); }
10703 end()
requires (!__detail::__simple_view<_Vp>)
10704 {
return ranges::end(_M_base); }
10707 end() const requires range<const _Vp>
10708 {
return ranges::end(_M_base); }
10711 size()
requires sized_range<_Vp>
10712 {
return ranges::size(_M_base); }
10715 size() const requires sized_range<const _Vp>
10716 {
return ranges::size(_M_base); }
10719 template<
typename _Range>
10720 as_input_view(_Range&&) -> as_input_view<views::all_t<_Range>>;
10722 template<input_range _Vp>
10724 template<
bool _Const>
10725 class as_input_view<_Vp>::_Iterator
10727 using _Base = __maybe_const_t<_Const, _Vp>;
10729 iterator_t<_Base> _M_current = iterator_t<_Base>();
10732 _Iterator(iterator_t<_Base> __current)
10733 : _M_current(std::move(__current))
10736 friend as_input_view;
10737 friend _Iterator<!_Const>;
10740 using difference_type = range_difference_t<_Base>;
10741 using value_type = range_value_t<_Base>;
10742 using iterator_concept = input_iterator_tag;
10744 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
10746 _Iterator(_Iterator&&) = default;
10747 _Iterator& operator=(_Iterator&&) = default;
10750 _Iterator(_Iterator<!_Const> __i)
10751 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10752 : _M_current(std::move(__i._M_current))
10755 constexpr iterator_t<_Base>
10759 constexpr const iterator_t<_Base>&
10760 base() const & noexcept
10761 {
return _M_current; }
10763 constexpr decltype(
auto)
10765 {
return *_M_current; }
10767 constexpr _Iterator&
10778 friend constexpr bool
10779 operator==(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10780 {
return __x._M_current == __y; }
10782 friend constexpr difference_type
10783 operator-(
const sentinel_t<_Base>& __y,
const _Iterator& __x)
10784 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10785 {
return __y - __x._M_current; }
10787 friend constexpr difference_type
10788 operator-(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10789 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10790 {
return __x._M_current - __y; }
10792 friend constexpr range_rvalue_reference_t<_Base>
10793 iter_move(
const _Iterator& __i)
10794 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10795 {
return ranges::iter_move(__i._M_current); }
10797 friend constexpr void
10798 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10799 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10800 requires indirectly_swappable<iterator_t<_Base>>
10801 { ranges::iter_swap(__x._M_current, __y._M_current); }
10808 template<
typename _Tp>
10812 struct _AsInput : __adaptor::_RangeAdaptorClosure<_AsInput>
10814 template<viewable_range _Range>
10815 requires __detail::__can_as_input<_Range>
10817 operator() [[nodiscard]] (_Range&& __r)
const
10819 if constexpr (input_range<_Range>
10820 && !common_range<_Range>
10821 && !forward_range<_Range>)
10827 static constexpr bool _S_has_simple_call_op =
true;
10830 inline constexpr _AsInput as_input;
10835_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.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.