30#ifndef _GLIBCXX_RANGES
31#define _GLIBCXX_RANGES 1
33#if __cplusplus > 201703L
36#pragma GCC system_header
50#if __cplusplus > 202002L
54#include <bits/binders.h>
58#define __glibcxx_want_algorithm_default_value_type
59#define __glibcxx_want_ranges
60#define __glibcxx_want_ranges_as_const
61#define __glibcxx_want_ranges_as_rvalue
62#define __glibcxx_want_ranges_cache_latest
63#define __glibcxx_want_ranges_cartesian_product
64#define __glibcxx_want_ranges_concat
65#define __glibcxx_want_ranges_chunk
66#define __glibcxx_want_ranges_chunk_by
67#define __glibcxx_want_ranges_enumerate
68#define __glibcxx_want_ranges_indices
69#define __glibcxx_want_ranges_join_with
70#define __glibcxx_want_ranges_repeat
71#define __glibcxx_want_ranges_slide
72#define __glibcxx_want_ranges_stride
73#define __glibcxx_want_ranges_to_container
74#define __glibcxx_want_ranges_to_input
75#define __glibcxx_want_ranges_zip
78#ifdef __glibcxx_generator
79# include <bits/elements_of.h>
88namespace std _GLIBCXX_VISIBILITY(default)
90_GLIBCXX_BEGIN_NAMESPACE_VERSION
105 template<
typename _Tp>
requires is_object_v<_Tp>
110 static constexpr _Tp*
begin() noexcept {
return nullptr; }
111 static constexpr _Tp*
end() noexcept {
return nullptr; }
112 static constexpr _Tp*
data() noexcept {
return nullptr; }
113 static constexpr size_t size() noexcept {
return 0; }
114 static constexpr bool empty() noexcept {
return true; }
117 template<
typename _Tp>
118 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> =
true;
122#if __cpp_lib_ranges >= 202207L
124 template<
typename _Tp>
125 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
127 template<
typename _Tp>
128 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
131 template<__boxable _Tp>
132 struct __box : std::optional<_Tp>
134 using std::optional<_Tp>::optional;
138 noexcept(is_nothrow_default_constructible_v<_Tp>)
139 requires default_initializable<_Tp>
140 : std::optional<_Tp>{std::in_place}
143 __box(
const __box&) =
default;
144 __box(__box&&) =
default;
146 using std::optional<_Tp>::operator=;
152 operator=(
const __box& __that)
153 noexcept(is_nothrow_copy_constructible_v<_Tp>)
154 requires (!copyable<_Tp>) && copy_constructible<_Tp>
159 this->emplace(*__that);
167 operator=(__box&& __that)
168 noexcept(is_nothrow_move_constructible_v<_Tp>)
169 requires (!movable<_Tp>)
182 template<
typename _Tp>
183 concept __boxable_copyable
184 = copy_constructible<_Tp>
185 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
186 && is_nothrow_copy_constructible_v<_Tp>));
187 template<
typename _Tp>
188 concept __boxable_movable
189 = (!copy_constructible<_Tp>)
190 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
196 template<__boxable _Tp>
197 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
201 [[no_unique_address]] _Tp _M_value = _Tp();
204 __box()
requires default_initializable<_Tp> = default;
207 __box(const _Tp& __t)
208 noexcept(is_nothrow_copy_constructible_v<_Tp>)
209 requires copy_constructible<_Tp>
215 noexcept(is_nothrow_move_constructible_v<_Tp>)
216 : _M_value(std::
move(__t))
219 template<
typename... _Args>
220 requires constructible_from<_Tp, _Args...>
222 __box(in_place_t, _Args&&... __args)
223 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
224 : _M_value(std::
forward<_Args>(__args)...)
227 __box(
const __box&) =
default;
228 __box(__box&&) =
default;
229 __box& operator=(
const __box&)
requires copyable<_Tp> =
default;
230 __box& operator=(__box&&)
requires movable<_Tp> = default;
235 operator=(const __box& __that) noexcept
236 requires (!copyable<_Tp>) && copy_constructible<_Tp>
238 static_assert(is_nothrow_copy_constructible_v<_Tp>);
249 operator=(__box&& __that)
noexcept
250 requires (!movable<_Tp>)
252 static_assert(is_nothrow_move_constructible_v<_Tp>);
262 has_value() const noexcept
277 constexpr const _Tp&&
282 operator->() noexcept
286 operator->() const noexcept
290 template<
template<
typename>
class>
291 constexpr bool __is_std_op_template =
false;
294 inline constexpr bool __is_std_op_template<std::equal_to> =
true;
296 inline constexpr bool __is_std_op_template<std::not_equal_to> =
true;
298 inline constexpr bool __is_std_op_template<std::greater> =
true;
300 inline constexpr bool __is_std_op_template<std::less> =
true;
302 inline constexpr bool __is_std_op_template<std::greater_equal> =
true;
304 inline constexpr bool __is_std_op_template<std::less_equal> =
true;
306 inline constexpr bool __is_std_op_template<std::plus> =
true;
308 inline constexpr bool __is_std_op_template<std::minus> =
true;
310 inline constexpr bool __is_std_op_template<std::multiplies> =
true;
312 inline constexpr bool __is_std_op_template<std::divides> =
true;
314 inline constexpr bool __is_std_op_template<std::modulus> =
true;
316 inline constexpr bool __is_std_op_template<std::negate> =
true;
318 inline constexpr bool __is_std_op_template<std::logical_and> =
true;
320 inline constexpr bool __is_std_op_template<std::logical_or> =
true;
322 inline constexpr bool __is_std_op_template<std::logical_not> =
true;
324 inline constexpr bool __is_std_op_template<std::bit_and> =
true;
326 inline constexpr bool __is_std_op_template<std::bit_or> =
true;
328 inline constexpr bool __is_std_op_template<std::bit_xor> =
true;
330 inline constexpr bool __is_std_op_template<std::bit_not> =
true;
333 template<
typename _Fn>
334 constexpr bool __is_std_op_wrapper =
false;
336 template<
template<
typename>
class _Ft,
typename _Tp>
337 constexpr bool __is_std_op_wrapper<_Ft<_Tp>>
338 = __is_std_op_template<_Ft>;
340 namespace __func_handle
342 template<
typename _Fn>
345 _Inplace() =
default;
348 _Inplace(_Fn __func) noexcept
352 template<
typename... _Iters>
353 constexpr decltype(
auto)
354 _M_call_deref(
const _Iters&... __iters)
const
355 noexcept(
noexcept(_M_ptr(*__iters...)))
356 {
return _M_ptr(*__iters...); }
358 template<
typename _DistType,
typename... _Iters>
359 constexpr decltype(
auto)
360 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
361 noexcept(
noexcept(_M_ptr(__iters[iter_difference_t<_Iters>(__n)]...)))
362 {
return _M_ptr(__iters[iter_difference_t<_Iters>(__n)]...); }
365 [[no_unique_address]] _Fn _M_ptr = _Fn();
368 template<
typename _Fn>
369 struct _InplaceMemPtr
371 _InplaceMemPtr() =
default;
374 _InplaceMemPtr(_Fn __func) noexcept
378 template<
typename... _Iters>
379 constexpr decltype(
auto)
380 _M_call_deref(
const _Iters&... __iters)
const
384 template<
typename _DistType,
typename... _Iters>
385 constexpr decltype(
auto)
386 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
387 noexcept(
noexcept(
std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...)))
388 {
return std::__invoke(_M_ptr, __iters[iter_difference_t<_Iters>(__n)]...); }
391 _Fn _M_ptr =
nullptr;
394 template<
typename _Fn>
397 _ViaPointer() =
default;
400 _ViaPointer(_Fn& __func) noexcept
404 template<
typename _Un>
405 requires (!is_const_v<_Un>) && is_same_v<const _Un, _Fn>
407 _ViaPointer(_ViaPointer<_Un> __other) noexcept
408 : _M_ptr(__other._M_ptr)
411 template<
typename... _Iters>
412 constexpr decltype(
auto)
413 _M_call_deref(
const _Iters&... __iters)
const
414 noexcept(
noexcept((*_M_ptr)(*__iters...)))
415 {
return (*_M_ptr)(*__iters...); }
417 template<
typename _DistType,
typename... _Iters>
418 constexpr decltype(
auto)
419 _M_call_subscript(
const _DistType __n,
const _Iters&... __iters)
const
420 noexcept(
noexcept((*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...)))
421 {
return (*_M_ptr)(__iters[iter_difference_t<_Iters>(__n)]...); }
424 _Fn* _M_ptr =
nullptr;
427 friend struct _ViaPointer;
430 template<
typename _Fn>
433 _StaticCall() =
default;
436 _StaticCall(
const _Fn&)
noexcept
439 template<
typename... _Iters>
440 static constexpr decltype(
auto)
441 _M_call_deref(
const _Iters&... __iters)
442 noexcept(
noexcept(_Fn::operator()(*__iters...)))
443 {
return _Fn::operator()(*__iters...); }
445 template<
typename _DistType,
typename... _Iters>
446 static constexpr decltype(
auto)
447 _M_call_subscript(_DistType __n,
const _Iters&... __iters)
448 noexcept(
noexcept(_Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...)))
449 {
return _Fn::operator()(__iters[iter_difference_t<_Iters>(__n)]...); }
453 template<
typename _Fn,
typename... _Iters>
454 using __func_handle_t =
decltype([] {
455 using _Fd = remove_cv_t<_Fn>;
456 if constexpr (is_member_pointer_v<_Fd>)
457 return __func_handle::_InplaceMemPtr<_Fd>();
458 else if constexpr (is_function_v<remove_pointer_t<_Fd>>)
459 return __func_handle::_Inplace<_Fd>();
460 else if constexpr (__is_std_op_wrapper<_Fd>)
461 return __func_handle::_Inplace<_Fd>();
462 else if constexpr (
requires (
const _Iters&... __iters)
463 { _Fd::operator()(*__iters...); })
464 return __func_handle::_StaticCall<_Fd>();
466 return __func_handle::_ViaPointer<_Fn>();
471#if __cpp_lib_ranges >= 202207L
472 template<move_constructible _Tp>
474 template<copy_constructible _Tp>
476 requires is_object_v<_Tp>
480 single_view()
requires default_initializable<_Tp> = default;
483 single_view(const _Tp& __t)
484 noexcept(is_nothrow_copy_constructible_v<_Tp>)
485 requires copy_constructible<_Tp>
490 single_view(_Tp&& __t)
491 noexcept(is_nothrow_move_constructible_v<_Tp>)
492 : _M_value(std::
move(__t))
497 template<
typename... _Args>
498 requires constructible_from<_Tp, _Args...>
500 single_view(in_place_t, _Args&&... __args)
501 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
502 : _M_value{in_place, std::
forward<_Args>(__args)...}
510 begin() const noexcept
515 {
return data() + 1; }
519 {
return data() + 1; }
523 static constexpr bool
527 static constexpr size_t
533 {
return _M_value.operator->(); }
536 data() const noexcept
537 {
return _M_value.operator->(); }
540 [[no_unique_address]] __detail::__box<_Tp> _M_value;
543 template<
typename _Tp>
544 single_view(_Tp) -> single_view<_Tp>;
548 template<
typename _Wp>
549 constexpr auto __to_signed_like(_Wp __w)
noexcept
551 if constexpr (!integral<_Wp>)
552 return iter_difference_t<_Wp>();
553 else if constexpr (
sizeof(iter_difference_t<_Wp>) >
sizeof(_Wp))
554 return iter_difference_t<_Wp>(__w);
555 else if constexpr (
sizeof(ptrdiff_t) >
sizeof(_Wp))
556 return ptrdiff_t(__w);
557 else if constexpr (
sizeof(
long long) >
sizeof(_Wp))
558 return (
long long)(__w);
559#ifdef __SIZEOF_INT128__
560 else if constexpr (__SIZEOF_INT128__ >
sizeof(_Wp))
561 return __int128(__w);
564 return __max_diff_type(__w);
567 template<
typename _Wp>
570 template<
typename _It>
571 concept __decrementable = incrementable<_It>
574 { --__i } -> same_as<_It&>;
575 { __i-- } -> same_as<_It>;
578 template<
typename _It>
579 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
580 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
582 { __i += __n } -> same_as<_It&>;
583 { __i -= __n } -> same_as<_It&>;
587 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
590 template<
typename _Winc>
591 struct __iota_view_iter_cat
594 template<incrementable _Winc>
595 struct __iota_view_iter_cat<_Winc>
596 {
using iterator_category = input_iterator_tag; };
599 template<weakly_incrementable _Winc,
600 semiregular _Bound = unreachable_sentinel_t>
601 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
608 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
614 using namespace __detail;
615 if constexpr (__advanceable<_Winc>)
616 return random_access_iterator_tag{};
617 else if constexpr (__decrementable<_Winc>)
618 return bidirectional_iterator_tag{};
619 else if constexpr (incrementable<_Winc>)
620 return forward_iterator_tag{};
622 return input_iterator_tag{};
626 using iterator_concept =
decltype(_S_iter_concept());
628 using value_type = _Winc;
629 using difference_type = __detail::__iota_diff_t<_Winc>;
631 _Iterator()
requires default_initializable<_Winc> = default;
634 _Iterator(_Winc __value)
635 : _M_value(__value) { }
638 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
653 operator++(
int)
requires incrementable<_Winc>
661 operator--()
requires __detail::__decrementable<_Winc>
668 operator--(
int)
requires __detail::__decrementable<_Winc>
676 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
678 using __detail::__is_integer_like;
679 using __detail::__is_signed_integer_like;
680 if constexpr (__is_integer_like<_Winc>
681 && !__is_signed_integer_like<_Winc>)
683 if (__n >= difference_type(0))
684 _M_value +=
static_cast<_Winc
>(__n);
686 _M_value -=
static_cast<_Winc
>(-__n);
694 operator-=(difference_type __n)
requires __detail::__advanceable<_Winc>
696 using __detail::__is_integer_like;
697 using __detail::__is_signed_integer_like;
698 if constexpr (__is_integer_like<_Winc>
699 && !__is_signed_integer_like<_Winc>)
701 if (__n >= difference_type(0))
702 _M_value -=
static_cast<_Winc
>(__n);
704 _M_value +=
static_cast<_Winc
>(-__n);
712 operator[](difference_type __n)
const
713 requires __detail::__advanceable<_Winc>
714 {
return _Winc(_M_value + __n); }
716 friend constexpr bool
717 operator==(
const _Iterator& __x,
const _Iterator& __y)
718 requires equality_comparable<_Winc>
719 {
return __x._M_value == __y._M_value; }
721 friend constexpr bool
722 operator<(
const _Iterator& __x,
const _Iterator& __y)
723 requires totally_ordered<_Winc>
724 {
return __x._M_value < __y._M_value; }
726 friend constexpr bool
727 operator>(
const _Iterator& __x,
const _Iterator& __y)
728 requires totally_ordered<_Winc>
729 {
return __y < __x; }
731 friend constexpr bool
732 operator<=(
const _Iterator& __x,
const _Iterator& __y)
733 requires totally_ordered<_Winc>
734 {
return !(__y < __x); }
736 friend constexpr bool
737 operator>=(
const _Iterator& __x,
const _Iterator& __y)
738 requires totally_ordered<_Winc>
739 {
return !(__x < __y); }
741#ifdef __cpp_lib_three_way_comparison
742 friend constexpr auto
743 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
744 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
745 {
return __x._M_value <=> __y._M_value; }
748 friend constexpr _Iterator
749 operator+(_Iterator __i, difference_type __n)
750 requires __detail::__advanceable<_Winc>
756 friend constexpr _Iterator
757 operator+(difference_type __n, _Iterator __i)
758 requires __detail::__advanceable<_Winc>
759 {
return __i += __n; }
761 friend constexpr _Iterator
762 operator-(_Iterator __i, difference_type __n)
763 requires __detail::__advanceable<_Winc>
769 friend constexpr difference_type
770 operator-(
const _Iterator& __x,
const _Iterator& __y)
771 requires __detail::__advanceable<_Winc>
773 using __detail::__is_integer_like;
774 using __detail::__is_signed_integer_like;
775 using _Dt = difference_type;
776 if constexpr (__is_integer_like<_Winc>)
778 if constexpr (__is_signed_integer_like<_Winc>)
779 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
781 return (__y._M_value > __x._M_value)
782 ? _Dt(-_Dt(__y._M_value - __x._M_value))
783 : _Dt(__x._M_value - __y._M_value);
786 return __x._M_value - __y._M_value;
790 _Winc _M_value = _Winc();
800 _M_equal(
const _Iterator& __x)
const
801 {
return __x._M_value == _M_bound; }
804 _M_distance_from(
const _Iterator& __x)
const
805 {
return _M_bound - __x._M_value; }
807 _Bound _M_bound = _Bound();
810 _Sentinel() =
default;
813 _Sentinel(_Bound __bound)
814 : _M_bound(__bound) { }
816 friend constexpr bool
817 operator==(
const _Iterator& __x,
const _Sentinel& __y)
818 {
return __y._M_equal(__x); }
820 friend constexpr iter_difference_t<_Winc>
821 operator-(
const _Iterator& __x,
const _Sentinel& __y)
822 requires sized_sentinel_for<_Bound, _Winc>
823 {
return -__y._M_distance_from(__x); }
825 friend constexpr iter_difference_t<_Winc>
826 operator-(
const _Sentinel& __x,
const _Iterator& __y)
827 requires sized_sentinel_for<_Bound, _Winc>
828 {
return __x._M_distance_from(__y); }
833 _Winc _M_value = _Winc();
834 [[no_unique_address]] _Bound _M_bound = _Bound();
837 iota_view()
requires default_initializable<_Winc> = default;
840 iota_view(_Winc __value)
845 iota_view(type_identity_t<_Winc> __value,
846 type_identity_t<_Bound> __bound)
847 : _M_value(__value), _M_bound(__bound)
849 if constexpr (totally_ordered_with<_Winc, _Bound>)
850 __glibcxx_assert(
bool(__value <= __bound) );
854 iota_view(_Iterator __first, _Iterator __last)
855 requires same_as<_Winc, _Bound>
856 : iota_view(__first._M_value, __last._M_value)
860 iota_view(_Iterator __first, unreachable_sentinel_t __last)
861 requires same_as<_Bound, unreachable_sentinel_t>
862 : iota_view(__first._M_value, __last)
866 iota_view(_Iterator __first, _Sentinel __last)
867 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
868 : iota_view(__first._M_value, __last._M_bound)
872 begin()
const {
return _Iterator{_M_value}; }
877 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
878 return unreachable_sentinel;
880 return _Sentinel{_M_bound};
884 end() const requires same_as<_Winc, _Bound>
885 {
return _Iterator{_M_bound}; }
891 {
return _M_value == _M_bound; }
895 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
896 || (integral<_Winc> && integral<_Bound>)
897 || sized_sentinel_for<_Bound, _Winc>
899 using __detail::__is_integer_like;
900 using __detail::__to_unsigned_like;
901 if constexpr (integral<_Winc> && integral<_Bound>)
904 return _Up(_M_bound) - _Up(_M_value);
906 else if constexpr (__is_integer_like<_Winc>)
907 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
909 return __to_unsigned_like(_M_bound - _M_value);
913 template<
typename _Winc,
typename _Bound>
914 requires (!__detail::__is_integer_like<_Winc>
915 || !__detail::__is_integer_like<_Bound>
916 || (__detail::__is_signed_integer_like<_Winc>
917 == __detail::__is_signed_integer_like<_Bound>))
918 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
920 template<
typename _Winc,
typename _Bound>
921 inline constexpr bool
922 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
926 template<
typename _Tp>
927 inline constexpr empty_view<_Tp>
empty{};
931 template<
typename _Tp>
932 concept __can_single_view
938 template<__detail::__can_single_view _Tp>
940 operator() [[nodiscard]] (_Tp&& __e)
const
945 inline constexpr _Single single{};
949 template<
typename... _Args>
955 template<__detail::__can_iota_view _Tp>
957 operator() [[nodiscard]] (_Tp&& __e)
const
960 template<
typename _Tp,
typename _Up>
961 requires __detail::__can_iota_view<_Tp, _Up>
963 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
967 inline constexpr _Iota
iota{};
969#ifdef __cpp_lib_ranges_indices
972 template<ranges::__detail::__is_
integer_like _Tp>
973 requires __detail::__can_iota_view<_Tp>
974 [[nodiscard]]
constexpr auto
975 operator() (_Tp __e)
const noexcept
976 {
return iota(_Tp{}, __e); }
979 inline constexpr _Indices indices{};
986 template<
typename _Val,
typename _CharT,
typename _Traits>
987 concept __stream_extractable
988 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
991 template<movable _Val,
typename _CharT,
992 typename _Traits = char_traits<_CharT>>
993 requires default_initializable<_Val>
994 && __detail::__stream_extractable<_Val, _CharT, _Traits>
995 class basic_istream_view
996 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
1000 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
1007 *_M_stream >> _M_object;
1008 return _Iterator{
this};
1011 constexpr default_sentinel_t
1012 end() const noexcept
1016 basic_istream<_CharT, _Traits>* _M_stream;
1017 _Val _M_object = _Val();
1022 using iterator_concept = input_iterator_tag;
1023 using difference_type = ptrdiff_t;
1024 using value_type = _Val;
1027 _Iterator(basic_istream_view* __parent) noexcept
1028 : _M_parent(__parent)
1031 _Iterator(
const _Iterator&) =
delete;
1032 _Iterator(_Iterator&&) =
default;
1033 _Iterator& operator=(
const _Iterator&) =
delete;
1034 _Iterator& operator=(_Iterator&&) =
default;
1039 *_M_parent->_M_stream >> _M_parent->_M_object;
1049 {
return _M_parent->_M_object; }
1052 operator==(
const _Iterator& __x, default_sentinel_t)
1053 {
return __x._M_at_end(); }
1056 basic_istream_view* _M_parent;
1060 {
return !*_M_parent->_M_stream; }
1066 template<
typename _Val>
1067 using istream_view = basic_istream_view<_Val, char>;
1069 template<
typename _Val>
1070 using wistream_view = basic_istream_view<_Val, wchar_t>;
1076 template<
typename _Tp,
typename _Up>
1077 concept __can_istream_view =
requires (_Up __e) {
1078 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
1082 template<
typename _Tp>
1085 template<
typename _CharT,
typename _Traits>
1087 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
1088 requires __detail::__can_istream_view<_Tp, remove_reference_t<
decltype(__e)>>
1089 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
1092 template<
typename _Tp>
1093 inline constexpr _Istream<_Tp>
istream;
1101 template<
typename _Tp,
int _Disc>
1110 template<
bool _Present,
typename _Tp,
int _Disc = 0>
1111 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
1114 template<
bool _Const,
typename _Tp>
1115 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
1120using __detail::__maybe_const_t;
1122namespace views::__adaptor
1125 template<
typename _Adaptor,
typename... _Args>
1126 concept __adaptor_invocable
1131 template<
typename _Adaptor,
typename... _Args>
1132 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
1133 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
1134 && (constructible_from<decay_t<_Args>, _Args> && ...);
1136 template<
typename _Adaptor,
typename... _Args>
1139 template<
typename _Lhs,
typename _Rhs>
1147 template<
typename _Derived>
1148 struct _RangeAdaptorClosure;
1150 template<
typename _Tp,
typename _Up>
1151 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
1152 void __is_range_adaptor_closure_fn
1153 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
1155 template<
typename _Tp>
1156 concept __is_range_adaptor_closure
1157 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
1159#pragma GCC diagnostic push
1160#pragma GCC diagnostic ignored "-Wdangling-reference"
1162 template<
typename _Self,
typename _Range>
1163 requires __is_range_adaptor_closure<_Self>
1164 && __adaptor_invocable<_Self, _Range>
1171 template<
typename _Lhs,
typename _Rhs>
1172 requires __is_range_adaptor_closure<_Lhs>
1173 && __is_range_adaptor_closure<_Rhs>
1180#pragma GCC diagnostic pop
1182 template<
typename _Derived>
1183 struct _RangeAdaptorClosure
1189 template<
typename _Self,
typename _Range>
1190 requires __is_range_adaptor_closure<_Self>
1191 && __adaptor_invocable<_Self, _Range>
1192 friend constexpr auto
1193 operator|(_Range&& __r, _Self&& __self);
1195 template<
typename _Lhs,
typename _Rhs>
1196 requires __is_range_adaptor_closure<_Lhs>
1197 && __is_range_adaptor_closure<_Rhs>
1198 friend constexpr auto
1213 template<
typename _Derived>
1214 struct _RangeAdaptor
1218 template<
typename... _Args>
1219 requires __adaptor_partial_app_viable<_Derived, _Args...>
1221 operator()(_Args&&... __args)
const
1230 template<
typename _Adaptor>
1231 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1235 template<
typename _Adaptor,
typename... _Args>
1236 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1237 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1241 template<
typename _Adaptor,
typename... _Args>
1242 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1244 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1245 [[no_unique_address]] _Binder _M_binder;
1249 template<
typename... _Ts>
1251 _Partial(
int, _Ts&&... __args)
1252 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1257#if __cpp_explicit_this_parameter
1258 template<
typename _Self,
typename _Range>
1259 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1261 operator()(
this _Self&& __self, _Range&& __r)
1263 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1267 template<
typename _Range>
1268 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1270 operator()(_Range&& __r)
const &
1273 template<
typename _Range>
1274 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1276 operator()(_Range&& __r) &&
1279 template<
typename _Range>
1281 operator()(_Range&& __r)
const && =
delete;
1289 template<
typename _Adaptor,
typename... _Args>
1290 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1291 && (is_trivially_copy_constructible_v<_Args> && ...)
1292 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1294 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1295 [[no_unique_address]] _Binder _M_binder;
1297 template<
typename... _Ts>
1299 _Partial(
int, _Ts&&... __args)
1300 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1305 template<
typename _Range>
1306 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1308 operator()(_Range&& __r)
const
1311 static constexpr bool _S_has_simple_call_op =
true;
1314 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1315 concept __pipe_invocable
1320 template<
typename _Lhs,
typename _Rhs>
1321 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1323 [[no_unique_address]] _Lhs _M_lhs;
1324 [[no_unique_address]] _Rhs _M_rhs;
1326 template<
typename _Tp,
typename _Up>
1328 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1329 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1334#if __cpp_explicit_this_parameter
1335 template<
typename _Self,
typename _Range>
1336 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1338 operator()(
this _Self&& __self, _Range&& __r)
1340 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1341 (__like_t<_Self, _Pipe>(__self)._M_lhs
1345 template<
typename _Range>
1346 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1348 operator()(_Range&& __r)
const &
1351 template<
typename _Range>
1352 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1354 operator()(_Range&& __r) &&
1357 template<
typename _Range>
1359 operator()(_Range&& __r)
const && =
delete;
1367 template<
typename _Lhs,
typename _Rhs>
1368 requires __closure_has_simple_call_op<_Lhs>
1369 && __closure_has_simple_call_op<_Rhs>
1370 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1372 [[no_unique_address]] _Lhs _M_lhs;
1373 [[no_unique_address]] _Rhs _M_rhs;
1375 template<
typename _Tp,
typename _Up>
1377 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1378 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1381 template<
typename _Range>
1382 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1384 operator()(_Range&& __r)
const
1387 static constexpr bool _S_has_simple_call_op =
true;
1391#if __cpp_lib_ranges >= 202202L
1393 template<
typename _Derived>
1394 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1395 class range_adaptor_closure
1396 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1400 template<range _Range>
requires is_object_v<_Range>
1406 static void _S_fun(_Range&);
1407 static void _S_fun(_Range&&) =
delete;
1410 template<__detail::__different_from<ref_view> _Tp>
1411 requires convertible_to<_Tp, _Range&>
1412 &&
requires { _S_fun(declval<_Tp>()); }
1423 constexpr iterator_t<_Range>
1425 {
return ranges::begin(*_M_r); }
1427 constexpr sentinel_t<_Range>
1429 {
return ranges::end(*_M_r); }
1432 empty() const requires requires { ranges::empty(*_M_r); }
1433 {
return ranges::empty(*_M_r); }
1436 size() const requires sized_range<_Range>
1437 {
return ranges::size(*_M_r); }
1440 data() const requires contiguous_range<_Range>
1441 {
return ranges::data(*_M_r); }
1444 template<
typename _Range>
1445 ref_view(_Range&) -> ref_view<_Range>;
1447 template<
typename _Tp>
1448 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1450 template<range _Range>
1451 requires movable<_Range>
1452 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1456 _Range _M_r = _Range();
1459 owning_view()
requires default_initializable<_Range> = default;
1462 owning_view(_Range&& __t)
1463 noexcept(is_nothrow_move_constructible_v<_Range>)
1464 : _M_r(std::
move(__t))
1467 owning_view(owning_view&&) =
default;
1468 owning_view& operator=(owning_view&&) =
default;
1474 constexpr const _Range&
1475 base() const& noexcept
1482 constexpr const _Range&&
1483 base() const&& noexcept
1486 constexpr iterator_t<_Range>
1488 {
return ranges::begin(_M_r); }
1490 constexpr sentinel_t<_Range>
1492 {
return ranges::end(_M_r); }
1495 begin() const requires range<const _Range>
1496 {
return ranges::begin(_M_r); }
1499 end() const requires range<const _Range>
1500 {
return ranges::end(_M_r); }
1503 empty()
requires requires { ranges::empty(_M_r); }
1504 {
return ranges::empty(_M_r); }
1507 empty() const requires requires { ranges::empty(_M_r); }
1508 {
return ranges::empty(_M_r); }
1511 size()
requires sized_range<_Range>
1512 {
return ranges::size(_M_r); }
1515 size() const requires sized_range<const _Range>
1516 {
return ranges::size(_M_r); }
1519 data()
requires contiguous_range<_Range>
1520 {
return ranges::data(_M_r); }
1523 data() const requires contiguous_range<const _Range>
1524 {
return ranges::data(_M_r); }
1527 template<
typename _Tp>
1528 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1529 = enable_borrowed_range<_Tp>;
1535 template<
typename _Range>
1538 template<
typename _Range>
1542 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1544 template<
typename _Range>
1545 static constexpr bool
1548 if constexpr (view<decay_t<_Range>>)
1549 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1550 else if constexpr (__detail::__can_ref_view<_Range>)
1556 template<viewable_range _Range>
1557 requires view<decay_t<_Range>>
1558 || __detail::__can_ref_view<_Range>
1559 || __detail::__can_owning_view<_Range>
1561 operator() [[nodiscard]] (_Range&& __r)
const
1562 noexcept(_S_noexcept<_Range>())
1564 if constexpr (view<decay_t<_Range>>)
1566 else if constexpr (__detail::__can_ref_view<_Range>)
1572 static constexpr bool _S_has_simple_call_op =
true;
1575 inline constexpr _All all;
1577 template<viewable_range _Range>
1583 template<
typename _Tp>
1584 struct __non_propagating_cache
1592 template<
typename _Tp>
1593 requires is_object_v<_Tp>
1594 struct __non_propagating_cache<_Tp>
1595 :
protected _Optional_base<_Tp>
1597 __non_propagating_cache() =
default;
1600 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1604 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1605 { __other._M_reset(); }
1607 constexpr __non_propagating_cache&
1608 operator=(
const __non_propagating_cache& __other)
noexcept
1615 constexpr __non_propagating_cache&
1616 operator=(__non_propagating_cache&& __other)
noexcept
1623 constexpr __non_propagating_cache&
1624 operator=(_Tp __val)
1627 this->_M_payload._M_construct(
std::move(__val));
1632 operator bool() const noexcept
1633 {
return this->_M_is_engaged(); }
1637 {
return this->_M_get(); }
1639 constexpr const _Tp&
1641 {
return this->_M_get(); }
1643 template<
typename _Iter>
1645 _M_emplace_deref(
const _Iter& __i)
1648 auto __f = [] (
auto& __x) {
return *__x; };
1649 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1650 return this->_M_get();
1653 using _Optional_base<_Tp>::_M_reset;
1656 template<range _Range>
1657 struct _CachedPosition
1660 _M_has_value()
const
1663 constexpr iterator_t<_Range>
1664 _M_get(
const _Range&)
const
1666 __glibcxx_assert(
false);
1667 __builtin_unreachable();
1671 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1675 template<forward_range _Range>
1676 struct _CachedPosition<_Range>
1677 :
protected __non_propagating_cache<iterator_t<_Range>>
1680 _M_has_value()
const
1681 {
return this->_M_is_engaged(); }
1683 constexpr iterator_t<_Range>
1684 _M_get(
const _Range&)
const
1686 __glibcxx_assert(_M_has_value());
1691 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1693 __glibcxx_assert(!_M_has_value());
1696 this->_M_payload._M_engaged =
true;
1700 template<random_access_range _Range>
1701 struct _CachedPosition<_Range>
1704 range_difference_t<_Range> _M_offset = -1;
1707 _CachedPosition() =
default;
1710 _CachedPosition(
const _CachedPosition&) =
default;
1713 _CachedPosition(_CachedPosition&& __other)
noexcept
1716 constexpr _CachedPosition&
1717 operator=(
const _CachedPosition&) =
default;
1719 constexpr _CachedPosition&
1720 operator=(_CachedPosition&& __other)
noexcept
1723 _M_offset = __other._M_offset;
1724 __other._M_offset = -1;
1729 _M_has_value()
const
1730 {
return _M_offset >= 0; }
1732 constexpr iterator_t<_Range>
1733 _M_get(_Range& __r)
const
1735 __glibcxx_assert(_M_has_value());
1736 return ranges::begin(__r) + _M_offset;
1740 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1742 __glibcxx_assert(!_M_has_value());
1743 _M_offset = __it - ranges::begin(__r);
1750 template<
typename _Base>
1751 struct __filter_view_iter_cat
1754 template<forward_range _Base>
1755 struct __filter_view_iter_cat<_Base>
1761 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1762 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1763 return bidirectional_iterator_tag{};
1764 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1765 return forward_iterator_tag{};
1770 using iterator_category =
decltype(_S_iter_cat());
1774 template<input_range _Vp,
1775 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1776 requires view<_Vp> && is_object_v<_Pred>
1777 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1782 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1785 static constexpr auto
1788 if constexpr (bidirectional_range<_Vp>)
1789 return bidirectional_iterator_tag{};
1790 else if constexpr (forward_range<_Vp>)
1791 return forward_iterator_tag{};
1793 return input_iterator_tag{};
1798 using _Vp_iter = iterator_t<_Vp>;
1800 _Vp_iter _M_current = _Vp_iter();
1801 filter_view* _M_parent =
nullptr;
1804 using iterator_concept =
decltype(_S_iter_concept());
1806 using value_type = range_value_t<_Vp>;
1807 using difference_type = range_difference_t<_Vp>;
1809 _Iterator()
requires default_initializable<_Vp_iter> = default;
1812 _Iterator(filter_view* __parent, _Vp_iter __current)
1813 : _M_current(std::move(__current)),
1817 constexpr const _Vp_iter&
1818 base() const & noexcept
1819 {
return _M_current; }
1825 constexpr range_reference_t<_Vp>
1827 {
return *_M_current; }
1831 requires __detail::__has_arrow<_Vp_iter>
1832 && copyable<_Vp_iter>
1833 {
return _M_current; }
1835 constexpr _Iterator&
1838 _M_current = ranges::find_if(
std::move(++_M_current),
1839 ranges::end(_M_parent->_M_base),
1849 operator++(
int)
requires forward_range<_Vp>
1856 constexpr _Iterator&
1857 operator--()
requires bidirectional_range<_Vp>
1866 operator--(
int)
requires bidirectional_range<_Vp>
1873 friend constexpr bool
1874 operator==(
const _Iterator& __x,
const _Iterator& __y)
1875 requires equality_comparable<_Vp_iter>
1876 {
return __x._M_current == __y._M_current; }
1878 friend constexpr range_rvalue_reference_t<_Vp>
1879 iter_move(
const _Iterator& __i)
1880 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1881 {
return ranges::iter_move(__i._M_current); }
1883 friend constexpr void
1884 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1885 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1886 requires indirectly_swappable<_Vp_iter>
1887 { ranges::iter_swap(__x._M_current, __y._M_current); }
1893 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1896 __equal(
const _Iterator& __i)
const
1897 {
return __i._M_current == _M_end; }
1900 _Sentinel() =
default;
1903 _Sentinel(filter_view* __parent)
1904 : _M_end(ranges::
end(__parent->_M_base))
1907 constexpr sentinel_t<_Vp>
1911 friend constexpr bool
1912 operator==(
const _Iterator& __x,
const _Sentinel& __y)
1913 {
return __y.__equal(__x); }
1916 _Vp _M_base = _Vp();
1917 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1918 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1921 filter_view()
requires (default_initializable<_Vp>
1922 && default_initializable<_Pred>)
1926 filter_view(_Vp __base, _Pred __pred)
1931 base() const& requires copy_constructible<_Vp>
1938 constexpr const _Pred&
1940 {
return *_M_pred; }
1945 if (_M_cached_begin._M_has_value())
1946 return {
this, _M_cached_begin._M_get(_M_base)};
1948 __glibcxx_assert(_M_pred.has_value());
1949 auto __it = ranges::find_if(ranges::begin(_M_base),
1950 ranges::end(_M_base),
1952 _M_cached_begin._M_set(_M_base, __it);
1959 if constexpr (common_range<_Vp>)
1960 return _Iterator{
this, ranges::end(_M_base)};
1962 return _Sentinel{
this};
1966 template<
typename _Range,
typename _Pred>
1967 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1973 template<
typename _Range,
typename _Pred>
1974 concept __can_filter_view
1978 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1980 template<viewable_range _Range,
typename _Pred>
1981 requires __detail::__can_filter_view<_Range, _Pred>
1983 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1988 using _RangeAdaptor<_Filter>::operator();
1989 static constexpr int _S_arity = 2;
1990 static constexpr bool _S_has_simple_extra_args =
true;
1993 inline constexpr _Filter filter;
1996#if __cpp_lib_ranges >= 202207L
1997 template<input_range _Vp, move_constructible _Fp>
1999 template<input_range _Vp, copy_constructible _Fp>
2001 requires view<_Vp> && is_object_v<_Fp>
2002 && regular_invocable<_Fp&, range_reference_t<_Vp>>
2003 && std::__detail::__can_reference<invoke_result_t<_Fp&,
2004 range_reference_t<_Vp>>>
2005 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
2008 template<
bool _Const>
2009 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2011 template<
bool _Const>
2015 template<
bool _Const>
2016 requires forward_range<_Base<_Const>>
2017 struct __iter_cat<_Const>
2026 using _Base = transform_view::_Base<_Const>;
2027 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2028 range_reference_t<_Base>>;
2031 if constexpr (is_reference_v<_Res>)
2034 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
2035 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
2036 return random_access_iterator_tag{};
2041 return input_iterator_tag{};
2044 using iterator_category =
decltype(_S_iter_cat());
2047 template<
bool _Const>
2050 template<
bool _Const>
2051 struct _Iterator : __iter_cat<_Const>
2054 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2055 using _Base = transform_view::_Base<_Const>;
2056 using _Base_iter = iterator_t<_Base>;
2057 using _Func_handle = __detail::__func_handle_t<
2058 __detail::__maybe_const_t<_Const, _Fp>,
2064 if constexpr (random_access_range<_Base>)
2065 return random_access_iterator_tag{};
2066 else if constexpr (bidirectional_range<_Base>)
2067 return bidirectional_iterator_tag{};
2068 else if constexpr (forward_range<_Base>)
2069 return forward_iterator_tag{};
2071 return input_iterator_tag{};
2074 _Base_iter _M_current = _Base_iter();
2075 [[no_unique_address]] _Func_handle _M_fun;
2078 using iterator_concept =
decltype(_S_iter_concept());
2081 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2082 range_reference_t<_Base>>>;
2083 using difference_type = range_difference_t<_Base>;
2085 _Iterator()
requires default_initializable<_Base_iter> = default;
2088 _Iterator(_Func_handle __fun, _Base_iter __current)
2089 : _M_current(std::move(__current)), _M_fun(__fun)
2093 _Iterator(_Parent* __parent, _Base_iter __current)
2094 : _M_current(std::
move(__current)), _M_fun(*__parent->_M_fun)
2098 _Iterator(_Iterator<!_Const> __i)
2100 && convertible_to<iterator_t<_Vp>, _Base_iter>
2101 : _M_current(
std::move(__i._M_current)), _M_fun(__i._M_fun)
2104 constexpr const _Base_iter&
2105 base() const & noexcept
2106 {
return _M_current; }
2108 constexpr _Base_iter
2112 constexpr decltype(
auto)
2114 noexcept(
noexcept(_M_fun._M_call_deref(_M_current)))
2115 {
return _M_fun._M_call_deref(_M_current); }
2117 constexpr _Iterator&
2129 operator++(
int)
requires forward_range<_Base>
2136 constexpr _Iterator&
2137 operator--()
requires bidirectional_range<_Base>
2144 operator--(
int)
requires bidirectional_range<_Base>
2151 constexpr _Iterator&
2152 operator+=(difference_type __n)
requires random_access_range<_Base>
2158 constexpr _Iterator&
2159 operator-=(difference_type __n)
requires random_access_range<_Base>
2165 constexpr decltype(
auto)
2166 operator[](difference_type __n)
const
2167 requires random_access_range<_Base>
2168 {
return _M_fun._M_call_subscript(__n, _M_current); }
2170 friend constexpr bool
2171 operator==(
const _Iterator& __x,
const _Iterator& __y)
2172 requires equality_comparable<_Base_iter>
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 __x._M_current < __y._M_current; }
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 !(__y < __x); }
2190 friend constexpr bool
2191 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2192 requires random_access_range<_Base>
2193 {
return !(__x < __y); }
2195#ifdef __cpp_lib_three_way_comparison
2196 friend constexpr auto
2197 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2198 requires random_access_range<_Base>
2199 && three_way_comparable<_Base_iter>
2200 {
return __x._M_current <=> __y._M_current; }
2203 friend constexpr _Iterator
2204 operator+(_Iterator __i, difference_type __n)
2205 requires random_access_range<_Base>
2206 {
return {__i._M_fun, __i._M_current + __n}; }
2208 friend constexpr _Iterator
2209 operator+(difference_type __n, _Iterator __i)
2210 requires random_access_range<_Base>
2211 {
return {__i._M_fun, __i._M_current + __n}; }
2213 friend constexpr _Iterator
2214 operator-(_Iterator __i, difference_type __n)
2215 requires random_access_range<_Base>
2216 {
return {__i._M_fun, __i._M_current - __n}; }
2220 friend constexpr difference_type
2221 operator-(
const _Iterator& __x,
const _Iterator& __y)
2222 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2223 {
return __x._M_current - __y._M_current; }
2225 friend constexpr decltype(
auto)
2226 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2228 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2234 friend _Iterator<!_Const>;
2235 template<
bool>
friend struct _Sentinel;
2238 template<
bool _Const>
2242 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2243 using _Base = transform_view::_Base<_Const>;
2245 template<
bool _Const2>
2247 __distance_from(
const _Iterator<_Const2>& __i)
const
2248 {
return _M_end - __i._M_current; }
2250 template<
bool _Const2>
2252 __equal(
const _Iterator<_Const2>& __i)
const
2253 {
return __i._M_current == _M_end; }
2255 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2258 _Sentinel() =
default;
2261 _Sentinel(sentinel_t<_Base> __end)
2266 _Sentinel(_Sentinel<!_Const> __i)
2268 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2272 constexpr sentinel_t<_Base>
2276 template<
bool _Const2>
2277 requires sentinel_for<sentinel_t<_Base>,
2278 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2279 friend constexpr bool
2280 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2281 {
return __y.__equal(__x); }
2283 template<
bool _Const2,
2284 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2285 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2286 friend constexpr range_difference_t<_Base2>
2287 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2288 {
return -__y.__distance_from(__x); }
2290 template<
bool _Const2,
2291 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2292 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2293 friend constexpr range_difference_t<_Base2>
2294 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2295 {
return __y.__distance_from(__x); }
2297 friend _Sentinel<!_Const>;
2300 _Vp _M_base = _Vp();
2301 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2304 transform_view()
requires (default_initializable<_Vp>
2305 && default_initializable<_Fp>)
2309 transform_view(_Vp __base, _Fp __fun)
2314 base() const& requires copy_constructible<_Vp>
2315 {
return _M_base ; }
2321 constexpr _Iterator<false>
2323 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2325 constexpr _Iterator<true>
2327 requires range<const _Vp>
2328 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2329 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2331 constexpr _Sentinel<false>
2333 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2335 constexpr _Iterator<false>
2336 end()
requires common_range<_Vp>
2337 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2339 constexpr _Sentinel<true>
2341 requires range<const _Vp>
2342 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2343 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2345 constexpr _Iterator<true>
2347 requires common_range<const _Vp>
2348 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2349 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2352 size()
requires sized_range<_Vp>
2353 {
return ranges::size(_M_base); }
2356 size() const requires sized_range<const _Vp>
2357 {
return ranges::size(_M_base); }
2360 template<
typename _Range,
typename _Fp>
2361 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2367 template<
typename _Range,
typename _Fp>
2368 concept __can_transform_view
2372 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2374 template<viewable_range _Range,
typename _Fp>
2375 requires __detail::__can_transform_view<_Range, _Fp>
2377 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2382 using _RangeAdaptor<_Transform>::operator();
2383 static constexpr int _S_arity = 2;
2384 static constexpr bool _S_has_simple_extra_args =
true;
2387 inline constexpr _Transform transform;
2394 template<
bool _Const>
2395 using _CI = counted_iterator<
2396 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2398 template<
bool _Const>
2402 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2403 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2406 _Sentinel() =
default;
2409 _Sentinel(sentinel_t<_Base> __end)
2414 _Sentinel(_Sentinel<!_Const> __s)
2415 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2419 constexpr sentinel_t<_Base>
2423 friend constexpr bool
2424 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2425 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2427 template<
bool _OtherConst = !_Const,
2428 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2429 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2430 friend constexpr bool
2431 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2432 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2434 friend _Sentinel<!_Const>;
2437 _Vp _M_base = _Vp();
2438 range_difference_t<_Vp> _M_count = 0;
2441 take_view()
requires default_initializable<_Vp> = default;
2444 take_view(_Vp __base, range_difference_t<_Vp> __count)
2445 : _M_base(std::move(__base)), _M_count(std::move(__count))
2449 base() const& requires copy_constructible<_Vp>
2457 begin()
requires (!__detail::__simple_view<_Vp>)
2459 if constexpr (sized_range<_Vp>)
2461 if constexpr (random_access_range<_Vp>)
2462 return ranges::begin(_M_base);
2466 return counted_iterator(ranges::begin(_M_base), __sz);
2470 return counted_iterator(ranges::begin(_M_base), _M_count);
2474 begin() const requires range<const _Vp>
2476 if constexpr (sized_range<const _Vp>)
2478 if constexpr (random_access_range<const _Vp>)
2479 return ranges::begin(_M_base);
2483 return counted_iterator(ranges::begin(_M_base), __sz);
2487 return counted_iterator(ranges::begin(_M_base), _M_count);
2491 end()
requires (!__detail::__simple_view<_Vp>)
2493 if constexpr (sized_range<_Vp>)
2495 if constexpr (random_access_range<_Vp>)
2496 return ranges::begin(_M_base) +
size();
2501 return _Sentinel<false>{ranges::end(_M_base)};
2505 end() const requires range<const _Vp>
2507 if constexpr (sized_range<const _Vp>)
2509 if constexpr (random_access_range<const _Vp>)
2510 return ranges::begin(_M_base) +
size();
2515 return _Sentinel<true>{ranges::end(_M_base)};
2519 size()
requires sized_range<_Vp>
2521 auto __n = ranges::size(_M_base);
2522 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2526 size() const requires sized_range<const _Vp>
2528 auto __n = ranges::size(_M_base);
2529 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2536 template<
typename _Range>
2537 take_view(_Range&&, range_difference_t<_Range>)
2538 -> take_view<views::all_t<_Range>>;
2540 template<
typename _Tp>
2541 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2542 = enable_borrowed_range<_Tp>;
2548 template<
typename _Range>
2549 inline constexpr bool __is_empty_view =
false;
2551 template<
typename _Tp>
2552 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2554 template<
typename _Range>
2555 inline constexpr bool __is_basic_string_view =
false;
2557 template<
typename _CharT,
typename _Traits>
2558 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2561 using ranges::__detail::__is_subrange;
2563 template<
typename _Range>
2564 inline constexpr bool __is_iota_view =
false;
2566 template<
typename _Winc,
typename _Bound>
2567 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2569 template<
typename _Range>
2570 inline constexpr bool __is_repeat_view =
false;
2572 template<
typename _Range>
2574 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2576 template<
typename _Range,
typename _Dp>
2577 concept __can_take_view
2581 struct _Take : __adaptor::_RangeAdaptor<_Take>
2583 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2584 requires __detail::__can_take_view<_Range, _Dp>
2586 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2588 using _Tp = remove_cvref_t<_Range>;
2589 if constexpr (__detail::__is_empty_view<_Tp>)
2591#ifdef __cpp_lib_optional_range_support
2592 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2595 else if constexpr (random_access_range<_Tp>
2597 && (std::__detail::__is_span<_Tp>
2598 || __detail::__is_basic_string_view<_Tp>
2599 || __detail::__is_subrange<_Tp>
2600 || __detail::__is_iota_view<_Tp>))
2603 auto __begin = ranges::begin(__r);
2604 auto __end = __begin + __n;
2605 if constexpr (std::__detail::__is_span<_Tp>)
2606 return span<typename _Tp::element_type>(__begin, __end);
2607 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2608 return _Tp(__begin, __end);
2609 else if constexpr (__detail::__is_subrange<_Tp>)
2610 return subrange<iterator_t<_Tp>>(__begin, __end);
2612 return iota_view(*__begin, *__end);
2614 else if constexpr (__detail::__is_repeat_view<_Tp>)
2620 using _RangeAdaptor<_Take>::operator();
2621 static constexpr int _S_arity = 2;
2625 template<
typename _Tp>
2626 static constexpr bool _S_has_simple_extra_args
2627 = ranges::__detail::__is_integer_like<_Tp>;
2630 inline constexpr _Take take;
2633 template<view _Vp,
typename _Pred>
2634 requires input_range<_Vp> && is_object_v<_Pred>
2635 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2636 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2638 template<
bool _Const>
2642 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2644 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2645 const _Pred* _M_pred =
nullptr;
2648 _Sentinel() =
default;
2651 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2652 : _M_end(__end), _M_pred(__pred)
2656 _Sentinel(_Sentinel<!_Const> __s)
2657 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2658 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2661 constexpr sentinel_t<_Base>
2662 base()
const {
return _M_end; }
2664 friend constexpr bool
2665 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2666 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2668 template<
bool _OtherConst = !_Const,
2669 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2670 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2671 friend constexpr bool
2672 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2673 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2675 friend _Sentinel<!_Const>;
2678 _Vp _M_base = _Vp();
2679 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2682 take_while_view()
requires (default_initializable<_Vp>
2683 && default_initializable<_Pred>)
2687 take_while_view(_Vp __base, _Pred __pred)
2692 base() const& requires copy_constructible<_Vp>
2699 constexpr const _Pred&
2701 {
return *_M_pred; }
2704 begin()
requires (!__detail::__simple_view<_Vp>)
2705 {
return ranges::begin(_M_base); }
2708 begin() const requires range<const _Vp>
2709 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2710 {
return ranges::begin(_M_base); }
2713 end()
requires (!__detail::__simple_view<_Vp>)
2714 {
return _Sentinel<false>(ranges::end(_M_base),
2718 end() const requires range<const _Vp>
2719 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2720 {
return _Sentinel<true>(ranges::end(_M_base),
2724 template<
typename _Range,
typename _Pred>
2725 take_while_view(_Range&&, _Pred)
2726 -> take_while_view<views::all_t<_Range>, _Pred>;
2732 template<
typename _Range,
typename _Pred>
2733 concept __can_take_while_view
2737 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2739 template<viewable_range _Range,
typename _Pred>
2740 requires __detail::__can_take_while_view<_Range, _Pred>
2742 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2747 using _RangeAdaptor<_TakeWhile>::operator();
2748 static constexpr int _S_arity = 2;
2749 static constexpr bool _S_has_simple_extra_args =
true;
2752 inline constexpr _TakeWhile take_while;
2759 _Vp _M_base = _Vp();
2760 range_difference_t<_Vp> _M_count = 0;
2764 static constexpr bool _S_needs_cached_begin
2765 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2766 [[no_unique_address]]
2767 __detail::__maybe_present_t<_S_needs_cached_begin,
2768 __detail::_CachedPosition<_Vp>>
2772 drop_view()
requires default_initializable<_Vp> = default;
2775 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2776 : _M_base(std::move(__base)), _M_count(__count)
2777 { __glibcxx_assert(__count >= 0); }
2780 base() const& requires copy_constructible<_Vp>
2790 requires (!(__detail::__simple_view<_Vp>
2791 && random_access_range<const _Vp>
2792 && sized_range<const _Vp>))
2794 if constexpr (_S_needs_cached_begin)
2795 if (_M_cached_begin._M_has_value())
2796 return _M_cached_begin._M_get(_M_base);
2798 auto __it = ranges::next(ranges::begin(_M_base),
2799 _M_count, ranges::end(_M_base));
2800 if constexpr (_S_needs_cached_begin)
2801 _M_cached_begin._M_set(_M_base, __it);
2809 requires random_access_range<const _Vp> && sized_range<const _Vp>
2811 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2816 end()
requires (!__detail::__simple_view<_Vp>)
2817 {
return ranges::end(_M_base); }
2820 end() const requires range<const _Vp>
2821 {
return ranges::end(_M_base); }
2824 size()
requires sized_range<_Vp>
2826 const auto __s = ranges::size(_M_base);
2827 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2828 return __s < __c ? 0 : __s - __c;
2832 size() const requires sized_range<const _Vp>
2834 const auto __s = ranges::size(_M_base);
2835 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2836 return __s < __c ? 0 : __s - __c;
2840 template<
typename _Range>
2841 drop_view(_Range&&, range_difference_t<_Range>)
2842 -> drop_view<views::all_t<_Range>>;
2844 template<
typename _Tp>
2845 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2846 = enable_borrowed_range<_Tp>;
2852 template<
typename _Range>
2854 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2856 template<
typename _Range,
typename _Dp>
2857 concept __can_drop_view
2861 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2863 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2864 requires __detail::__can_drop_view<_Range, _Dp>
2866 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2868 using _Tp = remove_cvref_t<_Range>;
2869 if constexpr (__detail::__is_empty_view<_Tp>)
2871#ifdef __cpp_lib_optional_range_support
2872 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2875 else if constexpr (random_access_range<_Tp>
2877 && (std::__detail::__is_span<_Tp>
2878 || __detail::__is_basic_string_view<_Tp>
2879 || __detail::__is_iota_view<_Tp>
2880 || __detail::__is_subrange<_Tp>))
2883 auto __begin = ranges::begin(__r) + __n;
2884 auto __end = ranges::end(__r);
2885 if constexpr (std::__detail::__is_span<_Tp>)
2886 return span<typename _Tp::element_type>(__begin, __end);
2887 else if constexpr (__detail::__is_subrange<_Tp>)
2889 if constexpr (_Tp::_S_store_size)
2891 using ranges::__detail::__to_unsigned_like;
2892 auto __m = ranges::distance(__r) - __n;
2893 return _Tp(__begin, __end, __to_unsigned_like(__m));
2896 return _Tp(__begin, __end);
2899 return _Tp(__begin, __end);
2901 else if constexpr (__detail::__is_repeat_view<_Tp>)
2907 using _RangeAdaptor<_Drop>::operator();
2908 static constexpr int _S_arity = 2;
2909 template<
typename _Tp>
2910 static constexpr bool _S_has_simple_extra_args
2911 = _Take::_S_has_simple_extra_args<_Tp>;
2914 inline constexpr _Drop drop;
2917 template<view _Vp,
typename _Pred>
2918 requires input_range<_Vp> && is_object_v<_Pred>
2919 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2920 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2923 _Vp _M_base = _Vp();
2924 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2925 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2928 drop_while_view()
requires (default_initializable<_Vp>
2929 && default_initializable<_Pred>)
2933 drop_while_view(_Vp __base, _Pred __pred)
2938 base() const& requires copy_constructible<_Vp>
2945 constexpr const _Pred&
2947 {
return *_M_pred; }
2952 if (_M_cached_begin._M_has_value())
2953 return _M_cached_begin._M_get(_M_base);
2955 __glibcxx_assert(_M_pred.has_value());
2956 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2957 ranges::end(_M_base),
2959 _M_cached_begin._M_set(_M_base, __it);
2965 {
return ranges::end(_M_base); }
2968 template<
typename _Range,
typename _Pred>
2969 drop_while_view(_Range&&, _Pred)
2970 -> drop_while_view<views::all_t<_Range>, _Pred>;
2972 template<
typename _Tp,
typename _Pred>
2973 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2974 = enable_borrowed_range<_Tp>;
2980 template<
typename _Range,
typename _Pred>
2981 concept __can_drop_while_view
2985 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2987 template<viewable_range _Range,
typename _Pred>
2988 requires __detail::__can_drop_while_view<_Range, _Pred>
2990 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2996 using _RangeAdaptor<_DropWhile>::operator();
2997 static constexpr int _S_arity = 2;
2998 static constexpr bool _S_has_simple_extra_args =
true;
3001 inline constexpr _DropWhile drop_while;
3006 template<
typename _Tp>
3008 __as_lvalue(_Tp&& __t)
3009 {
return static_cast<_Tp&
>(__t); }
3012 template<input_range _Vp>
3013 requires view<_Vp> && input_range<range_reference_t<_Vp>>
3017 using _InnerRange = range_reference_t<_Vp>;
3019 template<
bool _Const>
3020 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3022 template<
bool _Const>
3023 using _Outer_iter = iterator_t<_Base<_Const>>;
3025 template<
bool _Const>
3026 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
3028 template<
bool _Const>
3029 static constexpr bool _S_ref_is_glvalue
3030 = is_reference_v<range_reference_t<_Base<_Const>>>;
3032 template<
bool _Const>
3036 template<
bool _Const>
3037 requires _S_ref_is_glvalue<_Const>
3038 && forward_range<_Base<_Const>>
3039 && forward_range<range_reference_t<_Base<_Const>>>
3040 struct __iter_cat<_Const>
3043 static constexpr auto
3046 using _Outer_iter = join_view::_Outer_iter<_Const>;
3047 using _Inner_iter = join_view::_Inner_iter<_Const>;
3048 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
3049 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
3050 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
3051 && derived_from<_InnerCat, bidirectional_iterator_tag>
3052 && common_range<range_reference_t<_Base<_Const>>>)
3053 return bidirectional_iterator_tag{};
3054 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
3055 && derived_from<_InnerCat, forward_iterator_tag>)
3056 return forward_iterator_tag{};
3058 return input_iterator_tag{};
3061 using iterator_category =
decltype(_S_iter_cat());
3064 template<
bool _Const>
3067 template<
bool _Const>
3068 struct _Iterator : __iter_cat<_Const>
3071 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3072 using _Base = join_view::_Base<_Const>;
3076 static constexpr bool _S_ref_is_glvalue
3077 = join_view::_S_ref_is_glvalue<_Const>;
3082 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
3083 if constexpr (_S_ref_is_glvalue)
3086 return _M_parent->_M_inner._M_emplace_deref(__x);
3089 _Outer_iter& __outer = _M_get_outer();
3090 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
3092 auto&& __inner = __update_inner(__outer);
3093 _M_inner = ranges::begin(__inner);
3094 if (_M_inner != ranges::end(__inner))
3098 if constexpr (_S_ref_is_glvalue)
3100 if constexpr (forward_iterator<_Inner_iter>)
3101 _M_inner = _Inner_iter();
3107 static constexpr auto
3110 if constexpr (_S_ref_is_glvalue
3111 && bidirectional_range<_Base>
3112 && bidirectional_range<range_reference_t<_Base>>
3113 && common_range<range_reference_t<_Base>>)
3114 return bidirectional_iterator_tag{};
3115 else if constexpr (_S_ref_is_glvalue
3116 && forward_range<_Base>
3117 && forward_range<range_reference_t<_Base>>)
3118 return forward_iterator_tag{};
3120 return input_iterator_tag{};
3123 using _Outer_iter = join_view::_Outer_iter<_Const>;
3124 using _Inner_iter = join_view::_Inner_iter<_Const>;
3126 constexpr _Outer_iter&
3129 if constexpr (forward_range<_Base>)
3132 return *_M_parent->_M_outer;
3135 constexpr const _Outer_iter&
3136 _M_get_outer()
const
3138 if constexpr (forward_range<_Base>)
3141 return *_M_parent->_M_outer;
3144 constexpr _Inner_iter&
3145 _M_get_inner() noexcept
3147 if constexpr (forward_iterator<_Inner_iter>)
3153 constexpr const _Inner_iter&
3154 _M_get_inner() const noexcept
3156 if constexpr (forward_iterator<_Inner_iter>)
3163 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
3164 : _M_outer(
std::move(__outer)), _M_parent(__parent)
3168 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
3169 : _M_parent(__parent)
3172 [[no_unique_address]]
3173 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
3174 =
decltype(_M_outer)();
3175 __conditional_t<forward_iterator<_Inner_iter>,
3176 _Inner_iter, optional<_Inner_iter>> _M_inner
3177 =
decltype(_M_inner)();
3178 _Parent* _M_parent =
nullptr;
3181 using iterator_concept =
decltype(_S_iter_concept());
3183 using value_type = range_value_t<range_reference_t<_Base>>;
3184 using difference_type
3185 = common_type_t<range_difference_t<_Base>,
3186 range_difference_t<range_reference_t<_Base>>>;
3188 _Iterator() =
default;
3191 _Iterator(_Iterator<!_Const> __i)
3193 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3194 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3196 _M_parent(__i._M_parent)
3199 constexpr decltype(
auto)
3201 {
return *_M_get_inner(); }
3205 constexpr _Inner_iter
3207 requires __detail::__has_arrow<_Inner_iter>
3208 && copyable<_Inner_iter>
3209 {
return _M_get_inner(); }
3211 constexpr _Iterator&
3214 auto&& __inner_range = [
this] () ->
auto&& {
3215 if constexpr (_S_ref_is_glvalue)
3216 return *_M_get_outer();
3218 return *_M_parent->_M_inner;
3220 if (++_M_get_inner() == ranges::end(__inner_range))
3234 requires _S_ref_is_glvalue && forward_range<_Base>
3235 && forward_range<range_reference_t<_Base>>
3242 constexpr _Iterator&
3244 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3245 && bidirectional_range<range_reference_t<_Base>>
3246 && common_range<range_reference_t<_Base>>
3248 if (_M_outer == ranges::end(_M_parent->_M_base))
3249 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3250 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3251 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3258 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3259 && bidirectional_range<range_reference_t<_Base>>
3260 && common_range<range_reference_t<_Base>>
3267 friend constexpr bool
3268 operator==(
const _Iterator& __x,
const _Iterator& __y)
3269 requires _S_ref_is_glvalue
3270 && forward_range<_Base>
3271 && equality_comparable<_Inner_iter>
3273 return (__x._M_outer == __y._M_outer
3274 && __x._M_inner == __y._M_inner);
3277 friend constexpr decltype(
auto)
3278 iter_move(
const _Iterator& __i)
3279 noexcept(
noexcept(ranges::iter_move(__i._M_get_inner())))
3280 {
return ranges::iter_move(__i._M_get_inner()); }
3282 friend constexpr void
3283 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3284 noexcept(
noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3285 requires indirectly_swappable<_Inner_iter>
3286 {
return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3288 friend _Iterator<!_Const>;
3289 template<
bool>
friend struct _Sentinel;
3292 template<
bool _Const>
3296 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3297 using _Base = join_view::_Base<_Const>;
3299 template<
bool _Const2>
3301 __equal(
const _Iterator<_Const2>& __i)
const
3302 {
return __i._M_get_outer() == _M_end; }
3304 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3307 _Sentinel() =
default;
3310 _Sentinel(_Parent* __parent)
3311 : _M_end(ranges::
end(__parent->_M_base))
3315 _Sentinel(_Sentinel<!_Const> __s)
3316 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3320 template<
bool _Const2>
3321 requires sentinel_for<sentinel_t<_Base>,
3322 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3323 friend constexpr bool
3324 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3325 {
return __y.__equal(__x); }
3327 friend _Sentinel<!_Const>;
3330 _Vp _M_base = _Vp();
3331 [[no_unique_address]]
3332 __detail::__maybe_present_t<!forward_range<_Vp>,
3333 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3334 [[no_unique_address]]
3335 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3338 join_view()
requires default_initializable<_Vp> = default;
3341 join_view(_Vp __base)
3342 : _M_base(std::move(__base))
3346 base() const& requires copy_constructible<_Vp>
3356 if constexpr (forward_range<_Vp>)
3358 constexpr bool __use_const
3359 = (__detail::__simple_view<_Vp>
3360 && is_reference_v<range_reference_t<_Vp>>);
3361 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3365 _M_outer = ranges::begin(_M_base);
3366 return _Iterator<false>{
this};
3372 requires forward_range<const _Vp>
3373 && is_reference_v<range_reference_t<const _Vp>>
3374 && input_range<range_reference_t<const _Vp>>
3376 return _Iterator<true>{
this, ranges::begin(_M_base)};
3382 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3383 && forward_range<_InnerRange>
3384 && common_range<_Vp> && common_range<_InnerRange>)
3385 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3386 ranges::end(_M_base)};
3388 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3393 requires forward_range<const _Vp>
3394 && is_reference_v<range_reference_t<const _Vp>>
3395 && input_range<range_reference_t<const _Vp>>
3397 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3398 && forward_range<range_reference_t<const _Vp>>
3399 && common_range<const _Vp>
3400 && common_range<range_reference_t<const _Vp>>)
3401 return _Iterator<true>{
this, ranges::end(_M_base)};
3403 return _Sentinel<true>{
this};
3407 template<
typename _Range>
3408 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3414 template<
typename _Range>
3415 concept __can_join_view
3419 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3421 template<viewable_range _Range>
3422 requires __detail::__can_join_view<_Range>
3424 operator() [[nodiscard]] (_Range&& __r)
const
3431 static constexpr bool _S_has_simple_call_op =
true;
3434 inline constexpr _Join join;
3440 struct __require_constant;
3442 template<
typename _Range>
3443 concept __tiny_range = sized_range<_Range>
3445 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3446 && (remove_reference_t<_Range>::size() <= 1);
3448 template<
typename _Base>
3449 struct __lazy_split_view_outer_iter_cat
3452 template<forward_range _Base>
3453 struct __lazy_split_view_outer_iter_cat<_Base>
3454 {
using iterator_category = input_iterator_tag; };
3456 template<
typename _Base>
3457 struct __lazy_split_view_inner_iter_cat
3460 template<forward_range _Base>
3461 struct __lazy_split_view_inner_iter_cat<_Base>
3464 static constexpr auto
3467 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3468 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3469 return forward_iterator_tag{};
3474 using iterator_category =
decltype(_S_iter_cat());
3478 template<input_range _Vp, forward_range _Pattern>
3479 requires view<_Vp> && view<_Pattern>
3480 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3482 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3483 class lazy_split_view : public
view_interface<lazy_split_view<_Vp, _Pattern>>
3486 template<
bool _Const>
3487 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3489 template<
bool _Const>
3492 template<
bool _Const>
3494 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3497 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3498 using _Base = lazy_split_view::_Base<_Const>;
3502 {
return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3509 __current() noexcept
3511 if constexpr (forward_range<_Vp>)
3514 return *_M_parent->_M_current;
3518 __current() const noexcept
3520 if constexpr (forward_range<_Vp>)
3523 return *_M_parent->_M_current;
3526 _Parent* _M_parent =
nullptr;
3528 [[no_unique_address]]
3529 __detail::__maybe_present_t<forward_range<_Vp>,
3530 iterator_t<_Base>> _M_current
3531 =
decltype(_M_current)();
3532 bool _M_trailing_empty =
false;
3535 using iterator_concept = __conditional_t<forward_range<_Base>,
3536 forward_iterator_tag,
3537 input_iterator_tag>;
3539 using difference_type = range_difference_t<_Base>;
3541 struct value_type : view_interface<value_type>
3544 _OuterIter _M_i = _OuterIter();
3550 value_type(_OuterIter __i)
3551 : _M_i(std::
move(__i))
3557 constexpr _InnerIter<_Const>
3559 {
return _InnerIter<_Const>{_M_i}; }
3561 constexpr default_sentinel_t
3562 end() const noexcept
3566 _OuterIter() =
default;
3569 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3570 : _M_parent(__parent)
3574 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3575 requires forward_range<_Base>
3576 : _M_parent(__parent),
3581 _OuterIter(_OuterIter<!_Const> __i)
3583 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3584 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3585 _M_trailing_empty(__i._M_trailing_empty)
3588 constexpr value_type
3590 {
return value_type{*
this}; }
3592 constexpr _OuterIter&
3597 const auto __end = ranges::end(_M_parent->_M_base);
3598 if (__current() == __end)
3600 _M_trailing_empty =
false;
3603 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3604 if (__pbegin == __pend)
3606 else if constexpr (__detail::__tiny_range<_Pattern>)
3608 __current() = ranges::find(
std::move(__current()), __end,
3610 if (__current() != __end)
3613 if (__current() == __end)
3614 _M_trailing_empty =
true;
3621 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3625 if (__current() == __end)
3626 _M_trailing_empty =
true;
3629 }
while (++__current() != __end);
3633 constexpr decltype(
auto)
3636 if constexpr (forward_range<_Base>)
3646 friend constexpr bool
3647 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3648 requires forward_range<_Base>
3650 return __x._M_current == __y._M_current
3651 && __x._M_trailing_empty == __y._M_trailing_empty;
3654 friend constexpr bool
3655 operator==(
const _OuterIter& __x, default_sentinel_t)
3656 {
return __x.__at_end(); };
3658 friend _OuterIter<!_Const>;
3659 friend _InnerIter<_Const>;
3662 template<
bool _Const>
3664 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3667 using _Base = lazy_split_view::_Base<_Const>;
3672 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3673 auto __end = ranges::end(_M_i._M_parent->_M_base);
3674 if constexpr (__detail::__tiny_range<_Pattern>)
3676 const auto& __cur = _M_i_current();
3679 if (__pcur == __pend)
3680 return _M_incremented;
3681 return *__cur == *__pcur;
3685 auto __cur = _M_i_current();
3688 if (__pcur == __pend)
3689 return _M_incremented;
3692 if (*__cur != *__pcur)
3694 if (++__pcur == __pend)
3696 }
while (++__cur != __end);
3702 _M_i_current() noexcept
3703 {
return _M_i.__current(); }
3706 _M_i_current() const noexcept
3707 {
return _M_i.__current(); }
3709 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3710 bool _M_incremented =
false;
3713 using iterator_concept
3714 =
typename _OuterIter<_Const>::iterator_concept;
3716 using value_type = range_value_t<_Base>;
3717 using difference_type = range_difference_t<_Base>;
3719 _InnerIter() =
default;
3722 _InnerIter(_OuterIter<_Const> __i)
3723 : _M_i(std::
move(__i))
3726 constexpr const iterator_t<_Base>&
3727 base() const& noexcept
3728 {
return _M_i_current(); }
3730 constexpr iterator_t<_Base>
3731 base() &&
requires forward_range<_Vp>
3734 constexpr decltype(
auto)
3736 {
return *_M_i_current(); }
3738 constexpr _InnerIter&
3741 _M_incremented =
true;
3742 if constexpr (!forward_range<_Base>)
3743 if constexpr (_Pattern::size() == 0)
3749 constexpr decltype(
auto)
3752 if constexpr (forward_range<_Base>)
3762 friend constexpr bool
3763 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3764 requires forward_range<_Base>
3765 {
return __x._M_i == __y._M_i; }
3767 friend constexpr bool
3768 operator==(
const _InnerIter& __x, default_sentinel_t)
3769 {
return __x.__at_end(); }
3771 friend constexpr decltype(
auto)
3772 iter_move(
const _InnerIter& __i)
3773 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3774 {
return ranges::iter_move(__i._M_i_current()); }
3776 friend constexpr void
3777 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3778 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3779 __y._M_i_current())))
3780 requires indirectly_swappable<iterator_t<_Base>>
3781 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3784 _Vp _M_base = _Vp();
3785 _Pattern _M_pattern = _Pattern();
3786 [[no_unique_address]]
3787 __detail::__maybe_present_t<!forward_range<_Vp>,
3788 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3792 lazy_split_view()
requires (default_initializable<_Vp>
3793 && default_initializable<_Pattern>)
3797 lazy_split_view(_Vp __base, _Pattern __pattern)
3801 template<input_range _Range>
3802 requires constructible_from<_Vp, views::all_t<_Range>>
3803 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3805 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3806 : _M_base(views::all(
std::
forward<_Range>(__r))),
3807 _M_pattern(views::single(
std::
move(__e)))
3811 base() const& requires copy_constructible<_Vp>
3821 if constexpr (forward_range<_Vp>)
3823 constexpr bool __simple
3824 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3825 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3829 _M_current = ranges::begin(_M_base);
3830 return _OuterIter<false>{
this};
3835 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3837 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3841 end()
requires forward_range<_Vp> && common_range<_Vp>
3843 constexpr bool __simple
3844 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3845 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3851 if constexpr (forward_range<_Vp>
3852 && forward_range<const _Vp>
3853 && common_range<const _Vp>)
3854 return _OuterIter<true>{
this, ranges::end(_M_base)};
3860 template<
typename _Range,
typename _Pattern>
3861 lazy_split_view(_Range&&, _Pattern&&)
3862 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3864 template<input_range _Range>
3865 lazy_split_view(_Range&&, range_value_t<_Range>)
3866 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3872 template<
typename _Range,
typename _Pattern>
3873 concept __can_lazy_split_view
3877 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3879 template<viewable_range _Range,
typename _Pattern>
3880 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3882 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3887 using _RangeAdaptor<_LazySplit>::operator();
3888 static constexpr int _S_arity = 2;
3893 template<
typename _Pattern>
3894 static constexpr bool _S_has_simple_extra_args
3895 = is_scalar_v<_Pattern> || (view<_Pattern>
3896 && copy_constructible<_Pattern>);
3899 inline constexpr _LazySplit lazy_split;
3902 template<forward_range _Vp, forward_range _Pattern>
3903 requires view<_Vp> && view<_Pattern>
3904 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3906 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3909 _Vp _M_base = _Vp();
3910 _Pattern _M_pattern = _Pattern();
3911 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3917 split_view()
requires (default_initializable<_Vp>
3918 && default_initializable<_Pattern>)
3922 split_view(_Vp __base, _Pattern __pattern)
3926 template<forward_range _Range>
3927 requires constructible_from<_Vp, views::all_t<_Range>>
3928 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3930 split_view(_Range&& __r, range_value_t<_Range> __e)
3931 : _M_base(views::all(std::
forward<_Range>(__r))),
3932 _M_pattern(views::single(std::
move(__e)))
3936 base() const& requires copy_constructible<_Vp>
3946 if (!_M_cached_begin)
3947 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3948 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3954 if constexpr (common_range<_Vp>)
3955 return _Iterator{
this, ranges::end(_M_base), {}};
3957 return _Sentinel{
this};
3960 constexpr subrange<iterator_t<_Vp>>
3961 _M_find_next(iterator_t<_Vp> __it)
3963 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3964 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3976 split_view* _M_parent =
nullptr;
3977 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3978 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3979 bool _M_trailing_empty =
false;
3981 friend struct _Sentinel;
3984 using iterator_concept = forward_iterator_tag;
3985 using iterator_category = input_iterator_tag;
3986 using value_type = subrange<iterator_t<_Vp>>;
3987 using difference_type = range_difference_t<_Vp>;
3989 _Iterator() =
default;
3992 _Iterator(split_view* __parent,
3993 iterator_t<_Vp> __current,
3994 subrange<iterator_t<_Vp>> __next)
3995 : _M_parent(__parent),
3996 _M_cur(std::
move(__current)),
3997 _M_next(std::
move(__next))
4000 constexpr iterator_t<_Vp>
4004 constexpr value_type
4006 {
return {_M_cur, _M_next.begin()}; }
4008 constexpr _Iterator&
4011 _M_cur = _M_next.begin();
4012 if (_M_cur != ranges::end(_M_parent->_M_base))
4014 _M_cur = _M_next.end();
4015 if (_M_cur == ranges::end(_M_parent->_M_base))
4017 _M_trailing_empty =
true;
4018 _M_next = {_M_cur, _M_cur};
4021 _M_next = _M_parent->_M_find_next(_M_cur);
4024 _M_trailing_empty =
false;
4036 friend constexpr bool
4037 operator==(
const _Iterator& __x,
const _Iterator& __y)
4039 return __x._M_cur == __y._M_cur
4040 && __x._M_trailing_empty == __y._M_trailing_empty;
4047 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
4050 _M_equal(
const _Iterator& __x)
const
4051 {
return __x._M_cur == _M_end && !__x._M_trailing_empty; }
4054 _Sentinel() =
default;
4057 _Sentinel(split_view* __parent)
4058 : _M_end(ranges::
end(__parent->_M_base))
4061 friend constexpr bool
4062 operator==(
const _Iterator& __x,
const _Sentinel& __y)
4063 {
return __y._M_equal(__x); }
4067 template<
typename _Range,
typename _Pattern>
4068 split_view(_Range&&, _Pattern&&)
4069 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
4071 template<forward_range _Range>
4072 split_view(_Range&&, range_value_t<_Range>)
4073 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
4079 template<
typename _Range,
typename _Pattern>
4080 concept __can_split_view
4084 struct _Split : __adaptor::_RangeAdaptor<_Split>
4086 template<viewable_range _Range,
typename _Pattern>
4087 requires __detail::__can_split_view<_Range, _Pattern>
4089 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
4094 using _RangeAdaptor<_Split>::operator();
4095 static constexpr int _S_arity = 2;
4096 template<
typename _Pattern>
4097 static constexpr bool _S_has_simple_extra_args
4098 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
4101 inline constexpr _Split split;
4108 template<input_or_output_iterator _Iter>
4110 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
4112 if constexpr (contiguous_iterator<_Iter>)
4114 else if constexpr (random_access_iterator<_Iter>)
4115 return subrange(__i, __i + __n);
4117 return subrange(counted_iterator(
std::move(__i), __n),
4122 inline constexpr _Counted counted{};
4126 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
4127 class common_view : public view_interface<common_view<_Vp>>
4130 _Vp _M_base = _Vp();
4133 common_view()
requires default_initializable<_Vp> = default;
4136 common_view(_Vp __r)
4137 : _M_base(
std::move(__r))
4141 base() const& requires copy_constructible<_Vp>
4151 begin()
requires (!__detail::__simple_view<_Vp>)
4153 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4154 return ranges::begin(_M_base);
4156 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4157 (ranges::begin(_M_base));
4161 begin() const requires range<const _Vp>
4163 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4164 return ranges::begin(_M_base);
4166 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4167 (ranges::begin(_M_base));
4171 end()
requires (!__detail::__simple_view<_Vp>)
4173 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4174 return ranges::begin(_M_base) + ranges::size(_M_base);
4176 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4177 (ranges::end(_M_base));
4181 end() const requires range<const _Vp>
4183 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4184 return ranges::begin(_M_base) + ranges::size(_M_base);
4186 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4187 (ranges::end(_M_base));
4191 size()
requires sized_range<_Vp>
4192 {
return ranges::size(_M_base); }
4195 size() const requires sized_range<const _Vp>
4196 {
return ranges::size(_M_base); }
4199 template<
typename _Range>
4200 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4202 template<
typename _Tp>
4203 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4204 = enable_borrowed_range<_Tp>;
4210 template<
typename _Range>
4211 concept __already_common = common_range<_Range>
4214 template<
typename _Range>
4215 concept __can_common_view
4219 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4221 template<viewable_range _Range>
4222 requires __detail::__already_common<_Range>
4223 || __detail::__can_common_view<_Range>
4225 operator() [[nodiscard]] (_Range&& __r)
const
4227 if constexpr (__detail::__already_common<_Range>)
4233 static constexpr bool _S_has_simple_call_op =
true;
4236 inline constexpr _Common common;
4240 requires bidirectional_range<_Vp>
4241 class reverse_view :
public view_interface<reverse_view<_Vp>>
4244 static constexpr bool _S_needs_cached_begin
4245 = !common_range<_Vp> && !(random_access_range<_Vp>
4246 && sized_sentinel_for<sentinel_t<_Vp>,
4249 _Vp _M_base = _Vp();
4250 [[no_unique_address]]
4251 __detail::__maybe_present_t<_S_needs_cached_begin,
4252 __detail::_CachedPosition<_Vp>>
4256 reverse_view()
requires default_initializable<_Vp> = default;
4259 reverse_view(_Vp __r)
4260 : _M_base(std::move(__r))
4264 base() const& requires copy_constructible<_Vp>
4271 constexpr reverse_iterator<iterator_t<_Vp>>
4274 if constexpr (_S_needs_cached_begin)
4275 if (_M_cached_begin._M_has_value())
4278 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4279 if constexpr (_S_needs_cached_begin)
4280 _M_cached_begin._M_set(_M_base, __it);
4285 begin()
requires common_range<_Vp>
4289 begin() const requires common_range<const _Vp>
4292 constexpr reverse_iterator<iterator_t<_Vp>>
4297 end() const requires common_range<const _Vp>
4301 size()
requires sized_range<_Vp>
4302 {
return ranges::size(_M_base); }
4305 size() const requires sized_range<const _Vp>
4306 {
return ranges::size(_M_base); }
4309 template<
typename _Range>
4310 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4312 template<
typename _Tp>
4313 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4314 = enable_borrowed_range<_Tp>;
4321 inline constexpr bool __is_reversible_subrange =
false;
4323 template<
typename _Iter, subrange_kind _Kind>
4324 inline constexpr bool
4325 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4326 reverse_iterator<_Iter>,
4330 inline constexpr bool __is_reverse_view =
false;
4332 template<
typename _Vp>
4333 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4335 template<
typename _Range>
4336 concept __can_reverse_view
4340 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4342 template<viewable_range _Range>
4343 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4344 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4345 || __detail::__can_reverse_view<_Range>
4347 operator() [[nodiscard]] (_Range&& __r)
const
4349 using _Tp = remove_cvref_t<_Range>;
4350 if constexpr (__detail::__is_reverse_view<_Tp>)
4352#ifdef __cpp_lib_optional_range_support
4353 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
4356 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4358 using _Iter =
decltype(ranges::begin(__r).base());
4359 if constexpr (sized_range<_Tp>)
4360 return subrange<_Iter, _Iter, subrange_kind::sized>
4361 {__r.end().base(), __r.begin().base(), __r.size()};
4363 return subrange<_Iter, _Iter, subrange_kind::unsized>
4364 {__r.end().base(), __r.begin().base()};
4370 static constexpr bool _S_has_simple_call_op =
true;
4373 inline constexpr _Reverse reverse;
4378#if __cpp_lib_tuple_like
4379 template<
typename _Tp,
size_t _Nm>
4380 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4382 template<
typename _Tp,
size_t _Nm>
4383 concept __has_tuple_element =
requires(_Tp __t)
4385 typename tuple_size<_Tp>::type;
4386 requires _Nm < tuple_size_v<_Tp>;
4387 typename tuple_element_t<_Nm, _Tp>;
4388 { std::get<_Nm>(__t) }
4389 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4393 template<
typename _Tp,
size_t _Nm>
4394 concept __returnable_element
4395 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4398 template<input_range _Vp,
size_t _Nm>
4400 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4401 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4403 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4404 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4407 elements_view()
requires default_initializable<_Vp> = default;
4410 elements_view(_Vp __base)
4411 : _M_base(std::move(__base))
4415 base() const& requires copy_constructible<_Vp>
4423 begin()
requires (!__detail::__simple_view<_Vp>)
4424 {
return _Iterator<false>(ranges::begin(_M_base)); }
4427 begin() const requires range<const _Vp>
4428 {
return _Iterator<true>(ranges::begin(_M_base)); }
4431 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4432 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4435 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4436 {
return _Iterator<false>{ranges::end(_M_base)}; }
4439 end() const requires range<const _Vp>
4440 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4443 end() const requires common_range<const _Vp>
4444 {
return _Iterator<true>{ranges::end(_M_base)}; }
4447 size()
requires sized_range<_Vp>
4448 {
return ranges::size(_M_base); }
4451 size() const requires sized_range<const _Vp>
4452 {
return ranges::size(_M_base); }
4455 template<
bool _Const>
4456 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4458 template<
bool _Const>
4462 template<
bool _Const>
4463 requires forward_range<_Base<_Const>>
4464 struct __iter_cat<_Const>
4467 static auto _S_iter_cat()
4469 using _Base = elements_view::_Base<_Const>;
4470 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4471 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4472 if constexpr (!is_lvalue_reference_v<_Res>)
4473 return input_iterator_tag{};
4474 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4475 return random_access_iterator_tag{};
4480 using iterator_category =
decltype(_S_iter_cat());
4483 template<
bool _Const>
4486 template<
bool _Const>
4487 struct _Iterator : __iter_cat<_Const>
4490 using _Base = elements_view::_Base<_Const>;
4492 iterator_t<_Base> _M_current = iterator_t<_Base>();
4494 static constexpr decltype(
auto)
4495 _S_get_element(
const iterator_t<_Base>& __i)
4497 if constexpr (is_reference_v<range_reference_t<_Base>>)
4498 return std::get<_Nm>(*__i);
4501 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4502 return static_cast<_Et
>(std::get<_Nm>(*__i));
4509 if constexpr (random_access_range<_Base>)
4510 return random_access_iterator_tag{};
4511 else if constexpr (bidirectional_range<_Base>)
4512 return bidirectional_iterator_tag{};
4513 else if constexpr (forward_range<_Base>)
4514 return forward_iterator_tag{};
4516 return input_iterator_tag{};
4519 friend _Iterator<!_Const>;
4522 using iterator_concept =
decltype(_S_iter_concept());
4525 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4526 using difference_type = range_difference_t<_Base>;
4528 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4531 _Iterator(iterator_t<_Base> __current)
4532 : _M_current(std::move(__current))
4536 _Iterator(_Iterator<!_Const> __i)
4537 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4541 constexpr const iterator_t<_Base>&
4542 base() const& noexcept
4543 {
return _M_current; }
4545 constexpr iterator_t<_Base>
4549 constexpr decltype(
auto)
4551 {
return _S_get_element(_M_current); }
4553 constexpr _Iterator&
4565 operator++(
int)
requires forward_range<_Base>
4572 constexpr _Iterator&
4573 operator--()
requires bidirectional_range<_Base>
4580 operator--(
int)
requires bidirectional_range<_Base>
4587 constexpr _Iterator&
4588 operator+=(difference_type __n)
4589 requires random_access_range<_Base>
4595 constexpr _Iterator&
4596 operator-=(difference_type __n)
4597 requires random_access_range<_Base>
4603 constexpr decltype(
auto)
4604 operator[](difference_type __n)
const
4605 requires random_access_range<_Base>
4606 {
return _S_get_element(_M_current + __n); }
4608 friend constexpr bool
4609 operator==(
const _Iterator& __x,
const _Iterator& __y)
4610 requires equality_comparable<iterator_t<_Base>>
4611 {
return __x._M_current == __y._M_current; }
4613 friend constexpr bool
4614 operator<(
const _Iterator& __x,
const _Iterator& __y)
4615 requires random_access_range<_Base>
4616 {
return __x._M_current < __y._M_current; }
4618 friend constexpr bool
4619 operator>(
const _Iterator& __x,
const _Iterator& __y)
4620 requires random_access_range<_Base>
4621 {
return __y._M_current < __x._M_current; }
4623 friend constexpr bool
4624 operator<=(
const _Iterator& __x,
const _Iterator& __y)
4625 requires random_access_range<_Base>
4626 {
return !(__y._M_current > __x._M_current); }
4628 friend constexpr bool
4629 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4630 requires random_access_range<_Base>
4631 {
return !(__x._M_current > __y._M_current); }
4633#ifdef __cpp_lib_three_way_comparison
4634 friend constexpr auto
4635 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4636 requires random_access_range<_Base>
4637 && three_way_comparable<iterator_t<_Base>>
4638 {
return __x._M_current <=> __y._M_current; }
4641 friend constexpr _Iterator
4642 operator+(
const _Iterator& __x, difference_type __y)
4643 requires random_access_range<_Base>
4644 {
return _Iterator{__x} += __y; }
4646 friend constexpr _Iterator
4647 operator+(difference_type __x,
const _Iterator& __y)
4648 requires random_access_range<_Base>
4649 {
return __y + __x; }
4651 friend constexpr _Iterator
4652 operator-(
const _Iterator& __x, difference_type __y)
4653 requires random_access_range<_Base>
4654 {
return _Iterator{__x} -= __y; }
4658 friend constexpr difference_type
4659 operator-(
const _Iterator& __x,
const _Iterator& __y)
4660 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4661 {
return __x._M_current - __y._M_current; }
4663 template <
bool>
friend struct _Sentinel;
4666 template<
bool _Const>
4670 template<
bool _Const2>
4672 _M_equal(
const _Iterator<_Const2>& __x)
const
4673 {
return __x._M_current == _M_end; }
4675 template<
bool _Const2>
4677 _M_distance_from(
const _Iterator<_Const2>& __i)
const
4678 {
return _M_end - __i._M_current; }
4680 using _Base = elements_view::_Base<_Const>;
4681 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4684 _Sentinel() =
default;
4687 _Sentinel(sentinel_t<_Base> __end)
4688 : _M_end(std::
move(__end))
4692 _Sentinel(_Sentinel<!_Const> __other)
4694 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4698 constexpr sentinel_t<_Base>
4702 template<
bool _Const2>
4703 requires sentinel_for<sentinel_t<_Base>,
4704 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4705 friend constexpr bool
4706 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4707 {
return __y._M_equal(__x); }
4709 template<
bool _Const2,
4710 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4711 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4712 friend constexpr range_difference_t<_Base2>
4713 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4714 {
return -__y._M_distance_from(__x); }
4716 template<
bool _Const2,
4717 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4718 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4719 friend constexpr range_difference_t<_Base2>
4720 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4721 {
return __x._M_distance_from(__y); }
4723 friend _Sentinel<!_Const>;
4726 _Vp _M_base = _Vp();
4729 template<
typename _Tp,
size_t _Nm>
4730 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4731 = enable_borrowed_range<_Tp>;
4735 template<
typename _Range>
4736 using keys_view = elements_view<_Range, 0>;
4738 template<
typename _Range>
4739 using values_view = elements_view<_Range, 1>;
4745 template<
size_t _Nm,
typename _Range>
4746 concept __can_elements_view
4750 template<
size_t _Nm>
4751 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4753 template<viewable_range _Range>
4754 requires __detail::__can_elements_view<_Nm, _Range>
4756 operator() [[nodiscard]] (_Range&& __r)
const
4761 static constexpr bool _S_has_simple_call_op =
true;
4764 template<
size_t _Nm>
4765 inline constexpr _Elements<_Nm> elements;
4766 inline constexpr auto keys = elements<0>;
4767 inline constexpr auto values = elements<1>;
4770#ifdef __cpp_lib_ranges_zip
4773 template<
typename... _Rs>
4774 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4775 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4776 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4778 template<
typename _Fp,
typename _Tuple>
4780 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4782 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4783 return tuple<invoke_result_t<_Fp&, _Ts>...>
4788 template<
typename _Fp,
typename _Tuple>
4790 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4792 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4798 template<input_range... _Vs>
4799 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4800 class zip_view : public view_interface<zip_view<_Vs...>>
4802 tuple<_Vs...> _M_views;
4804 template<
bool>
class _Iterator;
4805 template<
bool>
class _Sentinel;
4808 zip_view() =
default;
4811 zip_view(_Vs... __views)
4812 : _M_views(
std::
move(__views)...)
4816 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4817 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4820 begin() const requires (range<const _Vs> && ...)
4821 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4824 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4826 if constexpr (!__detail::__zip_is_common<_Vs...>)
4827 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4828 else if constexpr ((random_access_range<_Vs> && ...))
4829 return begin() + iter_difference_t<_Iterator<false>>(
size());
4831 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4835 end() const requires (range<const _Vs> && ...)
4837 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4838 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4839 else if constexpr ((random_access_range<const _Vs> && ...))
4840 return begin() + iter_difference_t<_Iterator<true>>(
size());
4842 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4846 size()
requires (sized_range<_Vs> && ...)
4848 return std::apply([](
auto... sizes) {
4849 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4850 return ranges::min({_CT(sizes)...});
4851 }, __detail::__tuple_transform(ranges::size, _M_views));
4855 size() const requires (sized_range<const _Vs> && ...)
4857 return std::apply([](
auto... sizes) {
4858 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4859 return ranges::min({_CT(sizes)...});
4860 }, __detail::__tuple_transform(ranges::size, _M_views));
4864 template<
typename... _Rs>
4865 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4867 template<
typename... _Views>
4868 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4869 = (enable_borrowed_range<_Views> && ...);
4873 template<
bool _Const,
typename... _Vs>
4874 concept __all_random_access
4875 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4877 template<
bool _Const,
typename... _Vs>
4878 concept __all_bidirectional
4879 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4881 template<
bool _Const,
typename... _Vs>
4882 concept __all_forward
4883 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4885 template<
bool _Const,
typename... _Views>
4886 struct __zip_view_iter_cat
4889 template<
bool _Const,
typename... _Views>
4890 requires __all_forward<_Const, _Views...>
4891 struct __zip_view_iter_cat<_Const, _Views...>
4892 {
using iterator_category = input_iterator_tag; };
4895 template<input_range... _Vs>
4896 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4897 template<bool _Const>
4898 class zip_view<_Vs...>::_Iterator
4899 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4901#ifdef _GLIBCXX_CLANG
4904 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4907 _Iterator(
decltype(_M_current) __current)
4908 : _M_current(
std::
move(__current))
4914 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4915 return random_access_iterator_tag{};
4916 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4917 return bidirectional_iterator_tag{};
4918 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4919 return forward_iterator_tag{};
4921 return input_iterator_tag{};
4924#ifndef _GLIBCXX_CLANG
4925 template<move_constructible _Fp, input_range... _Ws>
4926 requires (view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4927 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4928 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4929 friend class zip_transform_view;
4934 using iterator_concept =
decltype(_S_iter_concept());
4936 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4937 using difference_type
4938 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4940 _Iterator() =
default;
4943 _Iterator(_Iterator<!_Const> __i)
4945 && (convertible_to<iterator_t<_Vs>,
4946 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4947 : _M_current(
std::
move(__i._M_current))
4953 auto __f = [](
auto& __i) ->
decltype(
auto) {
4956 return __detail::__tuple_transform(__f, _M_current);
4959 constexpr _Iterator&
4962 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4972 requires __detail::__all_forward<_Const, _Vs...>
4979 constexpr _Iterator&
4981 requires __detail::__all_bidirectional<_Const, _Vs...>
4983 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4989 requires __detail::__all_bidirectional<_Const, _Vs...>
4996 constexpr _Iterator&
4997 operator+=(difference_type __x)
4998 requires __detail::__all_random_access<_Const, _Vs...>
5000 auto __f = [&]<
typename _It>(_It& __i) {
5001 __i += iter_difference_t<_It>(__x);
5003 __detail::__tuple_for_each(__f, _M_current);
5007 constexpr _Iterator&
5008 operator-=(difference_type __x)
5009 requires __detail::__all_random_access<_Const, _Vs...>
5011 auto __f = [&]<
typename _It>(_It& __i) {
5012 __i -= iter_difference_t<_It>(__x);
5014 __detail::__tuple_for_each(__f, _M_current);
5019 operator[](difference_type __n)
const
5020 requires __detail::__all_random_access<_Const, _Vs...>
5022 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
5023 return __i[iter_difference_t<_It>(__n)];
5025 return __detail::__tuple_transform(__f, _M_current);
5028 friend constexpr bool
5029 operator==(
const _Iterator& __x,
const _Iterator& __y)
5030 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5032 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
5033 return __x._M_current == __y._M_current;
5036 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
5040 friend constexpr auto
5041 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5042 requires __detail::__all_random_access<_Const, _Vs...>
5043 {
return __x._M_current <=> __y._M_current; }
5045 friend constexpr _Iterator
5046 operator+(
const _Iterator& __i, difference_type __n)
5047 requires __detail::__all_random_access<_Const, _Vs...>
5054 friend constexpr _Iterator
5055 operator+(difference_type __n,
const _Iterator& __i)
5056 requires __detail::__all_random_access<_Const, _Vs...>
5063 friend constexpr _Iterator
5064 operator-(
const _Iterator& __i, difference_type __n)
5065 requires __detail::__all_random_access<_Const, _Vs...>
5072 friend constexpr difference_type
5073 operator-(
const _Iterator& __x,
const _Iterator& __y)
5074 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
5075 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5078 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
5079 - std::get<_Is>(__y._M_current))...},
5081 [](difference_type __i) {
5082 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5087 friend constexpr auto
5088 iter_move(
const _Iterator& __i)
5089 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5091 friend constexpr void
5092 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5093 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5096 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
5100 friend class zip_view;
5103 template<input_range... _Vs>
5104 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
5105 template<bool _Const>
5106 class zip_view<_Vs...>::_Sentinel
5108 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
5111 _Sentinel(
decltype(_M_end) __end)
5115 friend class zip_view;
5118 _Sentinel() =
default;
5121 _Sentinel(_Sentinel<!_Const> __i)
5123 && (convertible_to<sentinel_t<_Vs>,
5124 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5125 : _M_end(
std::
move(__i._M_end))
5128 template<
bool _OtherConst>
5129 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5130 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5131 friend constexpr bool
5132 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5135 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
5139 template<
bool _OtherConst>
5140 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5141 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5142 friend constexpr auto
5143 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5146 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
5148 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
5151 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5156 template<
bool _OtherConst>
5157 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5158 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5159 friend constexpr auto
5160 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5161 {
return -(__x - __y); }
5168 template<
typename... _Ts>
5169 concept __can_zip_view
5175 template<
typename... _Ts>
5176 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5178 operator() [[nodiscard]] (_Ts&&... __ts)
const
5180 if constexpr (
sizeof...(_Ts) == 0)
5181 return views::empty<tuple<>>;
5187 inline constexpr _Zip zip;
5192 template<
typename _Range,
bool _Const>
5193 using __range_iter_cat
5194 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5197 template<move_constructible _Fp, input_range... _Vs>
5198 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5199 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5200 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5201 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5203 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5204 zip_view<_Vs...> _M_zip;
5206 using _InnerView = zip_view<_Vs...>;
5208 template<
bool _Const>
5209 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5211 template<
bool _Const>
5212 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5214 template<
bool _Const>
5215 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5217 template<
bool _Const>
5221 template<
bool _Const>
5222 requires forward_range<_Base<_Const>>
5223 struct __iter_cat<_Const>
5229 using __detail::__maybe_const_t;
5230 using __detail::__range_iter_cat;
5231 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5232 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5235 if constexpr (!is_reference_v<_Res>)
5236 return input_iterator_tag{};
5237 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5238 random_access_iterator_tag> && ...))
5239 return random_access_iterator_tag{};
5240 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5241 bidirectional_iterator_tag> && ...))
5242 return bidirectional_iterator_tag{};
5243 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5244 forward_iterator_tag> && ...))
5245 return forward_iterator_tag{};
5247 return input_iterator_tag{};
5250 using iterator_category =
decltype(_S_iter_cat());
5253 template<
bool>
class _Iterator;
5254 template<
bool>
class _Sentinel;
5257 zip_transform_view() =
default;
5260 zip_transform_view(_Fp __fun, _Vs... __views)
5266 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5270 requires range<const _InnerView>
5271 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5272 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5277 if constexpr (common_range<_InnerView>)
5278 return _Iterator<false>(*
this, _M_zip.end());
5280 return _Sentinel<false>(_M_zip.end());
5285 requires range<const _InnerView>
5286 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5288 if constexpr (common_range<const _InnerView>)
5289 return _Iterator<true>(*
this, _M_zip.end());
5291 return _Sentinel<true>(_M_zip.end());
5295 size()
requires sized_range<_InnerView>
5296 {
return _M_zip.size(); }
5299 size() const requires sized_range<const _InnerView>
5300 {
return _M_zip.size(); }
5303 template<
class _Fp,
class... Rs>
5304 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5306 template<move_constructible _Fp, input_range... _Vs>
5307 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5308 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5309 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5310 template<bool _Const>
5311 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5313 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5314 using _Fun_handle = __detail::__func_handle_t<
5315 __detail::__maybe_const_t<_Const, _Fp>,
5316 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
5318 [[no_unique_address]] _Fun_handle _M_fun;
5319 __ziperator<_Const> _M_inner;
5322 _Iterator(_Fun_handle __fun, __ziperator<_Const> __inner)
5323 : _M_fun(__fun), _M_inner(
std::
move(__inner))
5327 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5328 : _M_fun(*__parent._M_fun), _M_inner(
std::
move(__inner))
5331 friend class zip_transform_view;
5335 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5337 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5338 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5339 using difference_type = range_difference_t<_Base<_Const>>;
5341 _Iterator() =
default;
5344 _Iterator(_Iterator<!_Const> __i)
5345 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5346 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
5349 constexpr decltype(
auto)
5352 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5353 return _M_fun._M_call_deref(__iters...);
5354 }, _M_inner._M_current);
5357 constexpr _Iterator&
5369 operator++(
int)
requires forward_range<_Base<_Const>>
5376 constexpr _Iterator&
5377 operator--()
requires bidirectional_range<_Base<_Const>>
5384 operator--(
int)
requires bidirectional_range<_Base<_Const>>
5391 constexpr _Iterator&
5392 operator+=(difference_type __x)
requires random_access_range<_Base<_Const>>
5398 constexpr _Iterator&
5399 operator-=(difference_type __x)
requires random_access_range<_Base<_Const>>
5405 constexpr decltype(
auto)
5406 operator[](difference_type __n)
const requires random_access_range<_Base<_Const>>
5408 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5409 return _M_fun._M_call_subscript(__n, __iters...);
5410 }, _M_inner._M_current);
5413 friend constexpr bool
5414 operator==(
const _Iterator& __x,
const _Iterator& __y)
5415 requires equality_comparable<__ziperator<_Const>>
5416 {
return __x._M_inner == __y._M_inner; }
5418 friend constexpr auto
5419 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5420 requires random_access_range<_Base<_Const>>
5421 {
return __x._M_inner <=> __y._M_inner; }
5423 friend constexpr _Iterator
5424 operator+(
const _Iterator& __i, difference_type __n)
5425 requires random_access_range<_Base<_Const>>
5426 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5428 friend constexpr _Iterator
5429 operator+(difference_type __n,
const _Iterator& __i)
5430 requires random_access_range<_Base<_Const>>
5431 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5433 friend constexpr _Iterator
5434 operator-(
const _Iterator& __i, difference_type __n)
5435 requires random_access_range<_Base<_Const>>
5436 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
5438 friend constexpr difference_type
5439 operator-(
const _Iterator& __x,
const _Iterator& __y)
5440 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5441 {
return __x._M_inner - __y._M_inner; }
5444 template<move_constructible _Fp, input_range... _Vs>
5445 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5446 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5447 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5448 template<bool _Const>
5449 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5451 __zentinel<_Const> _M_inner;
5454 _Sentinel(__zentinel<_Const> __inner)
5458 friend class zip_transform_view;
5461 _Sentinel() =
default;
5464 _Sentinel(_Sentinel<!_Const> __i)
5465 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5469 template<
bool _OtherConst>
5470 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5471 friend constexpr bool
5472 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5473 {
return __x._M_inner == __y._M_inner; }
5475 template<
bool _OtherConst>
5476 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5477 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5478 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5479 {
return __x._M_inner - __y._M_inner; }
5481 template<
bool _OtherConst>
5482 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5483 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5484 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5485 {
return __x._M_inner - __y._M_inner; }
5492 template<
typename _Fp,
typename... _Ts>
5493 concept __can_zip_transform_view
5497 struct _ZipTransform
5499 template<
typename _Fp>
5500 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5501 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5503 operator() [[nodiscard]] (_Fp&&)
const
5505 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5508 template<
typename _Fp,
typename... _Ts>
5509 requires (
sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5511 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5517 inline constexpr _ZipTransform zip_transform;
5520 template<forward_range _Vp,
size_t _Nm>
5521 requires view<_Vp> && (_Nm > 0)
5522 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5524 _Vp _M_base = _Vp();
5526 template<
bool>
class _Iterator;
5527 template<
bool>
class _Sentinel;
5529 struct __as_sentinel
5533 adjacent_view()
requires default_initializable<_Vp> = default;
5536 adjacent_view(_Vp __base)
5537 : _M_base(
std::move(__base))
5543 base() const & requires copy_constructible<_Vp>
5551 begin()
requires (!__detail::__simple_view<_Vp>)
5552 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5555 begin() const requires range<const _Vp>
5556 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5559 end()
requires (!__detail::__simple_view<_Vp>)
5561 if constexpr (common_range<_Vp>)
5562 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5564 return _Sentinel<false>(ranges::end(_M_base));
5568 end() const requires range<const _Vp>
5570 if constexpr (common_range<const _Vp>)
5571 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5573 return _Sentinel<true>(ranges::end(_M_base));
5577 size()
requires sized_range<_Vp>
5579 using _ST =
decltype(ranges::size(_M_base));
5580 using _CT = common_type_t<_ST, size_t>;
5581 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5583 return static_cast<_ST
>(__sz);
5587 size() const requires sized_range<const _Vp>
5589 using _ST =
decltype(ranges::size(_M_base));
5590 using _CT = common_type_t<_ST, size_t>;
5591 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5593 return static_cast<_ST
>(__sz);
5597 template<
typename _Vp,
size_t _Nm>
5598 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5599 = enable_borrowed_range<_Vp>;
5604 template<
typename _Tp,
size_t _Nm>
5605 using __repeated_tuple =
typename __make_tuple<array<_Tp, _Nm>>::__type;
5609 template<
typename _Fp,
size_t _Nm>
5612 template<
typename... _Ts>
5613 static invoke_result_t<_Fp, _Ts...>
5614 __tuple_apply(
const tuple<_Ts...>&);
5616 template<
typename _Tp>
5617 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5622 template<forward_range _Vp,
size_t _Nm>
5623 requires view<_Vp> && (_Nm > 0)
5624 template<bool _Const>
5625 class adjacent_view<_Vp, _Nm>::_Iterator
5627#ifdef _GLIBCXX_CLANG
5630 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5631 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5634 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5636 for (
auto& __i : _M_current)
5639 ranges::advance(__first, 1, __last);
5644 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5646 if constexpr (!bidirectional_range<_Base>)
5647 for (
auto& __it : _M_current)
5650 for (
size_t __i = 0; __i < _Nm; ++__i)
5652 _M_current[_Nm - 1 - __i] = __last;
5653 ranges::advance(__last, -1, __first);
5660 if constexpr (random_access_range<_Base>)
5661 return random_access_iterator_tag{};
5662 else if constexpr (bidirectional_range<_Base>)
5663 return bidirectional_iterator_tag{};
5665 return forward_iterator_tag{};
5668 friend class adjacent_view;
5670#ifndef _GLIBCXX_CLANG
5671 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5672 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5673 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5674 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5675 range_reference_t<_Wp>>>
5676 friend class adjacent_transform_view;
5680 using iterator_category = input_iterator_tag;
5681 using iterator_concept =
decltype(_S_iter_concept());
5682 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5683 using difference_type = range_difference_t<_Base>;
5685 _Iterator() =
default;
5688 _Iterator(_Iterator<!_Const> __i)
5689 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5691 for (
size_t __j = 0; __j < _Nm; ++__j)
5692 _M_current[__j] =
std::move(__i._M_current[__j]);
5698 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5699 return __detail::__tuple_transform(__f, _M_current);
5702 constexpr _Iterator&
5705 for (
auto& __i : _M_current)
5718 constexpr _Iterator&
5719 operator--()
requires bidirectional_range<_Base>
5721 for (
auto& __i : _M_current)
5727 operator--(
int)
requires bidirectional_range<_Base>
5734 constexpr _Iterator&
5735 operator+=(difference_type __x)
5736 requires random_access_range<_Base>
5738 for (
auto& __i : _M_current)
5743 constexpr _Iterator&
5744 operator-=(difference_type __x)
5745 requires random_access_range<_Base>
5747 for (
auto& __i : _M_current)
5753 operator[](difference_type __n)
const
5754 requires random_access_range<_Base>
5756 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5757 return __detail::__tuple_transform(__f, _M_current);
5760 friend constexpr bool
5761 operator==(
const _Iterator& __x,
const _Iterator& __y)
5762 {
return __x._M_current.back() == __y._M_current.back(); }
5764 friend constexpr bool
5765 operator<(
const _Iterator& __x,
const _Iterator& __y)
5766 requires random_access_range<_Base>
5767 {
return __x._M_current.back() < __y._M_current.back(); }
5769 friend constexpr bool
5770 operator>(
const _Iterator& __x,
const _Iterator& __y)
5771 requires random_access_range<_Base>
5772 {
return __y < __x; }
5774 friend constexpr bool
5775 operator<=(
const _Iterator& __x,
const _Iterator& __y)
5776 requires random_access_range<_Base>
5777 {
return !(__y < __x); }
5779 friend constexpr bool
5780 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5781 requires random_access_range<_Base>
5782 {
return !(__x < __y); }
5784 friend constexpr auto
5785 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5786 requires random_access_range<_Base>
5787 && three_way_comparable<iterator_t<_Base>>
5788 {
return __x._M_current.back() <=> __y._M_current.back(); }
5790 friend constexpr _Iterator
5791 operator+(
const _Iterator& __i, difference_type __n)
5792 requires random_access_range<_Base>
5799 friend constexpr _Iterator
5800 operator+(difference_type __n,
const _Iterator& __i)
5801 requires random_access_range<_Base>
5808 friend constexpr _Iterator
5809 operator-(
const _Iterator& __i, difference_type __n)
5810 requires random_access_range<_Base>
5817 friend constexpr difference_type
5818 operator-(
const _Iterator& __x,
const _Iterator& __y)
5819 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5820 {
return __x._M_current.back() - __y._M_current.back(); }
5822 friend constexpr auto
5823 iter_move(
const _Iterator& __i)
5824 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5826 friend constexpr void
5827 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5828 requires indirectly_swappable<iterator_t<_Base>>
5830 for (
size_t __i = 0; __i < _Nm; __i++)
5831 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5835 template<forward_range _Vp,
size_t _Nm>
5836 requires view<_Vp> && (_Nm > 0)
5837 template<bool _Const>
5838 class adjacent_view<_Vp, _Nm>::_Sentinel
5840 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5842 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5845 _Sentinel(sentinel_t<_Base> __end)
5849 friend class adjacent_view;
5852 _Sentinel() =
default;
5855 _Sentinel(_Sentinel<!_Const> __i)
5856 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5860 template<
bool _OtherConst>
5861 requires sentinel_for<sentinel_t<_Base>,
5862 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5863 friend constexpr bool
5864 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5865 {
return __x._M_current.back() == __y._M_end; }
5867 template<
bool _OtherConst>
5868 requires sized_sentinel_for<sentinel_t<_Base>,
5869 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5870 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5871 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5872 {
return __x._M_current.back() - __y._M_end; }
5874 template<
bool _OtherConst>
5875 requires sized_sentinel_for<sentinel_t<_Base>,
5876 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5877 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5878 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5879 {
return __y._M_end - __x._M_current.back(); }
5886 template<
size_t _Nm,
typename _Range>
5887 concept __can_adjacent_view
5891 template<
size_t _Nm>
5892 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5894 template<viewable_range _Range>
5895 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5897 operator() [[nodiscard]] (_Range&& __r)
const
5899 if constexpr (_Nm == 0)
5900 return views::empty<tuple<>>;
5906 template<
size_t _Nm>
5907 inline constexpr _Adjacent<_Nm> adjacent;
5909 inline constexpr auto pairwise = adjacent<2>;
5912 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5913 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5914 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5915 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5916 range_reference_t<_Vp>>>
5917 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5919 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5920 adjacent_view<_Vp, _Nm> _M_inner;
5922 using _InnerView = adjacent_view<_Vp, _Nm>;
5924 template<
bool _Const>
5925 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5927 template<
bool _Const>
5928 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5930 template<
bool>
class _Iterator;
5931 template<
bool>
class _Sentinel;
5934 adjacent_transform_view() =
default;
5937 adjacent_transform_view(_Vp __base, _Fp __fun)
5945 base() const & requires copy_constructible<_Vp>
5946 {
return _M_inner.base(); }
5954 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5958 requires range<const _InnerView>
5959 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5960 range_reference_t<const _Vp>>
5961 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5966 if constexpr (common_range<_InnerView>)
5967 return _Iterator<false>(*
this, _M_inner.end());
5969 return _Sentinel<false>(_M_inner.end());
5974 requires range<const _InnerView>
5975 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5976 range_reference_t<const _Vp>>
5978 if constexpr (common_range<const _InnerView>)
5979 return _Iterator<true>(*
this, _M_inner.end());
5981 return _Sentinel<true>(_M_inner.end());
5985 size()
requires sized_range<_InnerView>
5986 {
return _M_inner.size(); }
5989 size() const requires sized_range<const _InnerView>
5990 {
return _M_inner.size(); }
5993 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5994 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5995 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5996 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5997 range_reference_t<_Vp>>>
5998 template<bool _Const>
5999 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
6001 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
6002 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6004 return __detail::__func_handle_t<
6005 __detail::__maybe_const_t<_Const, _Fp>,
6006 iterator_t<__detail::__maybe_const_t<(_Ids, _Const), _Vp>>...>();
6007 }(make_index_sequence<_Nm>()));
6009 [[no_unique_address]] _Fun_handle _M_fun;
6010 _InnerIter<_Const> _M_inner;
6013 _Iterator(_Fun_handle __fun, _InnerIter<_Const> __inner)
6014 : _M_fun(__fun), _M_inner(
std::
move(__inner))
6018 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
6019 : _M_fun(*__parent._M_fun), _M_inner(
std::
move(__inner))
6025 using __detail::__maybe_const_t;
6026 using __detail::__unarize;
6027 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
6028 range_reference_t<_Base>>;
6029 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
6032 if constexpr (!is_reference_v<_Res>)
6033 return input_iterator_tag{};
6034 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
6035 return random_access_iterator_tag{};
6036 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
6037 return bidirectional_iterator_tag{};
6038 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
6039 return forward_iterator_tag{};
6041 return input_iterator_tag{};
6044 friend class adjacent_transform_view;
6047 using iterator_category =
decltype(_S_iter_cat());
6048 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
6050 = remove_cvref_t<invoke_result_t
6051 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
6052 range_reference_t<_Base>>>;
6053 using difference_type = range_difference_t<_Base>;
6055 _Iterator() =
default;
6058 _Iterator(_Iterator<!_Const> __i)
6059 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
6060 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
6063 constexpr decltype(
auto)
6066 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6067 return _M_fun._M_call_deref(__iters...);
6068 }, _M_inner._M_current);
6071 constexpr _Iterator&
6086 constexpr _Iterator&
6087 operator--()
requires bidirectional_range<_Base>
6094 operator--(
int)
requires bidirectional_range<_Base>
6101 constexpr _Iterator&
6102 operator+=(difference_type __x)
requires random_access_range<_Base>
6108 constexpr _Iterator&
6109 operator-=(difference_type __x)
requires random_access_range<_Base>
6115 constexpr decltype(
auto)
6116 operator[](difference_type __n)
const requires random_access_range<_Base>
6118 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6119 return _M_fun._M_call_subscript(__n, __iters...);
6120 }, _M_inner._M_current);
6123 friend constexpr bool
6124 operator==(
const _Iterator& __x,
const _Iterator& __y)
6125 {
return __x._M_inner == __y._M_inner; }
6127 friend constexpr bool
6128 operator<(
const _Iterator& __x,
const _Iterator& __y)
6129 requires random_access_range<_Base>
6130 {
return __x._M_inner < __y._M_inner; }
6132 friend constexpr bool
6133 operator>(
const _Iterator& __x,
const _Iterator& __y)
6134 requires random_access_range<_Base>
6135 {
return __x._M_inner > __y._M_inner; }
6137 friend constexpr bool
6138 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6139 requires random_access_range<_Base>
6140 {
return __x._M_inner <= __y._M_inner; }
6142 friend constexpr bool
6143 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6144 requires random_access_range<_Base>
6145 {
return __x._M_inner >= __y._M_inner; }
6147 friend constexpr auto
6148 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6149 requires random_access_range<_Base> &&
6150 three_way_comparable<_InnerIter<_Const>>
6151 {
return __x._M_inner <=> __y._M_inner; }
6153 friend constexpr _Iterator
6154 operator+(
const _Iterator& __i, difference_type __n)
6155 requires random_access_range<_Base>
6156 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6158 friend constexpr _Iterator
6159 operator+(difference_type __n,
const _Iterator& __i)
6160 requires random_access_range<_Base>
6161 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6163 friend constexpr _Iterator
6164 operator-(
const _Iterator& __i, difference_type __n)
6165 requires random_access_range<_Base>
6166 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
6168 friend constexpr difference_type
6169 operator-(
const _Iterator& __x,
const _Iterator& __y)
6170 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
6171 {
return __x._M_inner - __y._M_inner; }
6174 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6175 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6176 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6177 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6178 range_reference_t<_Vp>>>
6179 template<bool _Const>
6180 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6182 _InnerSent<_Const> _M_inner;
6185 _Sentinel(_InnerSent<_Const> __inner)
6189 friend class adjacent_transform_view;
6192 _Sentinel() =
default;
6195 _Sentinel(_Sentinel<!_Const> __i)
6196 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6200 template<
bool _OtherConst>
6201 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6202 friend constexpr bool
6203 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6204 {
return __x._M_inner == __y._M_inner; }
6206 template<
bool _OtherConst>
6207 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6208 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6209 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6210 {
return __x._M_inner - __y._M_inner; }
6212 template<
bool _OtherConst>
6213 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6214 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6215 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
6216 {
return __x._M_inner - __y._M_inner; }
6223 template<
size_t _Nm,
typename _Range,
typename _Fp>
6224 concept __can_adjacent_transform_view
6225 =
requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6229 template<
size_t _Nm>
6230 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6232 template<viewable_range _Range,
typename _Fp>
6233 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6235 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
6237 if constexpr (_Nm == 0)
6240 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6244 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6245 static constexpr int _S_arity = 2;
6246 static constexpr bool _S_has_simple_extra_args =
true;
6249 template<
size_t _Nm>
6250 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6252 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6256#ifdef __cpp_lib_ranges_chunk
6259 template<
typename _Tp>
6260 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6262 _Tp __r = __num / __denom;
6263 if (__num % __denom)
6270 requires input_range<_Vp>
6271 class chunk_view :
public view_interface<chunk_view<_Vp>>
6274 range_difference_t<_Vp> _M_n;
6275 range_difference_t<_Vp> _M_remainder = 0;
6276 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6283 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6285 { __glibcxx_assert(__n >= 0); }
6288 base() const & requires copy_constructible<_Vp>
6295 constexpr _OuterIter
6298 _M_current = ranges::begin(_M_base);
6299 _M_remainder = _M_n;
6300 return _OuterIter(*
this);
6303 constexpr default_sentinel_t
6304 end() const noexcept
6308 size()
requires sized_range<_Vp>
6310 return __detail::__to_unsigned_like(__detail::__div_ceil
6311 (ranges::distance(_M_base), _M_n));
6315 size() const requires sized_range<const _Vp>
6317 return __detail::__to_unsigned_like(__detail::__div_ceil
6318 (ranges::distance(_M_base), _M_n));
6322 template<
typename _Range>
6323 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6326 requires input_range<_Vp>
6327 class chunk_view<_Vp>::_OuterIter
6329 chunk_view* _M_parent;
6332 _OuterIter(chunk_view& __parent) noexcept
6339 using iterator_concept = input_iterator_tag;
6340 using difference_type = range_difference_t<_Vp>;
6344 _OuterIter(_OuterIter&&) =
default;
6345 _OuterIter& operator=(_OuterIter&&) =
default;
6347 constexpr value_type
6350 __glibcxx_assert(*
this != default_sentinel);
6351 return value_type(*_M_parent);
6354 constexpr _OuterIter&
6357 __glibcxx_assert(*
this != default_sentinel);
6358 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6359 ranges::end(_M_parent->_M_base));
6360 _M_parent->_M_remainder = _M_parent->_M_n;
6368 friend constexpr bool
6369 operator==(
const _OuterIter& __x, default_sentinel_t)
6371 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6372 && __x._M_parent->_M_remainder != 0;
6375 friend constexpr difference_type
6376 operator-(default_sentinel_t,
const _OuterIter& __x)
6377 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6379 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6381 if (__dist < __x._M_parent->_M_remainder)
6382 return __dist == 0 ? 0 : 1;
6384 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6385 __x._M_parent->_M_n);
6388 friend constexpr difference_type
6389 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6390 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6391 {
return -(__y - __x); }
6395 requires input_range<_Vp>
6396 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6399 chunk_view* _M_parent;
6402 value_type(chunk_view& __parent) noexcept
6409 constexpr _InnerIter
6410 begin() const noexcept
6411 {
return _InnerIter(*_M_parent); }
6413 constexpr default_sentinel_t
6414 end() const noexcept
6419 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6421 return __detail::__to_unsigned_like
6422 (ranges::min(_M_parent->_M_remainder,
6423 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6428 requires input_range<_Vp>
6429 class chunk_view<_Vp>::_InnerIter
6431 chunk_view* _M_parent;
6434 _InnerIter(chunk_view& __parent) noexcept
6438 friend _OuterIter::value_type;
6441 using iterator_concept = input_iterator_tag;
6442 using difference_type = range_difference_t<_Vp>;
6443 using value_type = range_value_t<_Vp>;
6445 _InnerIter(_InnerIter&&) =
default;
6446 _InnerIter& operator=(_InnerIter&&) =
default;
6448 constexpr const iterator_t<_Vp>&
6450 {
return *_M_parent->_M_current; }
6452 constexpr range_reference_t<_Vp>
6455 __glibcxx_assert(*
this != default_sentinel);
6456 return **_M_parent->_M_current;
6459 constexpr _InnerIter&
6462 __glibcxx_assert(*
this != default_sentinel);
6463 ++*_M_parent->_M_current;
6464 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6465 _M_parent->_M_remainder = 0;
6467 --_M_parent->_M_remainder;
6475 friend constexpr bool
6476 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6477 {
return __x._M_parent->_M_remainder == 0; }
6479 friend constexpr difference_type
6480 operator-(default_sentinel_t,
const _InnerIter& __x)
6481 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6483 return ranges::min(__x._M_parent->_M_remainder,
6484 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6487 friend constexpr difference_type
6488 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6489 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6490 {
return -(__y - __x); }
6494 friend constexpr range_rvalue_reference_t<_Vp>
6495 iter_move(
const _InnerIter& __i)
6496 noexcept(
noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6497 {
return ranges::iter_move(*__i._M_parent->_M_current); }
6499 friend constexpr void
6500 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
6501 noexcept(
noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6502 *__x._M_parent->_M_current)))
6503 requires indirectly_swappable<iterator_t<_Vp>>
6504 {
return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6508 requires forward_range<_Vp>
6509 class chunk_view<_Vp> :
public view_interface<chunk_view<_Vp>>
6512 range_difference_t<_Vp> _M_n;
6513 template<
bool>
class _Iterator;
6517 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6519 { __glibcxx_assert(__n > 0); }
6522 base() const & requires copy_constructible<_Vp>
6530 begin()
requires (!__detail::__simple_view<_Vp>)
6531 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6534 begin() const requires forward_range<const _Vp>
6535 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6538 end()
requires (!__detail::__simple_view<_Vp>)
6540 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6542 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6543 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6545 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6546 return _Iterator<false>(
this, ranges::end(_M_base));
6552 end() const requires forward_range<const _Vp>
6554 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6556 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6557 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6559 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6560 return _Iterator<true>(
this, ranges::end(_M_base));
6566 size()
requires sized_range<_Vp>
6568 return __detail::__to_unsigned_like(__detail::__div_ceil
6569 (ranges::distance(_M_base), _M_n));
6573 size() const requires sized_range<const _Vp>
6575 return __detail::__to_unsigned_like(__detail::__div_ceil
6576 (ranges::distance(_M_base), _M_n));
6580 template<
typename _Vp>
6581 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6582 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6585 requires forward_range<_Vp>
6586 template<
bool _Const>
6587 class chunk_view<_Vp>::_Iterator
6589 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6590 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6592 iterator_t<_Base> _M_current = iterator_t<_Base>();
6593 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6594 range_difference_t<_Base> _M_n = 0;
6595 range_difference_t<_Base> _M_missing = 0;
6598 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6599 range_difference_t<_Base> __missing = 0)
6600 : _M_current(__current), _M_end(ranges::
end(__parent->_M_base)),
6601 _M_n(__parent->_M_n), _M_missing(__missing)
6607 if constexpr (random_access_range<_Base>)
6608 return random_access_iterator_tag{};
6609 else if constexpr (bidirectional_range<_Base>)
6610 return bidirectional_iterator_tag{};
6612 return forward_iterator_tag{};
6618 using iterator_category = input_iterator_tag;
6619 using iterator_concept =
decltype(_S_iter_cat());
6620 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6621 using difference_type = range_difference_t<_Base>;
6623 _Iterator() =
default;
6625 constexpr _Iterator(_Iterator<!_Const> __i)
6627 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6628 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6630 _M_n(__i._M_n), _M_missing(__i._M_missing)
6633 constexpr iterator_t<_Base>
6635 {
return _M_current; }
6637 constexpr value_type
6640 __glibcxx_assert(_M_current != _M_end);
6641 return views::take(subrange(_M_current, _M_end), _M_n);
6644 constexpr _Iterator&
6647 __glibcxx_assert(_M_current != _M_end);
6648 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6660 constexpr _Iterator&
6661 operator--()
requires bidirectional_range<_Base>
6663 ranges::advance(_M_current, _M_missing - _M_n);
6669 operator--(
int)
requires bidirectional_range<_Base>
6676 constexpr _Iterator&
6677 operator+=(difference_type __x)
6678 requires random_access_range<_Base>
6682 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6683 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6687 ranges::advance(_M_current, _M_n * __x + _M_missing);
6693 constexpr _Iterator&
6694 operator-=(difference_type __x)
6695 requires random_access_range<_Base>
6696 {
return *
this += -__x; }
6698 constexpr value_type
6699 operator[](difference_type __n)
const
6700 requires random_access_range<_Base>
6701 {
return *(*
this + __n); }
6703 friend constexpr bool
6704 operator==(
const _Iterator& __x,
const _Iterator& __y)
6705 {
return __x._M_current == __y._M_current; }
6707 friend constexpr bool
6708 operator==(
const _Iterator& __x, default_sentinel_t)
6709 {
return __x._M_current == __x._M_end; }
6711 friend constexpr bool
6712 operator<(
const _Iterator& __x,
const _Iterator& __y)
6713 requires random_access_range<_Base>
6714 {
return __x._M_current > __y._M_current; }
6716 friend constexpr bool
6717 operator>(
const _Iterator& __x,
const _Iterator& __y)
6718 requires random_access_range<_Base>
6719 {
return __y < __x; }
6721 friend constexpr bool
6722 operator<=(
const _Iterator& __x,
const _Iterator& __y)
6723 requires random_access_range<_Base>
6724 {
return !(__y < __x); }
6726 friend constexpr bool
6727 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6728 requires random_access_range<_Base>
6729 {
return !(__x < __y); }
6731 friend constexpr auto
6732 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6733 requires random_access_range<_Base>
6734 && three_way_comparable<iterator_t<_Base>>
6735 {
return __x._M_current <=> __y._M_current; }
6737 friend constexpr _Iterator
6738 operator+(
const _Iterator& __i, difference_type __n)
6739 requires random_access_range<_Base>
6746 friend constexpr _Iterator
6747 operator+(difference_type __n,
const _Iterator& __i)
6748 requires random_access_range<_Base>
6755 friend constexpr _Iterator
6756 operator-(
const _Iterator& __i, difference_type __n)
6757 requires random_access_range<_Base>
6764 friend constexpr difference_type
6765 operator-(
const _Iterator& __x,
const _Iterator& __y)
6766 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6768 return (__x._M_current - __y._M_current
6769 + __x._M_missing - __y._M_missing) / __x._M_n;
6772 friend constexpr difference_type
6773 operator-(default_sentinel_t,
const _Iterator& __x)
6774 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6775 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6777 friend constexpr difference_type
6778 operator-(
const _Iterator& __x, default_sentinel_t __y)
6779 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6780 {
return -(__y - __x); }
6787 template<
typename _Range,
typename _Dp>
6788 concept __can_chunk_view
6792 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6794 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6795 requires __detail::__can_chunk_view<_Range, _Dp>
6797 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6800 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6801 static constexpr int _S_arity = 2;
6802 static constexpr bool _S_has_simple_extra_args =
true;
6805 inline constexpr _Chunk chunk;
6809#ifdef __cpp_lib_ranges_slide
6812 template<
typename _Vp>
6813 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6815 template<
typename _Vp>
6816 concept __slide_caches_last
6817 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6819 template<
typename _Vp>
6820 concept __slide_caches_first
6821 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6824 template<forward_range _Vp>
6826 class slide_view :
public view_interface<slide_view<_Vp>>
6829 range_difference_t<_Vp> _M_n;
6830 [[no_unique_address]]
6831 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6832 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6833 [[no_unique_address]]
6834 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6835 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6837 template<
bool>
class _Iterator;
6842 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6844 { __glibcxx_assert(__n > 0); }
6849 base() const & requires copy_constructible<_Vp>
6857 begin()
requires (!(__detail::__simple_view<_Vp>
6858 && __detail::__slide_caches_nothing<const _Vp>))
6860 if constexpr (__detail::__slide_caches_first<_Vp>)
6862 iterator_t<_Vp> __it;
6863 if (_M_cached_begin._M_has_value())
6864 __it = _M_cached_begin._M_get(_M_base);
6867 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6868 _M_cached_begin._M_set(_M_base, __it);
6870 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6873 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6877 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6878 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6881 end()
requires (!(__detail::__simple_view<_Vp>
6882 && __detail::__slide_caches_nothing<const _Vp>))
6884 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6885 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(
size()),
6887 else if constexpr (__detail::__slide_caches_last<_Vp>)
6889 iterator_t<_Vp> __it;
6890 if (_M_cached_end._M_has_value())
6891 __it = _M_cached_end._M_get(_M_base);
6894 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6895 _M_cached_end._M_set(_M_base, __it);
6897 return _Iterator<false>(
std::move(__it), _M_n);
6899 else if constexpr (common_range<_Vp>)
6900 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6902 return _Sentinel(ranges::end(_M_base));
6906 end() const requires __detail::__slide_caches_nothing<const _Vp>
6907 {
return begin() + range_difference_t<const _Vp>(
size()); }
6910 size()
requires sized_range<_Vp>
6912 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6915 return __detail::__to_unsigned_like(__sz);
6919 size() const requires sized_range<const _Vp>
6921 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6924 return __detail::__to_unsigned_like(__sz);
6928 template<
typename _Range>
6929 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6931 template<
typename _Vp>
6932 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6933 = enable_borrowed_range<_Vp>;
6935 template<forward_range _Vp>
6937 template<
bool _Const>
6938 class slide_view<_Vp>::_Iterator
6940 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6941 static constexpr bool _S_last_elt_present
6942 = __detail::__slide_caches_first<_Base>;
6944 iterator_t<_Base> _M_current = iterator_t<_Base>();
6945 [[no_unique_address]]
6946 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6947 _M_last_elt =
decltype(_M_last_elt)();
6948 range_difference_t<_Base> _M_n = 0;
6951 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6952 requires (!_S_last_elt_present)
6953 : _M_current(__current), _M_n(__n)
6957 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6958 range_difference_t<_Base> __n)
6959 requires _S_last_elt_present
6960 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6966 if constexpr (random_access_range<_Base>)
6967 return random_access_iterator_tag{};
6968 else if constexpr (bidirectional_range<_Base>)
6969 return bidirectional_iterator_tag{};
6971 return forward_iterator_tag{};
6975 friend slide_view::_Sentinel;
6978 using iterator_category = input_iterator_tag;
6979 using iterator_concept =
decltype(_S_iter_concept());
6980 using value_type =
decltype(views::counted(_M_current, _M_n));
6981 using difference_type = range_difference_t<_Base>;
6983 _Iterator() =
default;
6986 _Iterator(_Iterator<!_Const> __i)
6987 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6988 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
6993 {
return views::counted(_M_current, _M_n); }
6995 constexpr _Iterator&
6999 if constexpr (_S_last_elt_present)
7012 constexpr _Iterator&
7013 operator--()
requires bidirectional_range<_Base>
7016 if constexpr (_S_last_elt_present)
7022 operator--(
int)
requires bidirectional_range<_Base>
7029 constexpr _Iterator&
7030 operator+=(difference_type __x)
7031 requires random_access_range<_Base>
7034 if constexpr (_S_last_elt_present)
7039 constexpr _Iterator&
7040 operator-=(difference_type __x)
7041 requires random_access_range<_Base>
7044 if constexpr (_S_last_elt_present)
7050 operator[](difference_type __n)
const
7051 requires random_access_range<_Base>
7052 {
return views::counted(_M_current + __n, _M_n); }
7054 friend constexpr bool
7055 operator==(
const _Iterator& __x,
const _Iterator& __y)
7057 if constexpr (_S_last_elt_present)
7058 return __x._M_last_elt == __y._M_last_elt;
7060 return __x._M_current == __y._M_current;
7063 friend constexpr bool
7064 operator<(
const _Iterator& __x,
const _Iterator& __y)
7065 requires random_access_range<_Base>
7066 {
return __x._M_current < __y._M_current; }
7068 friend constexpr bool
7069 operator>(
const _Iterator& __x,
const _Iterator& __y)
7070 requires random_access_range<_Base>
7071 {
return __y < __x; }
7073 friend constexpr bool
7074 operator<=(
const _Iterator& __x,
const _Iterator& __y)
7075 requires random_access_range<_Base>
7076 {
return !(__y < __x); }
7078 friend constexpr bool
7079 operator>=(
const _Iterator& __x,
const _Iterator& __y)
7080 requires random_access_range<_Base>
7081 {
return !(__x < __y); }
7083 friend constexpr auto
7084 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7085 requires random_access_range<_Base>
7086 && three_way_comparable<iterator_t<_Base>>
7087 {
return __x._M_current <=> __y._M_current; }
7089 friend constexpr _Iterator
7090 operator+(
const _Iterator& __i, difference_type __n)
7091 requires random_access_range<_Base>
7098 friend constexpr _Iterator
7099 operator+(difference_type __n,
const _Iterator& __i)
7100 requires random_access_range<_Base>
7107 friend constexpr _Iterator
7108 operator-(
const _Iterator& __i, difference_type __n)
7109 requires random_access_range<_Base>
7116 friend constexpr difference_type
7117 operator-(
const _Iterator& __x,
const _Iterator& __y)
7118 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7120 if constexpr (_S_last_elt_present)
7121 return __x._M_last_elt - __y._M_last_elt;
7123 return __x._M_current - __y._M_current;
7127 template<forward_range _Vp>
7129 class slide_view<_Vp>::_Sentinel
7131 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
7134 _Sentinel(sentinel_t<_Vp> __end)
7141 _Sentinel() =
default;
7143 friend constexpr bool
7144 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
7145 {
return __x._M_last_elt == __y._M_end; }
7147 friend constexpr range_difference_t<_Vp>
7148 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
7149 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7150 {
return __x._M_last_elt - __y._M_end; }
7152 friend constexpr range_difference_t<_Vp>
7153 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
7154 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7155 {
return __y._M_end -__x._M_last_elt; }
7162 template<
typename _Range,
typename _Dp>
7163 concept __can_slide_view
7167 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
7169 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
7170 requires __detail::__can_slide_view<_Range, _Dp>
7172 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
7175 using __adaptor::_RangeAdaptor<_Slide>::operator();
7176 static constexpr int _S_arity = 2;
7177 static constexpr bool _S_has_simple_extra_args =
true;
7180 inline constexpr _Slide slide;
7184#ifdef __cpp_lib_ranges_chunk_by
7185 template<forward_range _Vp,
7186 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7187 requires view<_Vp> && is_object_v<_Pred>
7188 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
7190 _Vp _M_base = _Vp();
7191 __detail::__box<_Pred> _M_pred;
7192 __detail::_CachedPosition<_Vp> _M_cached_begin;
7194 constexpr iterator_t<_Vp>
7195 _M_find_next(iterator_t<_Vp> __current)
7197 __glibcxx_assert(_M_pred.has_value());
7198 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7201 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7202 return ranges::next(__it, 1, ranges::end(_M_base));
7205 constexpr iterator_t<_Vp>
7206 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
7208 __glibcxx_assert(_M_pred.has_value());
7209 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7214 __glibcxx_assert(__rbegin != __rend);
7215 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7216 return ranges::prev(__it, 1, ranges::begin(_M_base));
7222 chunk_by_view()
requires (default_initializable<_Vp>
7223 && default_initializable<_Pred>)
7227 chunk_by_view(_Vp __base, _Pred __pred)
7232 base() const & requires copy_constructible<_Vp>
7239 constexpr const _Pred&
7241 {
return *_M_pred; }
7246 __glibcxx_assert(_M_pred.has_value());
7247 iterator_t<_Vp> __it;
7248 if (_M_cached_begin._M_has_value())
7249 __it = _M_cached_begin._M_get(_M_base);
7252 __it = _M_find_next(ranges::begin(_M_base));
7253 _M_cached_begin._M_set(_M_base, __it);
7255 return _Iterator(*
this, ranges::begin(_M_base), __it);
7261 if constexpr (common_range<_Vp>)
7262 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
7268 template<
typename _Range,
typename _Pred>
7269 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7271 template<forward_range _Vp,
7272 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7273 requires view<_Vp> && is_object_v<_Pred>
7274 class chunk_by_view<_Vp, _Pred>::_Iterator
7276 chunk_by_view* _M_parent =
nullptr;
7277 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7278 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7281 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7282 : _M_parent(std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7288 if constexpr (bidirectional_range<_Vp>)
7289 return bidirectional_iterator_tag{};
7291 return forward_iterator_tag{};
7294 friend chunk_by_view;
7297 using value_type = subrange<iterator_t<_Vp>>;
7298 using difference_type = range_difference_t<_Vp>;
7299 using iterator_category = input_iterator_tag;
7300 using iterator_concept =
decltype(_S_iter_concept());
7302 _Iterator() =
default;
7304 constexpr value_type
7307 __glibcxx_assert(_M_current != _M_next);
7308 return ranges::subrange(_M_current, _M_next);
7311 constexpr _Iterator&
7314 __glibcxx_assert(_M_current != _M_next);
7315 _M_current = _M_next;
7316 _M_next = _M_parent->_M_find_next(_M_current);
7328 constexpr _Iterator&
7329 operator--()
requires bidirectional_range<_Vp>
7331 _M_next = _M_current;
7332 _M_current = _M_parent->_M_find_prev(_M_next);
7337 operator--(
int)
requires bidirectional_range<_Vp>
7344 friend constexpr bool
7345 operator==(
const _Iterator& __x,
const _Iterator& __y)
7346 {
return __x._M_current == __y._M_current; }
7348 friend constexpr bool
7349 operator==(
const _Iterator& __x, default_sentinel_t)
7350 {
return __x._M_current == __x._M_next; }
7357 template<
typename _Range,
typename _Pred>
7358 concept __can_chunk_by_view
7362 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7364 template<viewable_range _Range,
typename _Pred>
7365 requires __detail::__can_chunk_by_view<_Range, _Pred>
7367 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7370 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7371 static constexpr int _S_arity = 2;
7372 static constexpr bool _S_has_simple_extra_args =
true;
7375 inline constexpr _ChunkBy chunk_by;
7379#ifdef __cpp_lib_ranges_join_with
7382 template<
typename _Range,
typename _Pattern>
7383 concept __compatible_joinable_ranges
7384 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7385 && common_reference_with<range_reference_t<_Range>,
7386 range_reference_t<_Pattern>>
7387 && common_reference_with<range_rvalue_reference_t<_Range>,
7388 range_rvalue_reference_t<_Pattern>>;
7390 template<
typename _Range>
7391 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7394 template<input_range _Vp, forward_range _Pattern>
7395 requires view<_Vp> && view<_Pattern>
7396 && input_range<range_reference_t<_Vp>>
7397 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7398 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7400 using _InnerRange = range_reference_t<_Vp>;
7402 _Vp _M_base = _Vp();
7403 [[no_unique_address]]
7404 __detail::__maybe_present_t<!forward_range<_Vp>,
7405 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7406 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7407 _Pattern _M_pattern = _Pattern();
7409 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7410 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7411 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7413 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7414 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7415 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7417 template<
bool _Const>
7418 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7420 template<
bool _Const>
7424 template<
bool _Const>
7425 requires _S_ref_is_glvalue<_Const>
7426 && forward_range<_Base<_Const>>
7427 && forward_range<_InnerBase<_Const>>
7428 struct __iter_cat<_Const>
7434 using _OuterIter = join_with_view::_OuterIter<_Const>;
7435 using _InnerIter = join_with_view::_InnerIter<_Const>;
7436 using _PatternIter = join_with_view::_PatternIter<_Const>;
7437 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7438 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7439 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7442 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7443 iter_reference_t<_PatternIter>>>)
7444 return input_iterator_tag{};
7445 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7446 && derived_from<_InnerCat, bidirectional_iterator_tag>
7447 && derived_from<_PatternCat, bidirectional_iterator_tag>
7448 && common_range<_InnerBase<_Const>>
7449 && common_range<_PatternBase<_Const>>)
7450 return bidirectional_iterator_tag{};
7451 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7452 && derived_from<_InnerCat, forward_iterator_tag>
7453 && derived_from<_PatternCat, forward_iterator_tag>)
7454 return forward_iterator_tag{};
7456 return input_iterator_tag{};
7459 using iterator_category =
decltype(_S_iter_cat());
7462 template<
bool>
class _Iterator;
7463 template<
bool>
class _Sentinel;
7466 join_with_view()
requires (default_initializable<_Vp>
7467 && default_initializable<_Pattern>)
7471 join_with_view(_Vp __base, _Pattern __pattern)
7475 template<input_range _Range>
7476 requires constructible_from<_Vp, views::all_t<_Range>>
7477 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7479 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7480 : _M_base(views::all(std::
forward<_Range>(__r))),
7481 _M_pattern(views::single(std::
move(__e)))
7485 base() const& requires copy_constructible<_Vp>
7495 if constexpr (forward_range<_Vp>)
7497 constexpr bool __use_const = is_reference_v<_InnerRange>
7498 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7499 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7503 _M_outer_it = ranges::begin(_M_base);
7504 return _Iterator<false>{*
this};
7510 requires forward_range<const _Vp>
7511 && forward_range<const _Pattern>
7512 && is_reference_v<range_reference_t<const _Vp>>
7513 && input_range<range_reference_t<const _Vp>>
7514 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7519 constexpr bool __use_const
7520 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7521 if constexpr (is_reference_v<_InnerRange>
7522 && forward_range<_Vp> && common_range<_Vp>
7523 && forward_range<_InnerRange> && common_range<_InnerRange>)
7524 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7526 return _Sentinel<__use_const>{*
this};
7531 requires forward_range<const _Vp>
7532 && forward_range<const _Pattern>
7533 && is_reference_v<range_reference_t<const _Vp>>
7534 && input_range<range_reference_t<const _Vp>>
7536 using _InnerConstRange = range_reference_t<const _Vp>;
7537 if constexpr (forward_range<_InnerConstRange>
7538 && common_range<const _Vp>
7539 && common_range<_InnerConstRange>)
7540 return _Iterator<true>{*
this, ranges::end(_M_base)};
7542 return _Sentinel<true>{*
this};
7546 template<
typename _Range,
typename _Pattern>
7547 join_with_view(_Range&&, _Pattern&&)
7548 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7550 template<input_range _Range>
7551 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7552 -> join_with_view<views::all_t<_Range>,
7553 single_view<range_value_t<range_reference_t<_Range>>>>;
7555 template<input_range _Vp, forward_range _Pattern>
7556 requires view<_Vp> && view<_Pattern>
7557 && input_range<range_reference_t<_Vp>>
7558 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7559 template<
bool _Const>
7560 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7562 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7563 using _Base = join_with_view::_Base<_Const>;
7564 using _InnerBase = join_with_view::_InnerBase<_Const>;
7565 using _PatternBase = join_with_view::_PatternBase<_Const>;
7567 using _OuterIter = join_with_view::_OuterIter<_Const>;
7568 using _InnerIter = join_with_view::_InnerIter<_Const>;
7569 using _PatternIter = join_with_view::_PatternIter<_Const>;
7571 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7573 _Parent* _M_parent =
nullptr;
7574 [[no_unique_address]]
7575 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7576 =
decltype(_M_outer_it)();
7577 variant<_PatternIter, _InnerIter> _M_inner_it;
7579 constexpr _OuterIter&
7582 if constexpr (forward_range<_Base>)
7585 return *_M_parent->_M_outer_it;
7588 constexpr const _OuterIter&
7589 _M_get_outer()
const
7591 if constexpr (forward_range<_Base>)
7594 return *_M_parent->_M_outer_it;
7598 _Iterator(_Parent& __parent, _OuterIter __outer)
7599 requires forward_range<_Base>
7602 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7604 auto&& __inner = _M_update_inner();
7605 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7611 _Iterator(_Parent& __parent)
7612 requires (!forward_range<_Base>)
7615 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7617 auto&& __inner = _M_update_inner();
7618 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7626 _OuterIter& __outer = _M_get_outer();
7627 if constexpr (_S_ref_is_glvalue)
7628 return __detail::__as_lvalue(*__outer);
7630 return _M_parent->_M_inner._M_emplace_deref(__outer);
7636 if constexpr (_S_ref_is_glvalue)
7637 return __detail::__as_lvalue(*_M_get_outer());
7639 return *_M_parent->_M_inner;
7647 if (_M_inner_it.index() == 0)
7649 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7652 auto&& __inner = _M_update_inner();
7653 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7657 auto&& __inner = _M_get_inner();
7658 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7661 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7663 if constexpr (_S_ref_is_glvalue)
7664 _M_inner_it.template emplace<0>();
7668 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7676 if constexpr (_S_ref_is_glvalue
7677 && bidirectional_range<_Base>
7678 && __detail::__bidirectional_common<_InnerBase>
7679 && __detail::__bidirectional_common<_PatternBase>)
7680 return bidirectional_iterator_tag{};
7681 else if constexpr (_S_ref_is_glvalue
7682 && forward_range<_Base>
7683 && forward_range<_InnerBase>)
7684 return forward_iterator_tag{};
7686 return input_iterator_tag{};
7689 friend join_with_view;
7692 using iterator_concept =
decltype(_S_iter_concept());
7694 using value_type = common_type_t<iter_value_t<_InnerIter>,
7695 iter_value_t<_PatternIter>>;
7696 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7697 iter_difference_t<_InnerIter>,
7698 iter_difference_t<_PatternIter>>;
7700 _Iterator() =
default;
7703 _Iterator(_Iterator<!_Const> __i)
7705 && convertible_to<iterator_t<_Vp>, _OuterIter>
7706 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7707 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7708 : _M_parent(__i._M_parent),
7711 if (__i._M_inner_it.index() == 0)
7712 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7714 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7717 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7718 iter_reference_t<_PatternIter>>
7721 if (_M_inner_it.index() == 0)
7722 return *std::get<0>(_M_inner_it);
7724 return *std::get<1>(_M_inner_it);
7727 constexpr _Iterator&
7730 if (_M_inner_it.index() == 0)
7731 ++std::get<0>(_M_inner_it);
7733 ++std::get<1>(_M_inner_it);
7744 requires _S_ref_is_glvalue
7745 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7747 _Iterator __tmp = *
this;
7752 constexpr _Iterator&
7754 requires _S_ref_is_glvalue
7755 && bidirectional_range<_Base>
7756 && __detail::__bidirectional_common<_InnerBase>
7757 && __detail::__bidirectional_common<_PatternBase>
7759 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7761 auto&& __inner = *--_M_outer_it;
7762 _M_inner_it.template emplace<1>(ranges::end(__inner));
7767 if (_M_inner_it.index() == 0)
7769 auto& __it = std::get<0>(_M_inner_it);
7770 if (__it == ranges::begin(_M_parent->_M_pattern))
7772 auto&& __inner = *--_M_outer_it;
7773 _M_inner_it.template emplace<1>(ranges::end(__inner));
7780 auto& __it = std::get<1>(_M_inner_it);
7781 auto&& __inner = *_M_outer_it;
7782 if (__it == ranges::begin(__inner))
7783 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7789 if (_M_inner_it.index() == 0)
7790 --std::get<0>(_M_inner_it);
7792 --std::get<1>(_M_inner_it);
7798 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7799 && __detail::__bidirectional_common<_InnerBase>
7800 && __detail::__bidirectional_common<_PatternBase>
7802 _Iterator __tmp = *
this;
7807 friend constexpr bool
7808 operator==(
const _Iterator& __x,
const _Iterator& __y)
7809 requires _S_ref_is_glvalue
7810 && forward_range<_Base> && equality_comparable<_InnerIter>
7811 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7813 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7814 iter_rvalue_reference_t<_PatternIter>>
7815 iter_move(
const _Iterator& __x)
7817 if (__x._M_inner_it.index() == 0)
7818 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7820 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7823 friend constexpr void
7824 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7825 requires indirectly_swappable<_InnerIter, _PatternIter>
7827 if (__x._M_inner_it.index() == 0)
7829 if (__y._M_inner_it.index() == 0)
7830 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7832 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7836 if (__y._M_inner_it.index() == 0)
7837 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7839 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7844 template<input_range _Vp, forward_range _Pattern>
7845 requires view<_Vp> && view<_Pattern>
7846 && input_range<range_reference_t<_Vp>>
7847 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7848 template<
bool _Const>
7849 class join_with_view<_Vp, _Pattern>::_Sentinel
7851 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7852 using _Base = join_with_view::_Base<_Const>;
7854 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7857 _Sentinel(_Parent& __parent)
7858 : _M_end(ranges::
end(__parent._M_base))
7861 friend join_with_view;
7864 _Sentinel() =
default;
7867 _Sentinel(_Sentinel<!_Const> __s)
7868 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7872 template<
bool _OtherConst>
7873 requires sentinel_for<sentinel_t<_Base>,
7874 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7875 friend constexpr bool
7876 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7877 {
return __x._M_get_outer() == __y._M_end; }
7884 template<
typename _Range,
typename _Pattern>
7885 concept __can_join_with_view
7889 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7891 template<viewable_range _Range,
typename _Pattern>
7892 requires __detail::__can_join_with_view<_Range, _Pattern>
7894 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7899 using _RangeAdaptor<_JoinWith>::operator();
7900 static constexpr int _S_arity = 2;
7901 template<
typename _Pattern>
7902 static constexpr bool _S_has_simple_extra_args
7903 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7906 inline constexpr _JoinWith join_with;
7910#ifdef __cpp_lib_ranges_repeat
7911 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7912 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7913 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7914 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7916 __detail::__box<_Tp> _M_value;
7917 [[no_unique_address]] _Bound _M_bound = _Bound();
7921 template<
typename _Range>
7922 friend constexpr auto
7923 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7925 template<
typename _Range>
7926 friend constexpr auto
7927 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7930 repeat_view()
requires default_initializable<_Tp> = default;
7933 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7934 requires copy_constructible<_Tp>
7935 : _M_value(__value), _M_bound(__bound)
7937 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7938 __glibcxx_assert(__bound >= 0);
7942 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7943 : _M_value(
std::
move(__value)), _M_bound(__bound)
7946 template<
typename... _Args,
typename... _BoundArgs>
7947 requires constructible_from<_Tp, _Args...>
7948 && constructible_from<_Bound, _BoundArgs...>
7950 repeat_view(piecewise_construct_t,
7951 tuple<_Args...> __args,
7952 tuple<_BoundArgs...> __bound_args = tuple<>{})
7953 : _M_value(
std::make_from_tuple<_Tp>(
std::
move(__args))),
7954 _M_bound(
std::make_from_tuple<_Bound>(
std::
move(__bound_args)))
7962 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7965 constexpr unreachable_sentinel_t
7966 end() const noexcept
7967 {
return unreachable_sentinel; }
7970 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7971 {
return __detail::__to_unsigned_like(_M_bound); }
7976 template<
typename _Tp,
typename _Bound = unreachable_sentinel_t>
7977 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7979 template<move_constructible _Tp, semiregular _Bound>
7980 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7981 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7982 class repeat_view<_Tp, _Bound>::_Iterator
7985 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7987 const _Tp* _M_value =
nullptr;
7988 __index_type _M_current = __index_type();
7991 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
7992 : _M_value(__value), _M_current(__bound)
7994 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7995 __glibcxx_assert(__bound >= 0);
8001 using iterator_concept = random_access_iterator_tag;
8002 using iterator_category = random_access_iterator_tag;
8003 using value_type = _Tp;
8004 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
8006 __detail::__iota_diff_t<__index_type>>;
8008 _Iterator() =
default;
8010 constexpr const _Tp&
8012 {
return *_M_value; }
8014 constexpr _Iterator&
8029 constexpr _Iterator&
8032 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8033 __glibcxx_assert(_M_current > 0);
8046 constexpr _Iterator&
8047 operator+=(difference_type __n)
8049 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8050 __glibcxx_assert(_M_current + __n >= 0);
8055 constexpr _Iterator&
8056 operator-=(difference_type __n)
8058 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8059 __glibcxx_assert(_M_current - __n >= 0);
8064 constexpr const _Tp&
8065 operator[](difference_type __n)
const noexcept
8066 {
return *(*
this + __n); }
8068 friend constexpr bool
8069 operator==(
const _Iterator& __x,
const _Iterator& __y)
8070 {
return __x._M_current == __y._M_current; }
8072 friend constexpr auto
8073 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8074 {
return __x._M_current <=> __y._M_current; }
8076 friend constexpr _Iterator
8077 operator+(_Iterator __i, difference_type __n)
8083 friend constexpr _Iterator
8084 operator+(difference_type __n, _Iterator __i)
8085 {
return __i + __n; }
8087 friend constexpr _Iterator
8088 operator-(_Iterator __i, difference_type __n)
8094 friend constexpr difference_type
8095 operator-(
const _Iterator& __x,
const _Iterator& __y)
8097 return (
static_cast<difference_type
>(__x._M_current)
8098 -
static_cast<difference_type
>(__y._M_current));
8106 template<
typename _Tp,
typename _Bound>
8107 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
8109 template<
typename _Tp>
8110 concept __can_repeat_view
8113 template<
typename _Tp,
typename _Bound>
8114 concept __can_bounded_repeat_view
8120 template<
typename _Tp>
8121 requires __detail::__can_repeat_view<_Tp>
8123 operator() [[nodiscard]] (_Tp&& __value)
const
8130 template<
typename _Tp,
typename _Bound>
8131 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
8133 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
8137 inline constexpr _Repeat repeat;
8141 template<
typename _Range>
8143 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8145 using _Tp = remove_cvref_t<_Range>;
8146 static_assert(__is_repeat_view<_Tp>);
8147 if constexpr (sized_range<_Tp>)
8149 std::min(ranges::distance(__r), __n));
8154 template<
typename _Range>
8156 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8158 using _Tp = remove_cvref_t<_Range>;
8159 static_assert(__is_repeat_view<_Tp>);
8160 if constexpr (sized_range<_Tp>)
8162 auto __sz = ranges::distance(__r);
8173#ifdef __cpp_lib_ranges_stride
8174 template<input_range _Vp>
8176 class stride_view :
public view_interface<stride_view<_Vp>>
8179 range_difference_t<_Vp> _M_stride;
8181 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8183 template<
bool _Const>
8187 template<
bool _Const>
8188 requires forward_range<_Base<_Const>>
8189 struct __iter_cat<_Const>
8195 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8196 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8197 return random_access_iterator_tag{};
8202 using iterator_category =
decltype(_S_iter_cat());
8205 template<
bool>
class _Iterator;
8209 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8210 : _M_base(std::
move(
__base)), _M_stride(__stride)
8211 { __glibcxx_assert(__stride > 0); }
8214 base() const& requires copy_constructible<_Vp>
8221 constexpr range_difference_t<_Vp>
8222 stride() const noexcept
8223 {
return _M_stride; }
8226 begin()
requires (!__detail::__simple_view<_Vp>)
8227 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
8230 begin() const requires range<const _Vp>
8231 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
8234 end()
requires (!__detail::__simple_view<_Vp>)
8236 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8238 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8239 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
8241 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8242 return _Iterator<false>(
this, ranges::end(_M_base));
8248 end() const requires range<const _Vp>
8250 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8251 && forward_range<const _Vp>)
8253 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8254 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
8256 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8257 return _Iterator<true>(
this, ranges::end(_M_base));
8263 size()
requires sized_range<_Vp>
8265 return __detail::__to_unsigned_like
8266 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8270 size() const requires sized_range<const _Vp>
8272 return __detail::__to_unsigned_like
8273 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8277 template<
typename _Range>
8278 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8280 template<
typename _Vp>
8281 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8282 = enable_borrowed_range<_Vp>;
8284 template<input_range _Vp>
8286 template<
bool _Const>
8287 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8289 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8290 using _Base = stride_view::_Base<_Const>;
8292 iterator_t<_Base> _M_current = iterator_t<_Base>();
8293 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8294 range_difference_t<_Base> _M_stride = 0;
8295 range_difference_t<_Base> _M_missing = 0;
8298 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8299 range_difference_t<_Base> __missing = 0)
8300 : _M_current(std::
move(__current)), _M_end(ranges::
end(__parent->_M_base)),
8301 _M_stride(__parent->_M_stride), _M_missing(__missing)
8307 if constexpr (random_access_range<_Base>)
8308 return random_access_iterator_tag{};
8309 else if constexpr (bidirectional_range<_Base>)
8310 return bidirectional_iterator_tag{};
8311 else if constexpr (forward_range<_Base>)
8312 return forward_iterator_tag{};
8314 return input_iterator_tag{};
8320 using difference_type = range_difference_t<_Base>;
8321 using value_type = range_value_t<_Base>;
8322 using iterator_concept =
decltype(_S_iter_concept());
8325 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8328 _Iterator(_Iterator<!_Const> __other)
8330 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8331 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8332 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8333 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8336 constexpr iterator_t<_Base>
8340 constexpr const iterator_t<_Base>&
8341 base() const & noexcept
8342 {
return _M_current; }
8344 constexpr decltype(
auto)
8346 {
return *_M_current; }
8348 constexpr _Iterator&
8351 __glibcxx_assert(_M_current != _M_end);
8352 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8361 operator++(
int)
requires forward_range<_Base>
8368 constexpr _Iterator&
8369 operator--()
requires bidirectional_range<_Base>
8371 ranges::advance(_M_current, _M_missing - _M_stride);
8377 operator--(
int)
requires bidirectional_range<_Base>
8384 constexpr _Iterator&
8385 operator+=(difference_type __n)
requires random_access_range<_Base>
8389 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8390 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8394 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8400 constexpr _Iterator&
8401 operator-=(difference_type __n)
requires random_access_range<_Base>
8402 {
return *
this += -__n; }
8404 constexpr decltype(
auto)
operator[](difference_type __n)
const
8405 requires random_access_range<_Base>
8406 {
return *(*
this + __n); }
8408 friend constexpr bool
8409 operator==(
const _Iterator& __x, default_sentinel_t)
8410 {
return __x._M_current == __x._M_end; }
8412 friend constexpr bool
8413 operator==(
const _Iterator& __x,
const _Iterator& __y)
8414 requires equality_comparable<iterator_t<_Base>>
8415 {
return __x._M_current == __y._M_current; }
8417 friend constexpr bool
8418 operator<(
const _Iterator& __x,
const _Iterator& __y)
8419 requires random_access_range<_Base>
8420 {
return __x._M_current < __y._M_current; }
8422 friend constexpr bool
8423 operator>(
const _Iterator& __x,
const _Iterator& __y)
8424 requires random_access_range<_Base>
8425 {
return __y._M_current < __x._M_current; }
8427 friend constexpr bool
8428 operator<=(
const _Iterator& __x,
const _Iterator& __y)
8429 requires random_access_range<_Base>
8430 {
return !(__y._M_current < __x._M_current); }
8432 friend constexpr bool
8433 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8434 requires random_access_range<_Base>
8435 {
return !(__x._M_current < __y._M_current); }
8437 friend constexpr auto
8438 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8439 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8440 {
return __x._M_current <=> __y._M_current; }
8442 friend constexpr _Iterator
8443 operator+(
const _Iterator& __i, difference_type __n)
8444 requires random_access_range<_Base>
8451 friend constexpr _Iterator
8452 operator+(difference_type __n,
const _Iterator& __i)
8453 requires random_access_range<_Base>
8454 {
return __i + __n; }
8456 friend constexpr _Iterator
8457 operator-(
const _Iterator& __i, difference_type __n)
8458 requires random_access_range<_Base>
8465 friend constexpr difference_type
8466 operator-(
const _Iterator& __x,
const _Iterator& __y)
8467 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8469 auto __n = __x._M_current - __y._M_current;
8470 if constexpr (forward_range<_Base>)
8471 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8473 return -__detail::__div_ceil(-__n, __x._M_stride);
8475 return __detail::__div_ceil(__n, __x._M_stride);
8478 friend constexpr difference_type
8479 operator-(default_sentinel_t,
const _Iterator& __x)
8480 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8481 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8483 friend constexpr difference_type
8484 operator-(
const _Iterator& __x, default_sentinel_t __y)
8485 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8486 {
return -(__y - __x); }
8488 friend constexpr range_rvalue_reference_t<_Base>
8489 iter_move(
const _Iterator& __i)
8490 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8491 {
return ranges::iter_move(__i._M_current); }
8493 friend constexpr void
8494 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8495 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8496 requires indirectly_swappable<iterator_t<_Base>>
8497 { ranges::iter_swap(__x._M_current, __y._M_current); }
8504 template<
typename _Range,
typename _Dp>
8505 concept __can_stride_view
8509 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8511 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8512 requires __detail::__can_stride_view<_Range, _Dp>
8514 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8517 using __adaptor::_RangeAdaptor<_Stride>::operator();
8518 static constexpr int _S_arity = 2;
8519 static constexpr bool _S_has_simple_extra_args =
true;
8522 inline constexpr _Stride stride;
8526#ifdef __cpp_lib_ranges_cartesian_product
8529 template<
bool _Const,
typename _First,
typename... _Vs>
8530 concept __cartesian_product_is_random_access
8531 = (random_access_range<__maybe_const_t<_Const, _First>>
8533 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8534 && sized_range<__maybe_const_t<_Const, _Vs>>));
8536 template<
typename _Range>
8537 concept __cartesian_product_common_arg
8538 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8540 template<
bool _Const,
typename _First,
typename... _Vs>
8541 concept __cartesian_product_is_bidirectional
8542 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8544 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8545 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8547 template<
typename _First,
typename... _Vs>
8548 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8550 template<
typename... _Vs>
8551 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8553 template<
bool _Const,
template<
typename>
class FirstSent,
typename _First,
typename... _Vs>
8554 concept __cartesian_is_sized_sentinel
8555 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8556 iterator_t<__maybe_const_t<_Const, _First>>>
8558 && (sized_range<__maybe_const_t<_Const, _Vs>>
8559 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8560 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8562 template<__cartesian_product_common_arg _Range>
8564 __cartesian_common_arg_end(_Range& __r)
8566 if constexpr (common_range<_Range>)
8567 return ranges::end(__r);
8569 return ranges::begin(__r) + ranges::distance(__r);
8573 template<input_range _First, forward_range... _Vs>
8574 requires (view<_First> && ... && view<_Vs>)
8575 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8577 tuple<_First, _Vs...> _M_bases;
8579 template<
bool>
class _Iterator;
8582 _S_difference_type()
8588 range_difference_t<_First>,
8589 range_difference_t<_Vs>...>{};
8593 cartesian_product_view() =
default;
8596 cartesian_product_view(_First __first, _Vs... __rest)
8600 constexpr _Iterator<false>
8601 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8602 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8604 constexpr _Iterator<true>
8605 begin() const requires (range<const _First> && ... && range<const _Vs>)
8606 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8608 constexpr _Iterator<false>
8609 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8610 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8613 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8614 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8615 auto& __first = std::get<0>(_M_bases);
8616 return _Ret{(__empty_tail
8617 ? ranges::begin(__first)
8618 : __detail::__cartesian_common_arg_end(__first)),
8619 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8622 return _Iterator<false>{*
this,
std::move(__its)};
8625 constexpr _Iterator<true>
8626 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8629 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8630 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8631 auto& __first = std::get<0>(_M_bases);
8632 return _Ret{(__empty_tail
8633 ? ranges::begin(__first)
8634 : __detail::__cartesian_common_arg_end(__first)),
8635 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8638 return _Iterator<true>{*
this,
std::move(__its)};
8641 constexpr default_sentinel_t
8642 end() const noexcept
8646 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8648 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8650 auto __size =
static_cast<_ST
>(1);
8651#ifdef _GLIBCXX_ASSERTIONS
8652 if constexpr (integral<_ST>)
8655 = (__builtin_mul_overflow(__size,
8656 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8659 __glibcxx_assert(!__overflow);
8663 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8669 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8671 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8673 auto __size =
static_cast<_ST
>(1);
8674#ifdef _GLIBCXX_ASSERTIONS
8675 if constexpr (integral<_ST>)
8678 = (__builtin_mul_overflow(__size,
8679 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8682 __glibcxx_assert(!__overflow);
8686 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8692 template<
typename... _Vs>
8693 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8695 template<input_range _First, forward_range... _Vs>
8696 requires (view<_First> && ... && view<_Vs>)
8697 template<bool _Const>
8698 class cartesian_product_view<_First, _Vs...>::_Iterator
8700 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8701 _Parent* _M_parent =
nullptr;
8702 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8703 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8706 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8708 _M_current(
std::
move(__current))
8714 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8715 return random_access_iterator_tag{};
8716 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8717 return bidirectional_iterator_tag{};
8718 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8719 return forward_iterator_tag{};
8721 return input_iterator_tag{};
8724 friend cartesian_product_view;
8727 using iterator_category = input_iterator_tag;
8728 using iterator_concept =
decltype(_S_iter_concept());
8730 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8731 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8733 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8734 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8735 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8737 _Iterator() =
default;
8740 _Iterator(_Iterator<!_Const> __i)
8742 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8743 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8745 _M_current(
std::
move(__i._M_current))
8751 auto __f = [](
auto& __i) ->
decltype(
auto) {
8754 return __detail::__tuple_transform(__f, _M_current);
8757 constexpr _Iterator&
8769 operator++(
int)
requires forward_range<__maybe_const_t<_Const, _First>>
8776 constexpr _Iterator&
8778 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8786 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8793 constexpr _Iterator&
8794 operator+=(difference_type __x)
8795 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8801 constexpr _Iterator&
8802 operator-=(difference_type __x)
8803 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8804 {
return *
this += -__x; }
8807 operator[](difference_type __n)
const
8808 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8809 {
return *((*this) + __n); }
8811 friend constexpr bool
8812 operator==(
const _Iterator& __x,
const _Iterator& __y)
8813 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8814 {
return __x._M_current == __y._M_current; }
8816 friend constexpr bool
8817 operator==(
const _Iterator& __x, default_sentinel_t)
8820 return ((std::get<_Is>(__x._M_current)
8821 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8826 friend constexpr auto
8827 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8828 requires __detail::__all_random_access<_Const, _First, _Vs...>
8829 {
return __x._M_current <=> __y._M_current; }
8831 friend constexpr _Iterator
8832 operator+(_Iterator __x, difference_type __y)
8833 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8834 {
return __x += __y; }
8836 friend constexpr _Iterator
8837 operator+(difference_type __x, _Iterator __y)
8838 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8839 {
return __y += __x; }
8841 friend constexpr _Iterator
8842 operator-(_Iterator __x, difference_type __y)
8843 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8844 {
return __x -= __y; }
8846 friend constexpr difference_type
8847 operator-(
const _Iterator& __x,
const _Iterator& __y)
8848 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8849 {
return __x._M_distance_from(__y._M_current); }
8851 friend constexpr difference_type
8852 operator-(
const _Iterator& __i, default_sentinel_t)
8853 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8856 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8857 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8859 return __i._M_distance_from(__end_tuple);
8862 friend constexpr difference_type
8863 operator-(default_sentinel_t,
const _Iterator& __i)
8864 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8867 friend constexpr auto
8868 iter_move(
const _Iterator& __i)
8869 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8871 friend constexpr void
8872 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8873 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8875 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8878 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8883 template<
size_t _Nm =
sizeof...(_Vs)>
8887 auto& __it = std::get<_Nm>(_M_current);
8889 if constexpr (_Nm > 0)
8890 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8892 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8897 template<
size_t _Nm =
sizeof...(_Vs)>
8901 auto& __it = std::get<_Nm>(_M_current);
8902 if constexpr (_Nm > 0)
8903 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8905 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8911 template<
size_t _Nm =
sizeof...(_Vs)>
8913 _M_advance(difference_type __x)
8914 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8923 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8924 auto& __it = std::get<_Nm>(_M_current);
8925 if constexpr (_Nm == 0)
8927#ifdef _GLIBCXX_ASSERTIONS
8928 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8930 auto __size = ranges::ssize(__r);
8931 auto __begin = ranges::begin(__r);
8932 auto __offset = __it - __begin;
8933 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8940 auto __size = ranges::ssize(__r);
8941 auto __begin = ranges::begin(__r);
8942 auto __offset = __it - __begin;
8944 __x = __offset / __size;
8948 __offset = __size + __offset;
8951 __it = __begin + __offset;
8952 _M_advance<_Nm - 1>(__x);
8957 template<
typename _Tuple>
8958 constexpr difference_type
8959 _M_distance_from(
const _Tuple& __t)
const
8962 auto __sum =
static_cast<difference_type
>(0);
8963#ifdef _GLIBCXX_ASSERTIONS
8964 if constexpr (integral<difference_type>)
8967 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8969 __glibcxx_assert(!__overflow);
8973 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8978 template<
size_t _Nm,
typename _Tuple>
8979 constexpr difference_type
8980 _M_scaled_distance(
const _Tuple& __t)
const
8982 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8983 - std::get<_Nm>(__t));
8984#ifdef _GLIBCXX_ASSERTIONS
8985 if constexpr (integral<difference_type>)
8987 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8988 __glibcxx_assert(!__overflow);
8992 __dist *= _M_scaled_size<_Nm+1>();
8996 template<
size_t _Nm>
8997 constexpr difference_type
8998 _M_scaled_size()
const
9000 if constexpr (_Nm <=
sizeof...(_Vs))
9002 auto __size =
static_cast<difference_type
>(ranges::size
9003 (std::get<_Nm>(_M_parent->_M_bases)));
9004#ifdef _GLIBCXX_ASSERTIONS
9005 if constexpr (integral<difference_type>)
9007 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
9008 __glibcxx_assert(!__overflow);
9012 __size *= _M_scaled_size<_Nm+1>();
9016 return static_cast<difference_type
>(1);
9024 template<
typename... _Ts>
9025 concept __can_cartesian_product_view
9029 struct _CartesianProduct
9031 template<
typename... _Ts>
9032 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
9034 operator() [[nodiscard]] (_Ts&&... __ts)
const
9036 if constexpr (
sizeof...(_Ts) == 0)
9037 return views::single(tuple{});
9043 inline constexpr _CartesianProduct cartesian_product;
9047#ifdef __cpp_lib_ranges_as_rvalue
9048 template<input_range _Vp>
9050 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
9052 _Vp _M_base = _Vp();
9055 as_rvalue_view()
requires default_initializable<_Vp> = default;
9058 as_rvalue_view(_Vp __base)
9059 : _M_base(std::move(__base))
9063 base() const& requires copy_constructible<_Vp>
9071 begin()
requires (!__detail::__simple_view<_Vp>)
9072 {
return move_iterator(ranges::begin(_M_base)); }
9075 begin() const requires range<const _Vp>
9076 {
return move_iterator(ranges::begin(_M_base)); }
9079 end()
requires (!__detail::__simple_view<_Vp>)
9081 if constexpr (common_range<_Vp>)
9082 return move_iterator(ranges::end(_M_base));
9084 return move_sentinel(ranges::end(_M_base));
9088 end() const requires range<const _Vp>
9090 if constexpr (common_range<const _Vp>)
9091 return move_iterator(ranges::end(_M_base));
9093 return move_sentinel(ranges::end(_M_base));
9097 size()
requires sized_range<_Vp>
9098 {
return ranges::size(_M_base); }
9101 size() const requires sized_range<const _Vp>
9102 {
return ranges::size(_M_base); }
9105 template<
typename _Range>
9106 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
9108 template<
typename _Tp>
9109 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
9110 = enable_borrowed_range<_Tp>;
9116 template<
typename _Tp>
9117 concept __can_as_rvalue_view =
requires { as_rvalue_view(
std::declval<_Tp>()); };
9120 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
9122 template<viewable_range _Range>
9123 requires __detail::__can_as_rvalue_view<_Range>
9125 operator() [[nodiscard]] (_Range&& __r)
const
9127 if constexpr (same_as<range_rvalue_reference_t<_Range>,
9128 range_reference_t<_Range>>)
9135 inline constexpr _AsRvalue as_rvalue;
9139#ifdef __cpp_lib_ranges_enumerate
9142 template<
typename _Range>
9143 concept __range_with_movable_reference = input_range<_Range>
9144 && move_constructible<range_reference_t<_Range>>
9145 && move_constructible<range_rvalue_reference_t<_Range>>;
9149 requires __detail::__range_with_movable_reference<_Vp>
9150 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
9152 _Vp _M_base = _Vp();
9154 template<
bool _Const>
class _Iterator;
9155 template<
bool _Const>
class _Sentinel;
9158 enumerate_view()
requires default_initializable<_Vp> = default;
9161 enumerate_view(_Vp __base)
9162 : _M_base(std::move(__base))
9166 begin()
requires (!__detail::__simple_view<_Vp>)
9167 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
9170 begin() const requires __detail::__range_with_movable_reference<const _Vp>
9171 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
9174 end()
requires (!__detail::__simple_view<_Vp>)
9176 if constexpr (common_range<_Vp> && sized_range<_Vp>)
9177 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
9179 return _Sentinel<false>(ranges::end(_M_base));
9183 end() const requires __detail::__range_with_movable_reference<const _Vp>
9185 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9186 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9188 return _Sentinel<true>(ranges::end(_M_base));
9192 size()
requires sized_range<_Vp>
9193 {
return ranges::size(_M_base); }
9196 size() const requires sized_range<const _Vp>
9197 {
return ranges::size(_M_base); }
9200 base() const & requires copy_constructible<_Vp>
9208 template<
typename _Range>
9209 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9211 template<
typename _Tp>
9212 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9213 = enable_borrowed_range<_Tp>;
9216 requires __detail::__range_with_movable_reference<_Vp>
9217 template<
bool _Const>
9218 class enumerate_view<_Vp>::_Iterator
9220 using _Base = __maybe_const_t<_Const, _Vp>;
9225 if constexpr (random_access_range<_Base>)
9226 return random_access_iterator_tag{};
9227 else if constexpr (bidirectional_range<_Base>)
9228 return bidirectional_iterator_tag{};
9229 else if constexpr (forward_range<_Base>)
9230 return forward_iterator_tag{};
9232 return input_iterator_tag{};
9235 friend enumerate_view;
9238 using iterator_category = input_iterator_tag;
9239 using iterator_concept =
decltype(_S_iter_concept());
9240 using difference_type = range_difference_t<_Base>;
9241 using value_type = tuple<difference_type, range_value_t<_Base>>;
9244 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9246 iterator_t<_Base> _M_current = iterator_t<_Base>();
9247 difference_type _M_pos = 0;
9250 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9251 : _M_current(std::
move(__current)), _M_pos(__pos)
9255 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
9258 _Iterator(_Iterator<!_Const> __i)
9259 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9260 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9263 constexpr const iterator_t<_Base> &
9264 base() const & noexcept
9265 {
return _M_current; }
9267 constexpr iterator_t<_Base>
9271 constexpr difference_type
9272 index() const noexcept
9277 {
return __reference_type(_M_pos, *_M_current); }
9279 constexpr _Iterator&
9292 operator++(
int)
requires forward_range<_Base>
9299 constexpr _Iterator&
9300 operator--()
requires bidirectional_range<_Base>
9308 operator--(
int)
requires bidirectional_range<_Base>
9315 constexpr _Iterator&
9316 operator+=(difference_type __n)
requires random_access_range<_Base>
9323 constexpr _Iterator&
9324 operator-=(difference_type __n)
requires random_access_range<_Base>
9332 operator[](difference_type __n)
const requires random_access_range<_Base>
9333 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9335 friend constexpr bool
9336 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9337 {
return __x._M_pos == __y._M_pos; }
9339 friend constexpr strong_ordering
9340 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9341 {
return __x._M_pos <=> __y._M_pos; }
9343 friend constexpr _Iterator
9344 operator+(
const _Iterator& __x, difference_type __y)
9345 requires random_access_range<_Base>
9346 {
return (
auto(__x) += __y); }
9348 friend constexpr _Iterator
9349 operator+(difference_type __x,
const _Iterator& __y)
9350 requires random_access_range<_Base>
9351 {
return auto(__y) += __x; }
9353 friend constexpr _Iterator
9354 operator-(
const _Iterator& __x, difference_type __y)
9355 requires random_access_range<_Base>
9356 {
return auto(__x) -= __y; }
9358 friend constexpr difference_type
9359 operator-(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9360 {
return __x._M_pos - __y._M_pos; }
9362 friend constexpr auto
9363 iter_move(
const _Iterator& __i)
9364 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9365 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9367 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9368 (__i._M_pos, ranges::iter_move(__i._M_current));
9373 requires __detail::__range_with_movable_reference<_Vp>
9374 template<
bool _Const>
9375 class enumerate_view<_Vp>::_Sentinel
9377 using _Base = __maybe_const_t<_Const, _Vp>;
9379 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9382 _Sentinel(sentinel_t<_Base> __end)
9383 : _M_end(std::
move(__end))
9386 friend enumerate_view;
9389 _Sentinel() =
default;
9392 _Sentinel(_Sentinel<!_Const> __other)
9393 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9397 constexpr sentinel_t<_Base>
9401 template<
bool _OtherConst>
9402 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9403 friend constexpr bool
9404 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9405 {
return __x._M_current == __y._M_end; }
9407 template<
bool _OtherConst>
9408 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9409 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9410 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9411 {
return __x._M_current - __y._M_end; }
9413 template<
bool _OtherConst>
9414 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9415 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9416 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9417 {
return __x._M_end - __y._M_current; }
9424 template<
typename _Tp>
9425 concept __can_enumerate_view
9429 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9431 template<viewable_range _Range>
9432 requires __detail::__can_enumerate_view<_Range>
9434 operator() [[nodiscard]] (_Range&& __r)
const
9438 inline constexpr _Enumerate enumerate;
9442#ifdef __cpp_lib_ranges_as_const
9444 requires input_range<_Vp>
9445 class as_const_view :
public view_interface<as_const_view<_Vp>>
9447 _Vp _M_base = _Vp();
9450 as_const_view()
requires default_initializable<_Vp> = default;
9453 as_const_view(_Vp __base)
9454 noexcept(is_nothrow_move_constructible_v<_Vp>)
9455 : _M_base(std::move(__base))
9460 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9461 requires copy_constructible<_Vp>
9466 noexcept(is_nothrow_move_constructible_v<_Vp>)
9470 begin()
requires (!__detail::__simple_view<_Vp>)
9471 {
return ranges::cbegin(_M_base); }
9474 begin() const requires range<const _Vp>
9475 {
return ranges::cbegin(_M_base); }
9478 end()
requires (!__detail::__simple_view<_Vp>)
9479 {
return ranges::cend(_M_base); }
9482 end() const requires range<const _Vp>
9483 {
return ranges::cend(_M_base); }
9486 size()
requires sized_range<_Vp>
9487 {
return ranges::size(_M_base); }
9490 size() const requires sized_range<const _Vp>
9491 {
return ranges::size(_M_base); }
9494 template<
typename _Range>
9495 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9497 template<
typename _Tp>
9498 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9499 = enable_borrowed_range<_Tp>;
9505 template<
typename _Tp>
9506 inline constexpr bool __is_constable_ref_view =
false;
9508 template<
typename _Range>
9509 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9510 = constant_range<const _Range>;
9512 template<
typename _Range>
9516 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9518 template<viewable_range _Range>
9520 operator()(_Range&& __r)
const
9522 requires __detail::__can_as_const_view<_Range>
9524 using _Tp = remove_cvref_t<_Range>;
9525 using element_type = remove_reference_t<range_reference_t<_Range>>;
9526 if constexpr (constant_range<views::all_t<_Range>>)
9528 else if constexpr (__detail::__is_empty_view<_Tp>)
9529 return views::empty<const element_type>;
9530#if __cpp_lib_optional >= 202506L && __cpp_lib_optional_range_support
9531 else if constexpr (__is_optional_ref_v<_Tp>)
9532 return optional<const typename _Tp::value_type&>(__r);
9534 else if constexpr (std::__detail::__is_span<_Tp>)
9536 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9538 else if constexpr (is_lvalue_reference_v<_Range>
9539 && constant_range<const _Tp>
9541 return ref_view(
static_cast<const _Tp&
>(__r));
9547 inline constexpr _AsConst as_const;
9552 namespace views = ranges::views;
9554#if __cpp_lib_ranges_to_container
9560 template<
typename _Container>
9561 constexpr bool __reservable_container
9562 = sized_range<_Container>
9563 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9565 { __c.capacity() } -> same_as<
decltype(__n)>;
9566 { __c.max_size() } -> same_as<
decltype(__n)>;
9569 template<
typename _Cont,
typename _Range>
9570 constexpr bool __toable =
requires {
9571 requires (!input_range<_Cont>
9572 || convertible_to<range_reference_t<_Range>,
9573 range_value_t<_Cont>>);
9594 template<
typename _Cont, input_range _Rg,
typename... _Args>
9595 requires (!view<_Cont>)
9597 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9599 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9600 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9602 if constexpr (__detail::__toable<_Cont, _Rg>)
9604 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9607 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9610 else if constexpr (
requires {
requires common_range<_Rg>;
9611 typename __iter_category_t<iterator_t<_Rg>>;
9612 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9613 input_iterator_tag>;
9614 requires constructible_from<_Cont, iterator_t<_Rg>,
9615 sentinel_t<_Rg>, _Args...>;
9617 return _Cont(ranges::begin(__r), ranges::end(__r),
9621 static_assert(constructible_from<_Cont, _Args...>);
9623 if constexpr (sized_range<_Rg>
9624 && __detail::__reservable_container<_Cont>)
9625 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9629 auto __it = ranges::begin(__r);
9630 const auto __sent = ranges::end(__r);
9631 while (__it != __sent)
9633 if constexpr (
requires { __c.emplace_back(*__it); })
9634 __c.emplace_back(*__it);
9635 else if constexpr (
requires { __c.push_back(*__it); })
9636 __c.push_back(*__it);
9637 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9638 __c.emplace(__c.end(), *__it);
9640 __c.insert(__c.end(), *__it);
9648 static_assert(input_range<range_reference_t<_Rg>>);
9651 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9652 []<
typename _Elt>(_Elt&& __elem) {
9653 using _ValT = range_value_t<_Cont>;
9662 template<
typename _Rg>
9665 using iterator_category = input_iterator_tag;
9666 using value_type = range_value_t<_Rg>;
9667 using difference_type = ptrdiff_t;
9668 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9669 using reference = range_reference_t<_Rg>;
9671 pointer operator->()
const;
9672 _InputIter& operator++();
9673 _InputIter operator++(
int);
9674 bool operator==(
const _InputIter&)
const;
9677 template<
template<
typename...>
typename _Cont, input_range _Rg,
9682 template<
template<
typename...>
typename _Cont, input_range _Rg,
9688 template<
template<
typename...>
typename _Cont, input_range _Rg,
9698 template<
template<
typename...>
typename _Cont, input_range _Rg,
9701 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9703 using __detail::_DeduceExpr1;
9704 using __detail::_DeduceExpr2;
9705 using __detail::_DeduceExpr3;
9706 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9707 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9709 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9710 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9712 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9713 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9716 static_assert(
false);
9722 template<
typename _Cont>
9725 template<
typename _Range,
typename... _Args>
9729 operator()(_Range&& __r, _Args&&... __args)
const
9753 template<
typename _Cont,
typename... _Args>
9754 requires (!view<_Cont>)
9756 to [[nodiscard]] (_Args&&... __args)
9758 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9759 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9761 using __detail::_To;
9762 using views::__adaptor::_Partial;
9769 template<
template<
typename...>
typename _Cont>
9772 template<
typename _Range,
typename... _Args>
9776 operator()(_Range&& __r, _Args&&... __args)
const
9802 template<
template<
typename...>
typename _Cont,
typename... _Args>
9804 to [[nodiscard]] (_Args&&... __args)
9806 using __detail::_To2;
9807 using views::__adaptor::_Partial;
9814#if __cpp_lib_ranges_concat
9819 template<
typename... _Rs>
9820 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9822 template<
typename... _Rs>
9823 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9825 template<
typename... _Rs>
9826 using __concat_rvalue_reference_t
9827 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9829 template<
typename _Ref,
typename _RRef,
typename _It>
9830 concept __concat_indirectly_readable_impl =
requires(
const _It __it) {
9831 { *__it } -> convertible_to<_Ref>;
9832 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9835 template<
typename... _Rs>
9836 concept __concat_indirectly_readable
9837 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9838 && common_reference_with<__concat_reference_t<_Rs...>&&,
9839 __concat_rvalue_reference_t<_Rs...>&&>
9840 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9841 __concat_value_t<_Rs...>
const&>
9842 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9843 __concat_rvalue_reference_t<_Rs...>,
9847 template<
typename... _Rs>
9848 concept __concatable =
requires {
9849 typename __concat_reference_t<_Rs...>;
9850 typename __concat_value_t<_Rs...>;
9851 typename __concat_rvalue_reference_t<_Rs...>;
9852 } && __concat_indirectly_readable<_Rs...>;
9854 template<
bool _Const,
typename _Range,
typename... _Rs>
9855 struct __all_but_last_common
9857 static inline constexpr bool value
9858 =
requires {
requires (common_range<__maybe_const_t<_Const, _Range>>
9859 && __all_but_last_common<_Const, _Rs...>::value); };
9862 template<
bool _Const,
typename _Range>
9863 struct __all_but_last_common<_Const, _Range>
9864 {
static inline constexpr bool value =
true; };
9866 template<
bool _Const,
typename... _Rs>
9867 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9868 && __all_but_last_common<_Const, _Rs...>::value;
9870 template<
bool _Const,
typename... _Rs>
9871 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9872 && __all_but_last_common<_Const, _Rs...>::value;
9874 template<
typename _Range,
typename... _Rs>
9875 struct __all_but_first_sized
9876 {
static inline constexpr bool value = (sized_range<_Rs> && ...); };
9879 template<input_range... _Vs>
9880 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9881 class concat_view : public view_interface<concat_view<_Vs...>>
9883 tuple<_Vs...> _M_views;
9885 template<
bool _Const>
class _Iterator;
9888 constexpr concat_view() =
default;
9891 concat_view(_Vs... __views)
9892 : _M_views(std::
move(__views)...)
9895 constexpr _Iterator<false>
9896 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
9898 _Iterator<false> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9899 __it.template _M_satisfy<0>();
9903 constexpr _Iterator<true>
9904 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9906 _Iterator<true> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9907 __it.template _M_satisfy<0>();
9912 end()
requires (!(__detail::__simple_view<_Vs> && ...))
9914 constexpr auto __n =
sizeof...(_Vs);
9915 if constexpr (__detail::__all_forward<
false, _Vs...>
9916 && common_range<_Vs...[__n - 1]>)
9917 return _Iterator<false>(
this, in_place_index<__n - 1>,
9918 ranges::end(std::get<__n - 1>(_M_views)));
9924 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9926 constexpr auto __n =
sizeof...(_Vs);
9927 if constexpr (__detail::__all_forward<
true, _Vs...>
9928 && common_range<
const _Vs...[__n - 1]>)
9929 return _Iterator<true>(
this, in_place_index<__n - 1>,
9930 ranges::end(std::get<__n - 1>(_M_views)));
9936 size()
requires (sized_range<_Vs>&&...)
9938 return std::apply([](
auto... __sizes) {
9939 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9940 return (_CT(__sizes) + ...);
9941 }, __detail::__tuple_transform(ranges::size, _M_views));
9945 size() const requires (sized_range<const _Vs>&&...)
9947 return std::apply([](
auto... __sizes) {
9948 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9949 return (_CT(__sizes) + ...);
9950 }, __detail::__tuple_transform(ranges::size, _M_views));
9954 template<
typename... _Rs>
9955 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9959 template<
bool _Const,
typename... _Vs>
9960 struct __concat_view_iter_cat
9963 template<
bool _Const,
typename... _Vs>
9964 requires __detail::__all_forward<_Const, _Vs...>
9965 struct __concat_view_iter_cat<_Const, _Vs...>
9970 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9971 return input_iterator_tag{};
9973 return []<
typename... _Cats>(_Cats... __cats) {
9974 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9975 && __concat_is_random_access<_Const, _Vs...>)
9976 return random_access_iterator_tag{};
9977 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9978 && __concat_is_bidirectional<_Const, _Vs...>)
9979 return bidirectional_iterator_tag{};
9980 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9981 return forward_iterator_tag{};
9983 return input_iterator_tag{};
9984 }(
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9985 ::iterator_category{}...);
9990 template<input_range... _Vs>
9991 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9992 template<bool _Const>
9993 class concat_view<_Vs...>::_Iterator
9994 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9999 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
10000 return random_access_iterator_tag{};
10001 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
10002 return bidirectional_iterator_tag{};
10003 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
10004 return forward_iterator_tag{};
10006 return input_iterator_tag{};
10009 friend concat_view;
10010 friend _Iterator<!_Const>;
10014 using iterator_concept =
decltype(_S_iter_concept());
10015 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
10016 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
10019 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
10021 __maybe_const_t<_Const, concat_view>* _M_parent =
nullptr;
10024 template<
size_t _Nm>
10028 if constexpr (_Nm < (
sizeof...(_Vs) - 1))
10030 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
10032 _M_it.template emplace<_Nm + 1>(ranges::begin
10033 (std::get<_Nm + 1>(_M_parent->_M_views)));
10034 _M_satisfy<_Nm + 1>();
10039 template<
size_t _Nm>
10043 if constexpr (_Nm == 0)
10044 --std::get<0>(_M_it);
10047 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
10049 _M_it.template emplace<_Nm - 1>(ranges::end
10050 (std::get<_Nm - 1>(_M_parent->_M_views)));
10051 _M_prev<_Nm - 1>();
10054 --std::get<_Nm>(_M_it);
10058 template<
size_t _Nm>
10060 _M_advance_fwd(difference_type __offset, difference_type __steps)
10062 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10063 if constexpr (_Nm ==
sizeof...(_Vs) - 1)
10064 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10067 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
10068 if (__offset + __steps < __n_size)
10069 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10072 _M_it.template emplace<_Nm + 1>(ranges::begin
10073 (std::get<_Nm + 1>(_M_parent->_M_views)));
10074 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
10079 template<
size_t _Nm>
10081 _M_advance_bwd(difference_type __offset, difference_type __steps)
10083 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10084 if constexpr (_Nm == 0)
10085 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10087 if (__offset >= __steps)
10088 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10091 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
10092 _M_it.template emplace<_Nm - 1>(ranges::end
10093 (std::get<_Nm - 1>(_M_parent->_M_views)));
10094 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
10102 template<
typename _Fp>
10103 static constexpr auto
10104 _S_invoke_with_runtime_index(_Fp&& __f,
size_t __index)
10106 return [&__f, __index]<
size_t _Idx>(
this auto&& __self) {
10107 if (_Idx == __index)
10108 return __f.template operator()<_Idx>();
10109 if constexpr (_Idx + 1 <
sizeof...(_Vs))
10110 return __self.template
operator()<_Idx + 1>();
10111 __builtin_unreachable();
10112 }.template operator()<0>();
10115 template<
typename _Fp>
10117 _M_invoke_with_runtime_index(_Fp&& __f)
10118 {
return _S_invoke_with_runtime_index(
std::forward<_Fp>(__f), _M_it.index()); }
10120 template<
typename... _Args>
10122 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
10123 requires constructible_from<__base_iter, _Args&&...>
10128 _Iterator() =
default;
10131 _Iterator(_Iterator<!_Const> __it)
10132 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
10133 : _M_parent(__it._M_parent),
10134 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
10135 return __base_iter(in_place_index<_Idx>,
10136 std::get<_Idx>(
std::move(__it._M_it)));
10137 }, __it._M_it.index()))
10140 constexpr decltype(
auto)
10143 __glibcxx_assert(!_M_it.valueless_by_exception());
10144 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
10145 return std::visit([](
auto&& __it) -> reference {
return *__it; }, _M_it);
10148 constexpr _Iterator&
10151 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10152 ++std::get<_Idx>(_M_it);
10153 _M_satisfy<_Idx>();
10162 constexpr _Iterator
10164 requires __detail::__all_forward<_Const, _Vs...>
10166 auto __tmp = *
this;
10171 constexpr _Iterator&
10173 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10175 __glibcxx_assert(!_M_it.valueless_by_exception());
10176 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10182 constexpr _Iterator
10184 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10186 auto __tmp = *
this;
10191 constexpr _Iterator&
10192 operator+=(difference_type __n)
10193 requires __detail::__concat_is_random_access<_Const, _Vs...>
10195 __glibcxx_assert(!_M_it.valueless_by_exception());
10196 _M_invoke_with_runtime_index([
this, __n]<
size_t _Idx>() {
10197 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10199 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10201 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10206 constexpr _Iterator&
10207 operator-=(difference_type __n)
10208 requires __detail::__concat_is_random_access<_Const, _Vs...>
10214 constexpr decltype(
auto)
10215 operator[](difference_type __n)
const
10216 requires __detail::__concat_is_random_access<_Const, _Vs...>
10217 {
return *((*this) + __n); }
10219 friend constexpr bool
10220 operator==(
const _Iterator& __x,
const _Iterator& __y)
10221 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10223 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10224 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10225 return __x._M_it == __y._M_it;
10228 friend constexpr bool
10229 operator==(
const _Iterator& __it, default_sentinel_t)
10231 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10232 constexpr auto __last_idx =
sizeof...(_Vs) - 1;
10233 return (__it._M_it.index() == __last_idx
10234 && (std::get<__last_idx>(__it._M_it)
10235 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10238 friend constexpr bool
10239 operator<(
const _Iterator& __x,
const _Iterator& __y)
10240 requires __detail::__all_random_access<_Const, _Vs...>
10241 {
return __x._M_it < __y._M_it; }
10243 friend constexpr bool
10244 operator>(
const _Iterator& __x,
const _Iterator& __y)
10245 requires __detail::__all_random_access<_Const, _Vs...>
10246 {
return __x._M_it > __y._M_it; }
10248 friend constexpr bool
10249 operator<=(
const _Iterator& __x,
const _Iterator& __y)
10250 requires __detail::__all_random_access<_Const, _Vs...>
10251 {
return __x._M_it <= __y._M_it; }
10253 friend constexpr bool
10254 operator>=(
const _Iterator& __x,
const _Iterator& __y)
10255 requires __detail::__all_random_access<_Const, _Vs...>
10256 {
return __x._M_it >= __y._M_it; }
10258 friend constexpr auto
10259 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
10260 requires __detail::__all_random_access<_Const, _Vs...>
10261 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10262 {
return __x._M_it <=> __y._M_it; }
10264 friend constexpr _Iterator
10265 operator+(
const _Iterator& __it, difference_type __n)
10266 requires __detail::__concat_is_random_access<_Const, _Vs...>
10267 {
return auto(__it) += __n; }
10269 friend constexpr _Iterator
10270 operator+(difference_type __n,
const _Iterator& __it)
10271 requires __detail::__concat_is_random_access<_Const, _Vs...>
10272 {
return __it + __n; }
10274 friend constexpr _Iterator
10275 operator-(
const _Iterator& __it, difference_type __n)
10276 requires __detail::__concat_is_random_access<_Const, _Vs...>
10277 {
return auto(__it) -= __n; }
10279 friend constexpr difference_type
10280 operator-(
const _Iterator& __x,
const _Iterator& __y)
10281 requires __detail::__concat_is_random_access<_Const, _Vs...>
10283 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10284 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> difference_type {
10285 if constexpr (_Ix > _Iy)
10287 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10288 ranges::end(std::get<_Iy>(__y._M_parent
10290 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10292 std::get<_Ix>(__x._M_it));
10293 difference_type __s = 0;
10294 [&]<
size_t _Idx = _Iy + 1>(
this auto&& __self) {
10295 if constexpr (_Idx < _Ix)
10297 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10298 __self.template operator()<_Idx + 1>();
10301 return __dy + __s + __dx;
10303 else if constexpr (_Ix < _Iy)
10304 return -(__y - __x);
10306 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10307 }, __y._M_it.index());
10308 }, __x._M_it.index());
10311 friend constexpr difference_type
10312 operator-(
const _Iterator& __x, default_sentinel_t)
10313 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10314 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10315 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10317 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10318 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10319 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10320 difference_type __s = 0;
10321 [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) {
10322 if constexpr (_Idx <
sizeof...(_Vs))
10324 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10325 __self.template operator()<_Idx + 1>();
10328 return -(__dx + __s);
10329 }, __x._M_it.index());
10332 friend constexpr difference_type
10333 operator-(default_sentinel_t,
const _Iterator& __x)
10334 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10335 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10336 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10339 friend constexpr decltype(
auto)
10340 iter_move(
const _Iterator& __it)
10342 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10343 return std::visit([](
const auto& __i) -> _Res {
10344 return ranges::iter_move(__i);
10348 friend constexpr void
10349 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10350 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10351 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10353 std::visit([&]<
typename _Tp,
typename _Up>(
const _Tp& __it1,
const _Up& __it2) {
10354 if constexpr (is_same_v<_Tp, _Up>)
10355 ranges::iter_swap(__it1, __it2);
10357 ranges::swap(*__it1, *__it2);
10358 }, __x._M_it, __y._M_it);
10366 template<
typename... _Ts>
10372 template<
typename... _Ts>
10373 requires __detail::__can_concat_view<_Ts...>
10375 operator() [[nodiscard]] (_Ts&&... __ts)
const
10378 template<input_range _Range>
10380 operator() [[nodiscard]] (_Range&& __t)
const
10384 inline constexpr _Concat concat;
10390#if __cpp_lib_ranges_cache_latest
10393 template<input_range _Vp>
10395 class cache_latest_view :
public view_interface<cache_latest_view<_Vp>>
10397 _Vp _M_base = _Vp();
10399 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10400 add_pointer_t<range_reference_t<_Vp>>,
10401 range_reference_t<_Vp>>;
10402 __detail::__non_propagating_cache<__cache_t> _M_cache;
10408 cache_latest_view()
requires default_initializable<_Vp> = default;
10411 cache_latest_view(_Vp __base)
10412 : _M_base(std::move(__base))
10416 base() const & requires copy_constructible<_Vp>
10417 {
return _M_base; }
10425 {
return _Iterator(*
this); }
10429 {
return _Sentinel(*
this); }
10432 size()
requires sized_range<_Vp>
10433 {
return ranges::size(_M_base); }
10436 size() const requires sized_range<const _Vp>
10437 {
return ranges::size(_M_base); }
10440 template<
typename _Range>
10441 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10443 template<input_range _Vp>
10445 class cache_latest_view<_Vp>::_Iterator
10447 cache_latest_view* _M_parent;
10448 iterator_t<_Vp> _M_current;
10451 _Iterator(cache_latest_view& __parent)
10453 _M_current(ranges::
begin(__parent._M_base))
10456 friend class cache_latest_view;
10459 using difference_type = range_difference_t<_Vp>;
10460 using value_type = range_value_t<_Vp>;
10461 using iterator_concept = input_iterator_tag;
10463 _Iterator(_Iterator&&) =
default;
10466 operator=(_Iterator&&) =
default;
10468 constexpr iterator_t<_Vp>
10472 constexpr const iterator_t<_Vp>&
10473 base() const & noexcept
10474 {
return _M_current; }
10476 constexpr range_reference_t<_Vp>&
10479 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10481 if (!_M_parent->_M_cache)
10482 _M_parent->_M_cache =
std::__addressof(__detail::__as_lvalue(*_M_current));
10483 return **_M_parent->_M_cache;
10487 if (!_M_parent->_M_cache)
10488 _M_parent->_M_cache._M_emplace_deref(_M_current);
10489 return *_M_parent->_M_cache;
10493 constexpr _Iterator&
10496 _M_parent->_M_cache._M_reset();
10505 friend constexpr range_rvalue_reference_t<_Vp>
10506 iter_move(
const _Iterator& __i)
10507 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10508 {
return ranges::iter_move(__i._M_current); }
10510 friend constexpr void
10511 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10512 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10513 requires indirectly_swappable<iterator_t<_Vp>>
10514 { ranges::iter_swap(__x._M_current, __y._M_current); }
10517 template<input_range _Vp>
10519 class cache_latest_view<_Vp>::_Sentinel
10521 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10524 _Sentinel(cache_latest_view& __parent)
10525 : _M_end(ranges::
end(__parent._M_base))
10528 friend class cache_latest_view;
10531 _Sentinel() =
default;
10533 constexpr sentinel_t<_Vp>
10537 friend constexpr bool
10538 operator==(
const _Iterator& __x,
const _Sentinel& __y)
10539 {
return __x._M_current == __y._M_end; }
10541 friend constexpr range_difference_t<_Vp>
10542 operator-(
const _Iterator& __x,
const _Sentinel& __y)
10543 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10544 {
return __x._M_current - __y._M_end; }
10546 friend constexpr range_difference_t<_Vp>
10547 operator-(
const _Sentinel& __x,
const _Iterator& __y)
10548 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10549 {
return __x._M_end - __y._M_current; }
10556 template<
typename _Tp>
10557 concept __can_cache_latest =
requires { cache_latest_view(
std::declval<_Tp>()); };
10560 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10562 template<viewable_range _Range>
10563 requires __detail::__can_cache_latest<_Range>
10565 operator() [[nodiscard]] (_Range&& __r)
const
10568 static constexpr bool _S_has_simple_call_op =
true;
10571 inline constexpr _CacheLatest cache_latest;
10576#if __cpp_lib_ranges_to_input
10579 template<input_range _Vp>
10581 class to_input_view :
public view_interface<to_input_view<_Vp>>
10583 _Vp _M_base = _Vp();
10585 template<
bool _Const>
10589 to_input_view()
requires default_initializable<_Vp> = default;
10592 to_input_view(_Vp __base)
10593 : _M_base(std::move(__base))
10597 base() const & requires copy_constructible<_Vp>
10598 {
return _M_base; }
10605 begin()
requires (!__detail::__simple_view<_Vp>)
10606 {
return _Iterator<false>(ranges::begin(_M_base)); }
10609 begin() const requires range<const _Vp>
10610 {
return _Iterator<true>(ranges::begin(_M_base)); }
10613 end()
requires (!__detail::__simple_view<_Vp>)
10614 {
return ranges::end(_M_base); }
10617 end() const requires range<const _Vp>
10618 {
return ranges::end(_M_base); }
10621 size()
requires sized_range<_Vp>
10622 {
return ranges::size(_M_base); }
10625 size() const requires sized_range<const _Vp>
10626 {
return ranges::size(_M_base); }
10629 template<
typename _Range>
10630 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10632 template<input_range _Vp>
10634 template<
bool _Const>
10635 class to_input_view<_Vp>::_Iterator
10637 using _Base = __maybe_const_t<_Const, _Vp>;
10639 iterator_t<_Base> _M_current = iterator_t<_Base>();
10642 _Iterator(iterator_t<_Base> __current)
10643 : _M_current(std::
move(__current))
10646 friend to_input_view;
10647 friend _Iterator<!_Const>;
10650 using difference_type = range_difference_t<_Base>;
10651 using value_type = range_value_t<_Base>;
10652 using iterator_concept = input_iterator_tag;
10654 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
10656 _Iterator(_Iterator&&) = default;
10657 _Iterator& operator=(_Iterator&&) = default;
10660 _Iterator(_Iterator<!_Const> __i)
10661 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10662 : _M_current(std::move(__i._M_current))
10665 constexpr iterator_t<_Base>
10669 constexpr const iterator_t<_Base>&
10670 base() const & noexcept
10671 {
return _M_current; }
10673 constexpr decltype(
auto)
10675 {
return *_M_current; }
10677 constexpr _Iterator&
10688 friend constexpr bool
10689 operator==(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10690 {
return __x._M_current == __y; }
10692 friend constexpr difference_type
10693 operator-(
const sentinel_t<_Base>& __y,
const _Iterator& __x)
10694 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10695 {
return __y - __x._M_current; }
10697 friend constexpr difference_type
10698 operator-(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10699 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10700 {
return __x._M_current - __y; }
10702 friend constexpr range_rvalue_reference_t<_Base>
10703 iter_move(
const _Iterator& __i)
10704 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10705 {
return ranges::iter_move(__i._M_current); }
10707 friend constexpr void
10708 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10709 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10710 requires indirectly_swappable<iterator_t<_Base>>
10711 { ranges::iter_swap(__x._M_current, __y._M_current); }
10718 template<
typename _Tp>
10722 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10724 template<viewable_range _Range>
10725 requires __detail::__can_to_input<_Range>
10727 operator() [[nodiscard]] (_Range&& __r)
const
10729 if constexpr (input_range<_Range>
10730 && !common_range<_Range>
10731 && !forward_range<_Range>)
10737 static constexpr bool _S_has_simple_call_op =
true;
10740 inline constexpr _ToInput to_input;
10745_GLIBCXX_END_NAMESPACE_VERSION
constexpr bool operator<=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>=(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator<(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr bool operator>(const duration< _Rep1, _Period1 > &__lhs, const duration< _Rep2, _Period2 > &__rhs)
constexpr complex< _Tp > operator*(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x times y.
constexpr complex< _Tp > operator-(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x minus y.
constexpr complex< _Tp > operator+(const complex< _Tp > &__x, const complex< _Tp > &__y)
Return new complex value x plus y.
basic_istream< char > istream
Base class for char input streams.
constexpr _Tp * to_address(_Tp *__ptr) noexcept
Obtain address referenced by a pointer to an object.
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.
auto declval() noexcept -> decltype(__declval< _Tp >(0))
constexpr _Tp * addressof(_Tp &__r) noexcept
Returns the actual address of the object or function referenced by r, even in the presence of an over...
constexpr std::remove_reference< _Tp >::type && move(_Tp &&__t) noexcept
Convert a value to an rvalue.
constexpr __invoke_result< _Callable, _Args... >::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_invocable< _Callable, _Args... >::value)
Invoke a callable object.
constexpr _Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
_Tp * end(valarray< _Tp > &__va) noexcept
Return an iterator pointing to one past the last element of the valarray.
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.
constexpr reverse_iterator< _Iterator > make_reverse_iterator(_Iterator __i)
Generator function for reverse_iterator.
constexpr void iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value)
Create a range of sequentially increasing values.
ISO C++ entities toplevel namespace is std.
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
integer_sequence< size_t, _Idx... > index_sequence
Alias template index_sequence.
constexpr auto empty(const _Container &__cont) noexcept(noexcept(__cont.empty())) -> decltype(__cont.empty())
Return whether a container is empty.
constexpr auto size(const _Container &__cont) noexcept(noexcept(__cont.size())) -> decltype(__cont.size())
Return the size of a container.
constexpr default_sentinel_t default_sentinel
A default sentinel value.
constexpr auto data(_Container &__cont) noexcept(noexcept(__cont.data())) -> decltype(__cont.data())
Return the data pointer of a container.
constexpr bitset< _Nb > operator|(const bitset< _Nb > &__x, const bitset< _Nb > &__y) noexcept
Global bitwise operations on bitsets.
constexpr _Iterator __base(_Iterator __it)
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.