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_fn(*__iters...)))
356 {
return _M_fn(*__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_fn(__iters[iter_difference_t<_Iters>(__n)]...)))
362 {
return _M_fn(__iters[iter_difference_t<_Iters>(__n)]...); }
365 [[no_unique_address]] _Fn _M_fn = _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)]...); }
452 template<
typename _Fn,
typename... _Iters>
456 using _Fd = remove_cv_t<_Fn>;
457 if constexpr (is_member_pointer_v<_Fd>)
458 return __func_handle::_InplaceMemPtr<_Fd>();
459 else if constexpr (is_function_v<remove_pointer_t<_Fd>>)
460 return __func_handle::_Inplace<_Fd>();
461 else if constexpr (__is_std_op_wrapper<_Fd>)
462 return __func_handle::_Inplace<_Fd>();
463 else if constexpr (
requires (
const _Iters&... __iters)
464 { _Fd::operator()(*__iters...); })
465 return __func_handle::_StaticCall<_Fd>();
467 return __func_handle::_ViaPointer<_Fn>();
471 template<
typename _Fn,
typename... _Iters>
472 using __func_handle_t =
decltype(__func_handle::__select<_Fn, _Iters...>());
476#if __cpp_lib_ranges >= 202207L
477 template<move_constructible _Tp>
479 template<copy_constructible _Tp>
481 requires is_object_v<_Tp>
485 single_view()
requires default_initializable<_Tp> = default;
488 single_view(const _Tp& __t)
489 noexcept(is_nothrow_copy_constructible_v<_Tp>)
490 requires copy_constructible<_Tp>
495 single_view(_Tp&& __t)
496 noexcept(is_nothrow_move_constructible_v<_Tp>)
497 : _M_value(std::
move(__t))
502 template<
typename... _Args>
503 requires constructible_from<_Tp, _Args...>
505 single_view(in_place_t, _Args&&... __args)
506 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
507 : _M_value{in_place, std::
forward<_Args>(__args)...}
515 begin() const noexcept
520 {
return data() + 1; }
524 {
return data() + 1; }
528 static constexpr bool
532 static constexpr size_t
538 {
return _M_value.operator->(); }
541 data() const noexcept
542 {
return _M_value.operator->(); }
545 [[no_unique_address]] __detail::__box<_Tp> _M_value;
548 template<
typename _Tp>
549 single_view(_Tp) -> single_view<_Tp>;
553 template<
typename _Wp>
554 constexpr auto __to_signed_like(_Wp __w)
noexcept
556 if constexpr (!integral<_Wp>)
557 return iter_difference_t<_Wp>();
558 else if constexpr (
sizeof(iter_difference_t<_Wp>) >
sizeof(_Wp))
559 return iter_difference_t<_Wp>(__w);
560 else if constexpr (
sizeof(ptrdiff_t) >
sizeof(_Wp))
561 return ptrdiff_t(__w);
562 else if constexpr (
sizeof(
long long) >
sizeof(_Wp))
563 return (
long long)(__w);
564#ifdef __SIZEOF_INT128__
565 else if constexpr (__SIZEOF_INT128__ >
sizeof(_Wp))
566 return __int128(__w);
569 return __max_diff_type(__w);
572 template<
typename _Wp>
575 template<
typename _It>
576 concept __decrementable = incrementable<_It>
579 { --__i } -> same_as<_It&>;
580 { __i-- } -> same_as<_It>;
583 template<
typename _It>
584 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
585 &&
requires( _It __i,
const _It __j,
const __iota_diff_t<_It> __n)
587 { __i += __n } -> same_as<_It&>;
588 { __i -= __n } -> same_as<_It&>;
592 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
595 template<
typename _Winc>
596 struct __iota_view_iter_cat
599 template<incrementable _Winc>
600 struct __iota_view_iter_cat<_Winc>
601 {
using iterator_category = input_iterator_tag; };
604 template<weakly_incrementable _Winc,
605 semiregular _Bound = unreachable_sentinel_t>
606 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
613 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
619 using namespace __detail;
620 if constexpr (__advanceable<_Winc>)
621 return random_access_iterator_tag{};
622 else if constexpr (__decrementable<_Winc>)
623 return bidirectional_iterator_tag{};
624 else if constexpr (incrementable<_Winc>)
625 return forward_iterator_tag{};
627 return input_iterator_tag{};
631 using iterator_concept =
decltype(_S_iter_concept());
633 using value_type = _Winc;
634 using difference_type = __detail::__iota_diff_t<_Winc>;
636 _Iterator()
requires default_initializable<_Winc> = default;
639 _Iterator(_Winc __value)
640 : _M_value(__value) { }
643 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
658 operator++(
int)
requires incrementable<_Winc>
666 operator--()
requires __detail::__decrementable<_Winc>
673 operator--(
int)
requires __detail::__decrementable<_Winc>
681 operator+=(difference_type __n)
requires __detail::__advanceable<_Winc>
683 using __detail::__is_integer_like;
684 using __detail::__is_signed_integer_like;
685 if constexpr (__is_integer_like<_Winc>
686 && !__is_signed_integer_like<_Winc>)
688 if (__n >= difference_type(0))
689 _M_value +=
static_cast<_Winc
>(__n);
691 _M_value -=
static_cast<_Winc
>(-__n);
699 operator-=(difference_type __n)
requires __detail::__advanceable<_Winc>
701 using __detail::__is_integer_like;
702 using __detail::__is_signed_integer_like;
703 if constexpr (__is_integer_like<_Winc>
704 && !__is_signed_integer_like<_Winc>)
706 if (__n >= difference_type(0))
707 _M_value -=
static_cast<_Winc
>(__n);
709 _M_value +=
static_cast<_Winc
>(-__n);
717 operator[](difference_type __n)
const
718 requires __detail::__advanceable<_Winc>
719 {
return _Winc(_M_value + __n); }
721 friend constexpr bool
722 operator==(
const _Iterator& __x,
const _Iterator& __y)
723 requires equality_comparable<_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 __x._M_value < __y._M_value; }
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 !(__y < __x); }
741 friend constexpr bool
742 operator>=(
const _Iterator& __x,
const _Iterator& __y)
743 requires totally_ordered<_Winc>
744 {
return !(__x < __y); }
746#ifdef __cpp_lib_three_way_comparison
747 friend constexpr auto
748 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
749 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
750 {
return __x._M_value <=> __y._M_value; }
753 friend constexpr _Iterator
754 operator+(_Iterator __i, difference_type __n)
755 requires __detail::__advanceable<_Winc>
761 friend constexpr _Iterator
762 operator+(difference_type __n, _Iterator __i)
763 requires __detail::__advanceable<_Winc>
764 {
return __i += __n; }
766 friend constexpr _Iterator
767 operator-(_Iterator __i, difference_type __n)
768 requires __detail::__advanceable<_Winc>
774 friend constexpr difference_type
775 operator-(
const _Iterator& __x,
const _Iterator& __y)
776 requires __detail::__advanceable<_Winc>
778 using __detail::__is_integer_like;
779 using __detail::__is_signed_integer_like;
780 using _Dt = difference_type;
781 if constexpr (__is_integer_like<_Winc>)
783 if constexpr (__is_signed_integer_like<_Winc>)
784 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
786 return (__y._M_value > __x._M_value)
787 ? _Dt(-_Dt(__y._M_value - __x._M_value))
788 : _Dt(__x._M_value - __y._M_value);
791 return __x._M_value - __y._M_value;
795 _Winc _M_value = _Winc();
805 _M_equal(
const _Iterator& __x)
const
806 {
return __x._M_value == _M_bound; }
809 _M_distance_from(
const _Iterator& __x)
const
810 {
return _M_bound - __x._M_value; }
812 _Bound _M_bound = _Bound();
815 _Sentinel() =
default;
818 _Sentinel(_Bound __bound)
819 : _M_bound(__bound) { }
821 friend constexpr bool
822 operator==(
const _Iterator& __x,
const _Sentinel& __y)
823 {
return __y._M_equal(__x); }
825 friend constexpr iter_difference_t<_Winc>
826 operator-(
const _Iterator& __x,
const _Sentinel& __y)
827 requires sized_sentinel_for<_Bound, _Winc>
828 {
return -__y._M_distance_from(__x); }
830 friend constexpr iter_difference_t<_Winc>
831 operator-(
const _Sentinel& __x,
const _Iterator& __y)
832 requires sized_sentinel_for<_Bound, _Winc>
833 {
return __x._M_distance_from(__y); }
838 _Winc _M_value = _Winc();
839 [[no_unique_address]] _Bound _M_bound = _Bound();
842 iota_view()
requires default_initializable<_Winc> = default;
845 iota_view(_Winc __value)
850 iota_view(type_identity_t<_Winc> __value,
851 type_identity_t<_Bound> __bound)
852 : _M_value(__value), _M_bound(__bound)
854 if constexpr (totally_ordered_with<_Winc, _Bound>)
855 __glibcxx_assert(
bool(__value <= __bound) );
859 iota_view(_Iterator __first, _Iterator __last)
860 requires same_as<_Winc, _Bound>
861 : iota_view(__first._M_value, __last._M_value)
865 iota_view(_Iterator __first, unreachable_sentinel_t __last)
866 requires same_as<_Bound, unreachable_sentinel_t>
867 : iota_view(__first._M_value, __last)
871 iota_view(_Iterator __first, _Sentinel __last)
872 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
873 : iota_view(__first._M_value, __last._M_bound)
877 begin()
const {
return _Iterator{_M_value}; }
882 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
883 return unreachable_sentinel;
885 return _Sentinel{_M_bound};
889 end() const requires same_as<_Winc, _Bound>
890 {
return _Iterator{_M_bound}; }
896 {
return _M_value == _M_bound; }
900 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
901 || (integral<_Winc> && integral<_Bound>)
902 || sized_sentinel_for<_Bound, _Winc>
904 using __detail::__is_integer_like;
905 using __detail::__to_unsigned_like;
906 if constexpr (integral<_Winc> && integral<_Bound>)
909 return _Up(_M_bound) - _Up(_M_value);
911 else if constexpr (__is_integer_like<_Winc>)
912 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
914 return __to_unsigned_like(_M_bound - _M_value);
918 template<
typename _Winc,
typename _Bound>
919 requires (!__detail::__is_integer_like<_Winc>
920 || !__detail::__is_integer_like<_Bound>
921 || (__detail::__is_signed_integer_like<_Winc>
922 == __detail::__is_signed_integer_like<_Bound>))
923 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
925 template<
typename _Winc,
typename _Bound>
926 inline constexpr bool
927 enable_borrowed_range<iota_view<_Winc, _Bound>> =
true;
931 template<
typename _Tp>
932 inline constexpr empty_view<_Tp>
empty{};
936 template<
typename _Tp>
937 concept __can_single_view
943 template<__detail::__can_single_view _Tp>
945 operator() [[nodiscard]] (_Tp&& __e)
const
950 inline constexpr _Single single{};
954 template<
typename... _Args>
960 template<__detail::__can_iota_view _Tp>
962 operator() [[nodiscard]] (_Tp&& __e)
const
965 template<
typename _Tp,
typename _Up>
966 requires __detail::__can_iota_view<_Tp, _Up>
968 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f)
const
972 inline constexpr _Iota
iota{};
974#ifdef __cpp_lib_ranges_indices
977 template<ranges::__detail::__is_
integer_like _Tp>
978 requires __detail::__can_iota_view<_Tp>
979 [[nodiscard]]
constexpr auto
980 operator() (_Tp __e)
const noexcept
981 {
return iota(_Tp{}, __e); }
984 inline constexpr _Indices indices{};
991 template<
typename _Val,
typename _CharT,
typename _Traits>
992 concept __stream_extractable
993 =
requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
996 template<movable _Val,
typename _CharT,
997 typename _Traits = char_traits<_CharT>>
998 requires default_initializable<_Val>
999 && __detail::__stream_extractable<_Val, _CharT, _Traits>
1000 class basic_istream_view
1001 :
public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
1005 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
1012 *_M_stream >> _M_object;
1013 return _Iterator{
this};
1016 constexpr default_sentinel_t
1017 end() const noexcept
1021 basic_istream<_CharT, _Traits>* _M_stream;
1022 _Val _M_object = _Val();
1027 using iterator_concept = input_iterator_tag;
1028 using difference_type = ptrdiff_t;
1029 using value_type = _Val;
1032 _Iterator(basic_istream_view* __parent) noexcept
1033 : _M_parent(__parent)
1036 _Iterator(
const _Iterator&) =
delete;
1037 _Iterator(_Iterator&&) =
default;
1038 _Iterator& operator=(
const _Iterator&) =
delete;
1039 _Iterator& operator=(_Iterator&&) =
default;
1044 *_M_parent->_M_stream >> _M_parent->_M_object;
1054 {
return _M_parent->_M_object; }
1057 operator==(
const _Iterator& __x, default_sentinel_t)
1058 {
return __x._M_at_end(); }
1061 basic_istream_view* _M_parent;
1065 {
return !*_M_parent->_M_stream; }
1071 template<
typename _Val>
1072 using istream_view = basic_istream_view<_Val, char>;
1074 template<
typename _Val>
1075 using wistream_view = basic_istream_view<_Val, wchar_t>;
1081 template<
typename _Tp,
typename _Up>
1082 concept __can_istream_view =
requires (_Up __e) {
1083 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
1087 template<
typename _Tp>
1090 template<
typename _CharT,
typename _Traits>
1092 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e)
const
1093 requires __detail::__can_istream_view<_Tp, remove_reference_t<
decltype(__e)>>
1094 {
return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
1097 template<
typename _Tp>
1098 inline constexpr _Istream<_Tp>
istream;
1106 template<
typename _Tp,
int _Disc>
1115 template<
bool _Present,
typename _Tp,
int _Disc = 0>
1116 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
1119 template<
bool _Const,
typename _Tp>
1120 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
1125using __detail::__maybe_const_t;
1127namespace views::__adaptor
1130 template<
typename _Adaptor,
typename... _Args>
1131 concept __adaptor_invocable
1136 template<
typename _Adaptor,
typename... _Args>
1137 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
1138 && (
sizeof...(_Args) == _Adaptor::_S_arity - 1)
1139 && (constructible_from<decay_t<_Args>, _Args> && ...);
1141 template<
typename _Adaptor,
typename... _Args>
1144 template<
typename _Lhs,
typename _Rhs>
1152 template<
typename _Derived>
1153 struct _RangeAdaptorClosure;
1155 template<
typename _Tp,
typename _Up>
1156 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
1157 void __is_range_adaptor_closure_fn
1158 (
const _Tp&,
const _RangeAdaptorClosure<_Up>&);
1160 template<
typename _Tp>
1161 concept __is_range_adaptor_closure
1162 =
requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
1164#pragma GCC diagnostic push
1165#pragma GCC diagnostic ignored "-Wdangling-reference"
1167 template<
typename _Self,
typename _Range>
1168 requires __is_range_adaptor_closure<_Self>
1169 && __adaptor_invocable<_Self, _Range>
1176 template<
typename _Lhs,
typename _Rhs>
1177 requires __is_range_adaptor_closure<_Lhs>
1178 && __is_range_adaptor_closure<_Rhs>
1185#pragma GCC diagnostic pop
1187 template<
typename _Derived>
1188 struct _RangeAdaptorClosure
1194 template<
typename _Self,
typename _Range>
1195 requires __is_range_adaptor_closure<_Self>
1196 && __adaptor_invocable<_Self, _Range>
1197 friend constexpr auto
1198 operator|(_Range&& __r, _Self&& __self);
1200 template<
typename _Lhs,
typename _Rhs>
1201 requires __is_range_adaptor_closure<_Lhs>
1202 && __is_range_adaptor_closure<_Rhs>
1203 friend constexpr auto
1218 template<
typename _Derived>
1219 struct _RangeAdaptor
1223 template<
typename... _Args>
1224 requires __adaptor_partial_app_viable<_Derived, _Args...>
1226 operator()(_Args&&... __args)
const
1235 template<
typename _Adaptor>
1236 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1240 template<
typename _Adaptor,
typename... _Args>
1241 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1242 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1246 template<
typename _Adaptor,
typename... _Args>
1247 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1249 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1250 [[no_unique_address]] _Binder _M_binder;
1254 template<
typename... _Ts>
1256 _Partial(
int, _Ts&&... __args)
1257 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1262#if __cpp_explicit_this_parameter
1263 template<
typename _Self,
typename _Range>
1264 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1266 operator()(
this _Self&& __self, _Range&& __r)
1268 return _Binder::_S_call(__like_t<_Self, _Partial>(__self)._M_binder,
1272 template<
typename _Range>
1273 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1275 operator()(_Range&& __r)
const &
1278 template<
typename _Range>
1279 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1281 operator()(_Range&& __r) &&
1284 template<
typename _Range>
1286 operator()(_Range&& __r)
const && =
delete;
1294 template<
typename _Adaptor,
typename... _Args>
1295 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1296 && (is_trivially_copy_constructible_v<_Args> && ...)
1297 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1299 using _Binder = _Bind_back_t<_Adaptor, _Args...>;
1300 [[no_unique_address]] _Binder _M_binder;
1302 template<
typename... _Ts>
1304 _Partial(
int, _Ts&&... __args)
1305 : _M_binder(0, _Adaptor(), std::
forward<_Ts>(__args)...)
1310 template<
typename _Range>
1311 requires __adaptor_invocable<_Adaptor, _Range,
const _Args&...>
1313 operator()(_Range&& __r)
const
1316 static constexpr bool _S_has_simple_call_op =
true;
1319 template<
typename _Lhs,
typename _Rhs,
typename _Range>
1320 concept __pipe_invocable
1325 template<
typename _Lhs,
typename _Rhs>
1326 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1328 [[no_unique_address]] _Lhs _M_lhs;
1329 [[no_unique_address]] _Rhs _M_rhs;
1331 template<
typename _Tp,
typename _Up>
1333 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1334 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1339#if __cpp_explicit_this_parameter
1340 template<
typename _Self,
typename _Range>
1341 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1343 operator()(
this _Self&& __self, _Range&& __r)
1345 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1346 (__like_t<_Self, _Pipe>(__self)._M_lhs
1350 template<
typename _Range>
1351 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1353 operator()(_Range&& __r)
const &
1356 template<
typename _Range>
1357 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1359 operator()(_Range&& __r) &&
1362 template<
typename _Range>
1364 operator()(_Range&& __r)
const && =
delete;
1372 template<
typename _Lhs,
typename _Rhs>
1373 requires __closure_has_simple_call_op<_Lhs>
1374 && __closure_has_simple_call_op<_Rhs>
1375 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1377 [[no_unique_address]] _Lhs _M_lhs;
1378 [[no_unique_address]] _Rhs _M_rhs;
1380 template<
typename _Tp,
typename _Up>
1382 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1383 : _M_lhs(std::
forward<_Tp>(__lhs)), _M_rhs(std::
forward<_Up>(__rhs))
1386 template<
typename _Range>
1387 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1389 operator()(_Range&& __r)
const
1392 static constexpr bool _S_has_simple_call_op =
true;
1396#if __cpp_lib_ranges >= 202202L
1398 template<
typename _Derived>
1399 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1400 class range_adaptor_closure
1401 :
public views::__adaptor::_RangeAdaptorClosure<_Derived>
1405 template<range _Range>
requires is_object_v<_Range>
1411 static void _S_fun(_Range&);
1412 static void _S_fun(_Range&&) =
delete;
1415 template<__detail::__different_from<ref_view> _Tp>
1416 requires convertible_to<_Tp, _Range&>
1417 &&
requires { _S_fun(declval<_Tp>()); }
1428 constexpr iterator_t<_Range>
1430 {
return ranges::begin(*_M_r); }
1432 constexpr sentinel_t<_Range>
1434 {
return ranges::end(*_M_r); }
1437 empty() const requires requires { ranges::empty(*_M_r); }
1438 {
return ranges::empty(*_M_r); }
1441 size() const requires sized_range<_Range>
1442 {
return ranges::size(*_M_r); }
1445 data() const requires contiguous_range<_Range>
1446 {
return ranges::data(*_M_r); }
1449 template<
typename _Range>
1450 ref_view(_Range&) -> ref_view<_Range>;
1452 template<
typename _Tp>
1453 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> =
true;
1455 template<range _Range>
1456 requires movable<_Range>
1457 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1461 _Range _M_r = _Range();
1464 owning_view()
requires default_initializable<_Range> = default;
1467 owning_view(_Range&& __t)
1468 noexcept(is_nothrow_move_constructible_v<_Range>)
1469 : _M_r(std::
move(__t))
1472 owning_view(owning_view&&) =
default;
1473 owning_view& operator=(owning_view&&) =
default;
1479 constexpr const _Range&
1480 base() const& noexcept
1487 constexpr const _Range&&
1488 base() const&& noexcept
1491 constexpr iterator_t<_Range>
1493 {
return ranges::begin(_M_r); }
1495 constexpr sentinel_t<_Range>
1497 {
return ranges::end(_M_r); }
1500 begin() const requires range<const _Range>
1501 {
return ranges::begin(_M_r); }
1504 end() const requires range<const _Range>
1505 {
return ranges::end(_M_r); }
1508 empty()
requires requires { ranges::empty(_M_r); }
1509 {
return ranges::empty(_M_r); }
1512 empty() const requires requires { ranges::empty(_M_r); }
1513 {
return ranges::empty(_M_r); }
1516 size()
requires sized_range<_Range>
1517 {
return ranges::size(_M_r); }
1520 size() const requires sized_range<const _Range>
1521 {
return ranges::size(_M_r); }
1524 data()
requires contiguous_range<_Range>
1525 {
return ranges::data(_M_r); }
1528 data() const requires contiguous_range<const _Range>
1529 {
return ranges::data(_M_r); }
1532 template<
typename _Tp>
1533 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1534 = enable_borrowed_range<_Tp>;
1540 template<
typename _Range>
1543 template<
typename _Range>
1547 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1549 template<
typename _Range>
1550 static constexpr bool
1553 if constexpr (view<decay_t<_Range>>)
1554 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1555 else if constexpr (__detail::__can_ref_view<_Range>)
1561 template<viewable_range _Range>
1562 requires view<decay_t<_Range>>
1563 || __detail::__can_ref_view<_Range>
1564 || __detail::__can_owning_view<_Range>
1566 operator() [[nodiscard]] (_Range&& __r)
const
1567 noexcept(_S_noexcept<_Range>())
1569 if constexpr (view<decay_t<_Range>>)
1571 else if constexpr (__detail::__can_ref_view<_Range>)
1577 static constexpr bool _S_has_simple_call_op =
true;
1580 inline constexpr _All all;
1582 template<viewable_range _Range>
1588 template<
typename _Tp>
1589 struct __non_propagating_cache
1597 template<
typename _Tp>
1598 requires is_object_v<_Tp>
1599 struct __non_propagating_cache<_Tp>
1600 :
protected _Optional_base<_Tp>
1602 __non_propagating_cache() =
default;
1605 __non_propagating_cache(
const __non_propagating_cache&)
noexcept
1609 __non_propagating_cache(__non_propagating_cache&& __other)
noexcept
1610 { __other._M_reset(); }
1612 constexpr __non_propagating_cache&
1613 operator=(
const __non_propagating_cache& __other)
noexcept
1620 constexpr __non_propagating_cache&
1621 operator=(__non_propagating_cache&& __other)
noexcept
1628 constexpr __non_propagating_cache&
1629 operator=(_Tp __val)
1632 this->_M_payload._M_construct(
std::move(__val));
1637 operator bool() const noexcept
1638 {
return this->_M_is_engaged(); }
1642 {
return this->_M_get(); }
1644 constexpr const _Tp&
1646 {
return this->_M_get(); }
1648 template<
typename _Iter>
1650 _M_emplace_deref(
const _Iter& __i)
1653 auto __f = [] (
auto& __x) {
return *__x; };
1654 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1655 return this->_M_get();
1658 using _Optional_base<_Tp>::_M_reset;
1661 template<range _Range>
1662 struct _CachedPosition
1665 _M_has_value()
const
1668 constexpr iterator_t<_Range>
1669 _M_get(
const _Range&)
const
1671 __glibcxx_assert(
false);
1672 __builtin_unreachable();
1676 _M_set(
const _Range&,
const iterator_t<_Range>&)
const
1680 template<forward_range _Range>
1681 struct _CachedPosition<_Range>
1682 :
protected __non_propagating_cache<iterator_t<_Range>>
1685 _M_has_value()
const
1686 {
return this->_M_is_engaged(); }
1688 constexpr iterator_t<_Range>
1689 _M_get(
const _Range&)
const
1691 __glibcxx_assert(_M_has_value());
1696 _M_set(
const _Range&,
const iterator_t<_Range>& __it)
1698 __glibcxx_assert(!_M_has_value());
1701 this->_M_payload._M_engaged =
true;
1705 template<random_access_range _Range>
1706 struct _CachedPosition<_Range>
1709 range_difference_t<_Range> _M_offset = -1;
1712 _CachedPosition() =
default;
1715 _CachedPosition(
const _CachedPosition&) =
default;
1718 _CachedPosition(_CachedPosition&& __other)
noexcept
1721 constexpr _CachedPosition&
1722 operator=(
const _CachedPosition&) =
default;
1724 constexpr _CachedPosition&
1725 operator=(_CachedPosition&& __other)
noexcept
1728 _M_offset = __other._M_offset;
1729 __other._M_offset = -1;
1734 _M_has_value()
const
1735 {
return _M_offset >= 0; }
1737 constexpr iterator_t<_Range>
1738 _M_get(_Range& __r)
const
1740 __glibcxx_assert(_M_has_value());
1741 return ranges::begin(__r) + _M_offset;
1745 _M_set(_Range& __r,
const iterator_t<_Range>& __it)
1747 __glibcxx_assert(!_M_has_value());
1748 _M_offset = __it - ranges::begin(__r);
1755 template<
typename _Base>
1756 struct __filter_view_iter_cat
1759 template<forward_range _Base>
1760 struct __filter_view_iter_cat<_Base>
1766 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
1767 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1768 return bidirectional_iterator_tag{};
1769 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1770 return forward_iterator_tag{};
1775 using iterator_category =
decltype(_S_iter_cat());
1779 template<input_range _Vp,
1780 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1781 requires view<_Vp> && is_object_v<_Pred>
1782 class filter_view :
public view_interface<filter_view<_Vp, _Pred>>
1787 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1790 static constexpr auto
1793 if constexpr (bidirectional_range<_Vp>)
1794 return bidirectional_iterator_tag{};
1795 else if constexpr (forward_range<_Vp>)
1796 return forward_iterator_tag{};
1798 return input_iterator_tag{};
1803 using _Vp_iter = iterator_t<_Vp>;
1805 _Vp_iter _M_current = _Vp_iter();
1806 filter_view* _M_parent =
nullptr;
1809 using iterator_concept =
decltype(_S_iter_concept());
1811 using value_type = range_value_t<_Vp>;
1812 using difference_type = range_difference_t<_Vp>;
1814 _Iterator()
requires default_initializable<_Vp_iter> = default;
1817 _Iterator(filter_view* __parent, _Vp_iter __current)
1818 : _M_current(std::move(__current)),
1822 constexpr const _Vp_iter&
1823 base() const & noexcept
1824 {
return _M_current; }
1830 constexpr range_reference_t<_Vp>
1832 {
return *_M_current; }
1836 requires __detail::__has_arrow<_Vp_iter>
1837 && copyable<_Vp_iter>
1838 {
return _M_current; }
1840 constexpr _Iterator&
1843 _M_current = ranges::find_if(
std::move(++_M_current),
1844 ranges::end(_M_parent->_M_base),
1854 operator++(
int)
requires forward_range<_Vp>
1861 constexpr _Iterator&
1862 operator--()
requires bidirectional_range<_Vp>
1871 operator--(
int)
requires bidirectional_range<_Vp>
1878 friend constexpr bool
1879 operator==(
const _Iterator& __x,
const _Iterator& __y)
1880 requires equality_comparable<_Vp_iter>
1881 {
return __x._M_current == __y._M_current; }
1883 friend constexpr range_rvalue_reference_t<_Vp>
1884 iter_move(
const _Iterator& __i)
1885 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
1886 {
return ranges::iter_move(__i._M_current); }
1888 friend constexpr void
1889 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
1890 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1891 requires indirectly_swappable<_Vp_iter>
1892 { ranges::iter_swap(__x._M_current, __y._M_current); }
1898 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1901 __equal(
const _Iterator& __i)
const
1902 {
return __i._M_current == _M_end; }
1905 _Sentinel() =
default;
1908 _Sentinel(filter_view* __parent)
1909 : _M_end(ranges::
end(__parent->_M_base))
1912 constexpr sentinel_t<_Vp>
1916 friend constexpr bool
1917 operator==(
const _Iterator& __x,
const _Sentinel& __y)
1918 {
return __y.__equal(__x); }
1921 _Vp _M_base = _Vp();
1922 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1923 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1926 filter_view()
requires (default_initializable<_Vp>
1927 && default_initializable<_Pred>)
1931 filter_view(_Vp __base, _Pred __pred)
1936 base() const& requires copy_constructible<_Vp>
1943 constexpr const _Pred&
1945 {
return *_M_pred; }
1950 if (_M_cached_begin._M_has_value())
1951 return {
this, _M_cached_begin._M_get(_M_base)};
1953 __glibcxx_assert(_M_pred.has_value());
1954 auto __it = ranges::find_if(ranges::begin(_M_base),
1955 ranges::end(_M_base),
1957 _M_cached_begin._M_set(_M_base, __it);
1964 if constexpr (common_range<_Vp>)
1965 return _Iterator{
this, ranges::end(_M_base)};
1967 return _Sentinel{
this};
1971 template<
typename _Range,
typename _Pred>
1972 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1978 template<
typename _Range,
typename _Pred>
1979 concept __can_filter_view
1983 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1985 template<viewable_range _Range,
typename _Pred>
1986 requires __detail::__can_filter_view<_Range, _Pred>
1988 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
1993 using _RangeAdaptor<_Filter>::operator();
1994 static constexpr int _S_arity = 2;
1995 static constexpr bool _S_has_simple_extra_args =
true;
1998 inline constexpr _Filter filter;
2001#if __cpp_lib_ranges >= 202207L
2002 template<input_range _Vp, move_constructible _Fp>
2004 template<input_range _Vp, copy_constructible _Fp>
2006 requires view<_Vp> && is_object_v<_Fp>
2007 && regular_invocable<_Fp&, range_reference_t<_Vp>>
2008 && std::__detail::__can_reference<invoke_result_t<_Fp&,
2009 range_reference_t<_Vp>>>
2010 class transform_view :
public view_interface<transform_view<_Vp, _Fp>>
2013 template<
bool _Const>
2014 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2016 template<
bool _Const>
2020 template<
bool _Const>
2021 requires forward_range<_Base<_Const>>
2022 struct __iter_cat<_Const>
2031 using _Base = transform_view::_Base<_Const>;
2032 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2033 range_reference_t<_Base>>;
2036 if constexpr (is_reference_v<_Res>)
2039 =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
2040 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
2041 return random_access_iterator_tag{};
2046 return input_iterator_tag{};
2049 using iterator_category =
decltype(_S_iter_cat());
2052 template<
bool _Const>
2055 template<
bool _Const>
2056 struct _Iterator : __iter_cat<_Const>
2059 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2060 using _Base = transform_view::_Base<_Const>;
2061 using _Base_iter = iterator_t<_Base>;
2062 using _Func_handle = __detail::__func_handle_t<
2063 __detail::__maybe_const_t<_Const, _Fp>,
2069 if constexpr (random_access_range<_Base>)
2070 return random_access_iterator_tag{};
2071 else if constexpr (bidirectional_range<_Base>)
2072 return bidirectional_iterator_tag{};
2073 else if constexpr (forward_range<_Base>)
2074 return forward_iterator_tag{};
2076 return input_iterator_tag{};
2079 _Base_iter _M_current = _Base_iter();
2080 [[no_unique_address]] _Func_handle _M_fun;
2083 using iterator_concept =
decltype(_S_iter_concept());
2086 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
2087 range_reference_t<_Base>>>;
2088 using difference_type = range_difference_t<_Base>;
2090 _Iterator()
requires default_initializable<_Base_iter> = default;
2093 _Iterator(_Func_handle __fun, _Base_iter __current)
2094 : _M_current(std::move(__current)), _M_fun(__fun)
2098 _Iterator(_Parent* __parent, _Base_iter __current)
2099 : _M_current(std::
move(__current)), _M_fun(*__parent->_M_fun)
2103 _Iterator(_Iterator<!_Const> __i)
2105 && convertible_to<iterator_t<_Vp>, _Base_iter>
2106 : _M_current(
std::move(__i._M_current)), _M_fun(__i._M_fun)
2109 constexpr const _Base_iter&
2110 base() const & noexcept
2111 {
return _M_current; }
2113 constexpr _Base_iter
2117 constexpr decltype(
auto)
2119 noexcept(
noexcept(_M_fun._M_call_deref(_M_current)))
2120 {
return _M_fun._M_call_deref(_M_current); }
2122 constexpr _Iterator&
2134 operator++(
int)
requires forward_range<_Base>
2141 constexpr _Iterator&
2142 operator--()
requires bidirectional_range<_Base>
2149 operator--(
int)
requires bidirectional_range<_Base>
2156 constexpr _Iterator&
2157 operator+=(difference_type __n)
requires random_access_range<_Base>
2163 constexpr _Iterator&
2164 operator-=(difference_type __n)
requires random_access_range<_Base>
2170 constexpr decltype(
auto)
2171 operator[](difference_type __n)
const
2172 requires random_access_range<_Base>
2173 {
return _M_fun._M_call_subscript(__n, _M_current); }
2175 friend constexpr bool
2176 operator==(
const _Iterator& __x,
const _Iterator& __y)
2177 requires equality_comparable<_Base_iter>
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 __x._M_current < __y._M_current; }
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 !(__y < __x); }
2195 friend constexpr bool
2196 operator>=(
const _Iterator& __x,
const _Iterator& __y)
2197 requires random_access_range<_Base>
2198 {
return !(__x < __y); }
2200#ifdef __cpp_lib_three_way_comparison
2201 friend constexpr auto
2202 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
2203 requires random_access_range<_Base>
2204 && three_way_comparable<_Base_iter>
2205 {
return __x._M_current <=> __y._M_current; }
2208 friend constexpr _Iterator
2209 operator+(_Iterator __i, difference_type __n)
2210 requires random_access_range<_Base>
2211 {
return {__i._M_fun, __i._M_current + __n}; }
2213 friend constexpr _Iterator
2214 operator+(difference_type __n, _Iterator __i)
2215 requires random_access_range<_Base>
2216 {
return {__i._M_fun, __i._M_current + __n}; }
2218 friend constexpr _Iterator
2219 operator-(_Iterator __i, difference_type __n)
2220 requires random_access_range<_Base>
2221 {
return {__i._M_fun, __i._M_current - __n}; }
2225 friend constexpr difference_type
2226 operator-(
const _Iterator& __x,
const _Iterator& __y)
2227 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2228 {
return __x._M_current - __y._M_current; }
2230 friend constexpr decltype(
auto)
2231 iter_move(
const _Iterator& __i)
noexcept(
noexcept(*__i))
2233 if constexpr (is_lvalue_reference_v<
decltype(*__i)>)
2239 friend _Iterator<!_Const>;
2240 template<
bool>
friend struct _Sentinel;
2243 template<
bool _Const>
2247 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2248 using _Base = transform_view::_Base<_Const>;
2250 template<
bool _Const2>
2252 __distance_from(
const _Iterator<_Const2>& __i)
const
2253 {
return _M_end - __i._M_current; }
2255 template<
bool _Const2>
2257 __equal(
const _Iterator<_Const2>& __i)
const
2258 {
return __i._M_current == _M_end; }
2260 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2263 _Sentinel() =
default;
2266 _Sentinel(sentinel_t<_Base> __end)
2271 _Sentinel(_Sentinel<!_Const> __i)
2273 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2277 constexpr sentinel_t<_Base>
2281 template<
bool _Const2>
2282 requires sentinel_for<sentinel_t<_Base>,
2283 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2284 friend constexpr bool
2285 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2286 {
return __y.__equal(__x); }
2288 template<
bool _Const2,
2289 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2290 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2291 friend constexpr range_difference_t<_Base2>
2292 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
2293 {
return -__y.__distance_from(__x); }
2295 template<
bool _Const2,
2296 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2297 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2298 friend constexpr range_difference_t<_Base2>
2299 operator-(
const _Sentinel& __y,
const _Iterator<_Const2>& __x)
2300 {
return __y.__distance_from(__x); }
2302 friend _Sentinel<!_Const>;
2305 _Vp _M_base = _Vp();
2306 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2309 transform_view()
requires (default_initializable<_Vp>
2310 && default_initializable<_Fp>)
2314 transform_view(_Vp __base, _Fp __fun)
2319 base() const& requires copy_constructible<_Vp>
2320 {
return _M_base ; }
2326 constexpr _Iterator<false>
2328 {
return _Iterator<false>{
this, ranges::begin(_M_base)}; }
2330 constexpr _Iterator<true>
2332 requires range<const _Vp>
2333 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2334 {
return _Iterator<true>{
this, ranges::begin(_M_base)}; }
2336 constexpr _Sentinel<false>
2338 {
return _Sentinel<false>{ranges::end(_M_base)}; }
2340 constexpr _Iterator<false>
2341 end()
requires common_range<_Vp>
2342 {
return _Iterator<false>{
this, ranges::end(_M_base)}; }
2344 constexpr _Sentinel<true>
2346 requires range<const _Vp>
2347 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2348 {
return _Sentinel<true>{ranges::end(_M_base)}; }
2350 constexpr _Iterator<true>
2352 requires common_range<const _Vp>
2353 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2354 {
return _Iterator<true>{
this, ranges::end(_M_base)}; }
2357 size()
requires sized_range<_Vp>
2358 {
return ranges::size(_M_base); }
2361 size() const requires sized_range<const _Vp>
2362 {
return ranges::size(_M_base); }
2365 template<
typename _Range,
typename _Fp>
2366 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2372 template<
typename _Range,
typename _Fp>
2373 concept __can_transform_view
2377 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2379 template<viewable_range _Range,
typename _Fp>
2380 requires __detail::__can_transform_view<_Range, _Fp>
2382 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
2387 using _RangeAdaptor<_Transform>::operator();
2388 static constexpr int _S_arity = 2;
2389 static constexpr bool _S_has_simple_extra_args =
true;
2392 inline constexpr _Transform transform;
2399 template<
bool _Const>
2400 using _CI = counted_iterator<
2401 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2403 template<
bool _Const>
2407 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2408 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2411 _Sentinel() =
default;
2414 _Sentinel(sentinel_t<_Base> __end)
2419 _Sentinel(_Sentinel<!_Const> __s)
2420 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2424 constexpr sentinel_t<_Base>
2428 friend constexpr bool
2429 operator==(
const _CI<_Const>& __y,
const _Sentinel& __x)
2430 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2432 template<
bool _OtherConst = !_Const,
2433 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2434 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2435 friend constexpr bool
2436 operator==(
const _CI<_OtherConst>& __y,
const _Sentinel& __x)
2437 {
return __y.count() == 0 || __y.base() == __x._M_end; }
2439 friend _Sentinel<!_Const>;
2442 _Vp _M_base = _Vp();
2443 range_difference_t<_Vp> _M_count = 0;
2446 take_view()
requires default_initializable<_Vp> = default;
2449 take_view(_Vp __base, range_difference_t<_Vp> __count)
2450 : _M_base(std::move(__base)), _M_count(std::move(__count))
2454 base() const& requires copy_constructible<_Vp>
2462 begin()
requires (!__detail::__simple_view<_Vp>)
2464 if constexpr (sized_range<_Vp>)
2466 if constexpr (random_access_range<_Vp>)
2467 return ranges::begin(_M_base);
2471 return counted_iterator(ranges::begin(_M_base), __sz);
2475 return counted_iterator(ranges::begin(_M_base), _M_count);
2479 begin() const requires range<const _Vp>
2481 if constexpr (sized_range<const _Vp>)
2483 if constexpr (random_access_range<const _Vp>)
2484 return ranges::begin(_M_base);
2488 return counted_iterator(ranges::begin(_M_base), __sz);
2492 return counted_iterator(ranges::begin(_M_base), _M_count);
2496 end()
requires (!__detail::__simple_view<_Vp>)
2498 if constexpr (sized_range<_Vp>)
2500 if constexpr (random_access_range<_Vp>)
2501 return ranges::begin(_M_base) +
size();
2506 return _Sentinel<false>{ranges::end(_M_base)};
2510 end() const requires range<const _Vp>
2512 if constexpr (sized_range<const _Vp>)
2514 if constexpr (random_access_range<const _Vp>)
2515 return ranges::begin(_M_base) +
size();
2520 return _Sentinel<true>{ranges::end(_M_base)};
2524 size()
requires sized_range<_Vp>
2526 auto __n = ranges::size(_M_base);
2527 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2531 size() const requires sized_range<const _Vp>
2533 auto __n = ranges::size(_M_base);
2534 return std::min(__n,
static_cast<decltype(__n)
>(_M_count));
2541 template<
typename _Range>
2542 take_view(_Range&&, range_difference_t<_Range>)
2543 -> take_view<views::all_t<_Range>>;
2545 template<
typename _Tp>
2546 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2547 = enable_borrowed_range<_Tp>;
2553 template<
typename _Range>
2554 inline constexpr bool __is_empty_view =
false;
2556 template<
typename _Tp>
2557 inline constexpr bool __is_empty_view<empty_view<_Tp>> =
true;
2559 template<
typename _Range>
2560 inline constexpr bool __is_basic_string_view =
false;
2562 template<
typename _CharT,
typename _Traits>
2563 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2566 using ranges::__detail::__is_subrange;
2568 template<
typename _Range>
2569 inline constexpr bool __is_iota_view =
false;
2571 template<
typename _Winc,
typename _Bound>
2572 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> =
true;
2574 template<
typename _Range>
2575 inline constexpr bool __is_repeat_view =
false;
2577 template<
typename _Range>
2579 __take_of_repeat_view(_Range&&, range_difference_t<_Range>);
2581 template<
typename _Range,
typename _Dp>
2582 concept __can_take_view
2586 struct _Take : __adaptor::_RangeAdaptor<_Take>
2588 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2589 requires __detail::__can_take_view<_Range, _Dp>
2591 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2593 using _Tp = remove_cvref_t<_Range>;
2594 if constexpr (__detail::__is_empty_view<_Tp>)
2596#ifdef __cpp_lib_optional_range_support
2597 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2600 else if constexpr (random_access_range<_Tp>
2602 && (std::__detail::__is_span<_Tp>
2603 || __detail::__is_basic_string_view<_Tp>
2604 || __detail::__is_subrange<_Tp>
2605 || __detail::__is_iota_view<_Tp>))
2608 auto __begin = ranges::begin(__r);
2609 auto __end = __begin + __n;
2610 if constexpr (std::__detail::__is_span<_Tp>)
2611 return span<typename _Tp::element_type>(__begin, __end);
2612 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2613 return _Tp(__begin, __end);
2614 else if constexpr (__detail::__is_subrange<_Tp>)
2615 return subrange<iterator_t<_Tp>>(__begin, __end);
2617 return iota_view(*__begin, *__end);
2619 else if constexpr (__detail::__is_repeat_view<_Tp>)
2625 using _RangeAdaptor<_Take>::operator();
2626 static constexpr int _S_arity = 2;
2630 template<
typename _Tp>
2631 static constexpr bool _S_has_simple_extra_args
2632 = ranges::__detail::__is_integer_like<_Tp>;
2635 inline constexpr _Take take;
2638 template<view _Vp,
typename _Pred>
2639 requires input_range<_Vp> && is_object_v<_Pred>
2640 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2641 class take_while_view :
public view_interface<take_while_view<_Vp, _Pred>>
2643 template<
bool _Const>
2647 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2649 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2650 const _Pred* _M_pred =
nullptr;
2653 _Sentinel() =
default;
2656 _Sentinel(sentinel_t<_Base> __end,
const _Pred* __pred)
2657 : _M_end(__end), _M_pred(__pred)
2661 _Sentinel(_Sentinel<!_Const> __s)
2662 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2663 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2666 constexpr sentinel_t<_Base>
2667 base()
const {
return _M_end; }
2669 friend constexpr bool
2670 operator==(
const iterator_t<_Base>& __x,
const _Sentinel& __y)
2671 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2673 template<
bool _OtherConst = !_Const,
2674 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2675 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2676 friend constexpr bool
2677 operator==(
const iterator_t<_Base2>& __x,
const _Sentinel& __y)
2678 {
return __y._M_end == __x || !
std::__invoke(*__y._M_pred, *__x); }
2680 friend _Sentinel<!_Const>;
2683 _Vp _M_base = _Vp();
2684 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2687 take_while_view()
requires (default_initializable<_Vp>
2688 && default_initializable<_Pred>)
2692 take_while_view(_Vp __base, _Pred __pred)
2697 base() const& requires copy_constructible<_Vp>
2704 constexpr const _Pred&
2706 {
return *_M_pred; }
2709 begin()
requires (!__detail::__simple_view<_Vp>)
2710 {
return ranges::begin(_M_base); }
2713 begin() const requires range<const _Vp>
2714 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2715 {
return ranges::begin(_M_base); }
2718 end()
requires (!__detail::__simple_view<_Vp>)
2719 {
return _Sentinel<false>(ranges::end(_M_base),
2723 end() const requires range<const _Vp>
2724 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2725 {
return _Sentinel<true>(ranges::end(_M_base),
2729 template<
typename _Range,
typename _Pred>
2730 take_while_view(_Range&&, _Pred)
2731 -> take_while_view<views::all_t<_Range>, _Pred>;
2737 template<
typename _Range,
typename _Pred>
2738 concept __can_take_while_view
2742 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2744 template<viewable_range _Range,
typename _Pred>
2745 requires __detail::__can_take_while_view<_Range, _Pred>
2747 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
2752 using _RangeAdaptor<_TakeWhile>::operator();
2753 static constexpr int _S_arity = 2;
2754 static constexpr bool _S_has_simple_extra_args =
true;
2757 inline constexpr _TakeWhile take_while;
2764 _Vp _M_base = _Vp();
2765 range_difference_t<_Vp> _M_count = 0;
2769 static constexpr bool _S_needs_cached_begin
2770 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2771 [[no_unique_address]]
2772 __detail::__maybe_present_t<_S_needs_cached_begin,
2773 __detail::_CachedPosition<_Vp>>
2777 drop_view()
requires default_initializable<_Vp> = default;
2780 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2781 : _M_base(std::move(__base)), _M_count(__count)
2782 { __glibcxx_assert(__count >= 0); }
2785 base() const& requires copy_constructible<_Vp>
2795 requires (!(__detail::__simple_view<_Vp>
2796 && random_access_range<const _Vp>
2797 && sized_range<const _Vp>))
2799 if constexpr (_S_needs_cached_begin)
2800 if (_M_cached_begin._M_has_value())
2801 return _M_cached_begin._M_get(_M_base);
2803 auto __it = ranges::next(ranges::begin(_M_base),
2804 _M_count, ranges::end(_M_base));
2805 if constexpr (_S_needs_cached_begin)
2806 _M_cached_begin._M_set(_M_base, __it);
2814 requires random_access_range<const _Vp> && sized_range<const _Vp>
2816 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2821 end()
requires (!__detail::__simple_view<_Vp>)
2822 {
return ranges::end(_M_base); }
2825 end() const requires range<const _Vp>
2826 {
return ranges::end(_M_base); }
2829 size()
requires sized_range<_Vp>
2831 const auto __s = ranges::size(_M_base);
2832 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2833 return __s < __c ? 0 : __s - __c;
2837 size() const requires sized_range<const _Vp>
2839 const auto __s = ranges::size(_M_base);
2840 const auto __c =
static_cast<decltype(__s)
>(_M_count);
2841 return __s < __c ? 0 : __s - __c;
2845 template<
typename _Range>
2846 drop_view(_Range&&, range_difference_t<_Range>)
2847 -> drop_view<views::all_t<_Range>>;
2849 template<
typename _Tp>
2850 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2851 = enable_borrowed_range<_Tp>;
2857 template<
typename _Range>
2859 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
2861 template<
typename _Range,
typename _Dp>
2862 concept __can_drop_view
2866 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2868 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
2869 requires __detail::__can_drop_view<_Range, _Dp>
2871 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
2873 using _Tp = remove_cvref_t<_Range>;
2874 if constexpr (__detail::__is_empty_view<_Tp>)
2876#ifdef __cpp_lib_optional_range_support
2877 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
2880 else if constexpr (random_access_range<_Tp>
2882 && (std::__detail::__is_span<_Tp>
2883 || __detail::__is_basic_string_view<_Tp>
2884 || __detail::__is_iota_view<_Tp>
2885 || __detail::__is_subrange<_Tp>))
2888 auto __begin = ranges::begin(__r) + __n;
2889 auto __end = ranges::end(__r);
2890 if constexpr (std::__detail::__is_span<_Tp>)
2891 return span<typename _Tp::element_type>(__begin, __end);
2892 else if constexpr (__detail::__is_subrange<_Tp>)
2894 if constexpr (_Tp::_S_store_size)
2896 using ranges::__detail::__to_unsigned_like;
2897 auto __m = ranges::distance(__r) - __n;
2898 return _Tp(__begin, __end, __to_unsigned_like(__m));
2901 return _Tp(__begin, __end);
2904 return _Tp(__begin, __end);
2906 else if constexpr (__detail::__is_repeat_view<_Tp>)
2912 using _RangeAdaptor<_Drop>::operator();
2913 static constexpr int _S_arity = 2;
2914 template<
typename _Tp>
2915 static constexpr bool _S_has_simple_extra_args
2916 = _Take::_S_has_simple_extra_args<_Tp>;
2919 inline constexpr _Drop drop;
2922 template<view _Vp,
typename _Pred>
2923 requires input_range<_Vp> && is_object_v<_Pred>
2924 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2925 class drop_while_view :
public view_interface<drop_while_view<_Vp, _Pred>>
2928 _Vp _M_base = _Vp();
2929 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2930 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2933 drop_while_view()
requires (default_initializable<_Vp>
2934 && default_initializable<_Pred>)
2938 drop_while_view(_Vp __base, _Pred __pred)
2943 base() const& requires copy_constructible<_Vp>
2950 constexpr const _Pred&
2952 {
return *_M_pred; }
2957 if (_M_cached_begin._M_has_value())
2958 return _M_cached_begin._M_get(_M_base);
2960 __glibcxx_assert(_M_pred.has_value());
2961 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2962 ranges::end(_M_base),
2964 _M_cached_begin._M_set(_M_base, __it);
2970 {
return ranges::end(_M_base); }
2973 template<
typename _Range,
typename _Pred>
2974 drop_while_view(_Range&&, _Pred)
2975 -> drop_while_view<views::all_t<_Range>, _Pred>;
2977 template<
typename _Tp,
typename _Pred>
2978 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2979 = enable_borrowed_range<_Tp>;
2985 template<
typename _Range,
typename _Pred>
2986 concept __can_drop_while_view
2990 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2992 template<viewable_range _Range,
typename _Pred>
2993 requires __detail::__can_drop_while_view<_Range, _Pred>
2995 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p)
const
3001 using _RangeAdaptor<_DropWhile>::operator();
3002 static constexpr int _S_arity = 2;
3003 static constexpr bool _S_has_simple_extra_args =
true;
3006 inline constexpr _DropWhile drop_while;
3011 template<
typename _Tp>
3013 __as_lvalue(_Tp&& __t)
3014 {
return static_cast<_Tp&
>(__t); }
3017 template<input_range _Vp>
3018 requires view<_Vp> && input_range<range_reference_t<_Vp>>
3022 using _InnerRange = range_reference_t<_Vp>;
3024 template<
bool _Const>
3025 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3027 template<
bool _Const>
3028 using _Outer_iter = iterator_t<_Base<_Const>>;
3030 template<
bool _Const>
3031 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
3033 template<
bool _Const>
3034 static constexpr bool _S_ref_is_glvalue
3035 = is_reference_v<range_reference_t<_Base<_Const>>>;
3037 template<
bool _Const>
3041 template<
bool _Const>
3042 requires _S_ref_is_glvalue<_Const>
3043 && forward_range<_Base<_Const>>
3044 && forward_range<range_reference_t<_Base<_Const>>>
3045 struct __iter_cat<_Const>
3048 static constexpr auto
3051 using _Outer_iter = join_view::_Outer_iter<_Const>;
3052 using _Inner_iter = join_view::_Inner_iter<_Const>;
3053 using _OuterCat =
typename iterator_traits<_Outer_iter>::iterator_category;
3054 using _InnerCat =
typename iterator_traits<_Inner_iter>::iterator_category;
3055 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
3056 && derived_from<_InnerCat, bidirectional_iterator_tag>
3057 && common_range<range_reference_t<_Base<_Const>>>)
3058 return bidirectional_iterator_tag{};
3059 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
3060 && derived_from<_InnerCat, forward_iterator_tag>)
3061 return forward_iterator_tag{};
3063 return input_iterator_tag{};
3066 using iterator_category =
decltype(_S_iter_cat());
3069 template<
bool _Const>
3072 template<
bool _Const>
3073 struct _Iterator : __iter_cat<_Const>
3076 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3077 using _Base = join_view::_Base<_Const>;
3081 static constexpr bool _S_ref_is_glvalue
3082 = join_view::_S_ref_is_glvalue<_Const>;
3087 auto __update_inner = [
this] (
const iterator_t<_Base>& __x) ->
auto&& {
3088 if constexpr (_S_ref_is_glvalue)
3091 return _M_parent->_M_inner._M_emplace_deref(__x);
3094 _Outer_iter& __outer = _M_get_outer();
3095 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
3097 auto&& __inner = __update_inner(__outer);
3098 _M_inner = ranges::begin(__inner);
3099 if (_M_inner != ranges::end(__inner))
3103 if constexpr (_S_ref_is_glvalue)
3105 if constexpr (forward_iterator<_Inner_iter>)
3106 _M_inner = _Inner_iter();
3112 static constexpr auto
3115 if constexpr (_S_ref_is_glvalue
3116 && bidirectional_range<_Base>
3117 && bidirectional_range<range_reference_t<_Base>>
3118 && common_range<range_reference_t<_Base>>)
3119 return bidirectional_iterator_tag{};
3120 else if constexpr (_S_ref_is_glvalue
3121 && forward_range<_Base>
3122 && forward_range<range_reference_t<_Base>>)
3123 return forward_iterator_tag{};
3125 return input_iterator_tag{};
3128 using _Outer_iter = join_view::_Outer_iter<_Const>;
3129 using _Inner_iter = join_view::_Inner_iter<_Const>;
3131 constexpr _Outer_iter&
3134 if constexpr (forward_range<_Base>)
3137 return *_M_parent->_M_outer;
3140 constexpr const _Outer_iter&
3141 _M_get_outer()
const
3143 if constexpr (forward_range<_Base>)
3146 return *_M_parent->_M_outer;
3149 constexpr _Inner_iter&
3150 _M_get_inner() noexcept
3152 if constexpr (forward_iterator<_Inner_iter>)
3158 constexpr const _Inner_iter&
3159 _M_get_inner() const noexcept
3161 if constexpr (forward_iterator<_Inner_iter>)
3168 _Iterator(_Parent* __parent, _Outer_iter __outer)
requires forward_range<_Base>
3169 : _M_outer(
std::move(__outer)), _M_parent(__parent)
3173 _Iterator(_Parent* __parent)
requires (!forward_range<_Base>)
3174 : _M_parent(__parent)
3177 [[no_unique_address]]
3178 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer
3179 =
decltype(_M_outer)();
3180 __conditional_t<forward_iterator<_Inner_iter>,
3181 _Inner_iter, optional<_Inner_iter>> _M_inner
3182 =
decltype(_M_inner)();
3183 _Parent* _M_parent =
nullptr;
3186 using iterator_concept =
decltype(_S_iter_concept());
3188 using value_type = range_value_t<range_reference_t<_Base>>;
3189 using difference_type
3190 = common_type_t<range_difference_t<_Base>,
3191 range_difference_t<range_reference_t<_Base>>>;
3193 _Iterator() =
default;
3196 _Iterator(_Iterator<!_Const> __i)
3198 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3199 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3201 _M_parent(__i._M_parent)
3204 constexpr decltype(
auto)
3206 {
return *_M_get_inner(); }
3210 constexpr _Inner_iter
3212 requires __detail::__has_arrow<_Inner_iter>
3213 && copyable<_Inner_iter>
3214 {
return _M_get_inner(); }
3216 constexpr _Iterator&
3219 auto&& __inner_range = [
this] () ->
auto&& {
3220 if constexpr (_S_ref_is_glvalue)
3221 return *_M_get_outer();
3223 return *_M_parent->_M_inner;
3225 if (++_M_get_inner() == ranges::end(__inner_range))
3239 requires _S_ref_is_glvalue && forward_range<_Base>
3240 && forward_range<range_reference_t<_Base>>
3247 constexpr _Iterator&
3249 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3250 && bidirectional_range<range_reference_t<_Base>>
3251 && common_range<range_reference_t<_Base>>
3253 if (_M_outer == ranges::end(_M_parent->_M_base))
3254 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3255 while (_M_get_inner() == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3256 _M_get_inner() = ranges::end(__detail::__as_lvalue(*--_M_outer));
3263 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3264 && bidirectional_range<range_reference_t<_Base>>
3265 && common_range<range_reference_t<_Base>>
3272 friend constexpr bool
3273 operator==(
const _Iterator& __x,
const _Iterator& __y)
3274 requires _S_ref_is_glvalue
3275 && forward_range<_Base>
3276 && equality_comparable<_Inner_iter>
3278 return (__x._M_outer == __y._M_outer
3279 && __x._M_inner == __y._M_inner);
3282 friend constexpr decltype(
auto)
3283 iter_move(
const _Iterator& __i)
3284 noexcept(
noexcept(ranges::iter_move(__i._M_get_inner())))
3285 {
return ranges::iter_move(__i._M_get_inner()); }
3287 friend constexpr void
3288 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
3289 noexcept(
noexcept(ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner())))
3290 requires indirectly_swappable<_Inner_iter>
3291 {
return ranges::iter_swap(__x._M_get_inner(), __y._M_get_inner()); }
3293 friend _Iterator<!_Const>;
3294 template<
bool>
friend struct _Sentinel;
3297 template<
bool _Const>
3301 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3302 using _Base = join_view::_Base<_Const>;
3304 template<
bool _Const2>
3306 __equal(
const _Iterator<_Const2>& __i)
const
3307 {
return __i._M_get_outer() == _M_end; }
3309 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3312 _Sentinel() =
default;
3315 _Sentinel(_Parent* __parent)
3316 : _M_end(ranges::
end(__parent->_M_base))
3320 _Sentinel(_Sentinel<!_Const> __s)
3321 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3325 template<
bool _Const2>
3326 requires sentinel_for<sentinel_t<_Base>,
3327 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3328 friend constexpr bool
3329 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
3330 {
return __y.__equal(__x); }
3332 friend _Sentinel<!_Const>;
3335 _Vp _M_base = _Vp();
3336 [[no_unique_address]]
3337 __detail::__maybe_present_t<!forward_range<_Vp>,
3338 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3339 [[no_unique_address]]
3340 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3343 join_view()
requires default_initializable<_Vp> = default;
3346 join_view(_Vp __base)
3347 : _M_base(std::move(__base))
3351 base() const& requires copy_constructible<_Vp>
3361 if constexpr (forward_range<_Vp>)
3363 constexpr bool __use_const
3364 = (__detail::__simple_view<_Vp>
3365 && is_reference_v<range_reference_t<_Vp>>);
3366 return _Iterator<__use_const>{
this, ranges::begin(_M_base)};
3370 _M_outer = ranges::begin(_M_base);
3371 return _Iterator<false>{
this};
3377 requires forward_range<const _Vp>
3378 && is_reference_v<range_reference_t<const _Vp>>
3379 && input_range<range_reference_t<const _Vp>>
3381 return _Iterator<true>{
this, ranges::begin(_M_base)};
3387 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3388 && forward_range<_InnerRange>
3389 && common_range<_Vp> && common_range<_InnerRange>)
3390 return _Iterator<__detail::__simple_view<_Vp>>{
this,
3391 ranges::end(_M_base)};
3393 return _Sentinel<__detail::__simple_view<_Vp>>{
this};
3398 requires forward_range<const _Vp>
3399 && is_reference_v<range_reference_t<const _Vp>>
3400 && input_range<range_reference_t<const _Vp>>
3402 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3403 && forward_range<range_reference_t<const _Vp>>
3404 && common_range<const _Vp>
3405 && common_range<range_reference_t<const _Vp>>)
3406 return _Iterator<true>{
this, ranges::end(_M_base)};
3408 return _Sentinel<true>{
this};
3412 template<
typename _Range>
3413 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3419 template<
typename _Range>
3420 concept __can_join_view
3424 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3426 template<viewable_range _Range>
3427 requires __detail::__can_join_view<_Range>
3429 operator() [[nodiscard]] (_Range&& __r)
const
3436 static constexpr bool _S_has_simple_call_op =
true;
3439 inline constexpr _Join join;
3445 struct __require_constant;
3447 template<
typename _Range>
3448 concept __tiny_range = sized_range<_Range>
3450 {
typename __require_constant<remove_reference_t<_Range>::size()>; }
3451 && (remove_reference_t<_Range>::size() <= 1);
3453 template<
typename _Base>
3454 struct __lazy_split_view_outer_iter_cat
3457 template<forward_range _Base>
3458 struct __lazy_split_view_outer_iter_cat<_Base>
3459 {
using iterator_category = input_iterator_tag; };
3461 template<
typename _Base>
3462 struct __lazy_split_view_inner_iter_cat
3465 template<forward_range _Base>
3466 struct __lazy_split_view_inner_iter_cat<_Base>
3469 static constexpr auto
3472 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
3473 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3474 return forward_iterator_tag{};
3479 using iterator_category =
decltype(_S_iter_cat());
3483 template<input_range _Vp, forward_range _Pattern>
3484 requires view<_Vp> && view<_Pattern>
3485 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3487 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3488 class lazy_split_view : public
view_interface<lazy_split_view<_Vp, _Pattern>>
3491 template<
bool _Const>
3492 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3494 template<
bool _Const>
3497 template<
bool _Const>
3499 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3502 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3503 using _Base = lazy_split_view::_Base<_Const>;
3507 {
return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3514 __current() noexcept
3516 if constexpr (forward_range<_Vp>)
3519 return *_M_parent->_M_current;
3523 __current() const noexcept
3525 if constexpr (forward_range<_Vp>)
3528 return *_M_parent->_M_current;
3531 _Parent* _M_parent =
nullptr;
3533 [[no_unique_address]]
3534 __detail::__maybe_present_t<forward_range<_Vp>,
3535 iterator_t<_Base>> _M_current
3536 =
decltype(_M_current)();
3537 bool _M_trailing_empty =
false;
3540 using iterator_concept = __conditional_t<forward_range<_Base>,
3541 forward_iterator_tag,
3542 input_iterator_tag>;
3544 using difference_type = range_difference_t<_Base>;
3546 struct value_type : view_interface<value_type>
3549 _OuterIter _M_i = _OuterIter();
3555 value_type(_OuterIter __i)
3556 : _M_i(std::
move(__i))
3562 constexpr _InnerIter<_Const>
3564 {
return _InnerIter<_Const>{_M_i}; }
3566 constexpr default_sentinel_t
3567 end() const noexcept
3571 _OuterIter() =
default;
3574 _OuterIter(_Parent* __parent)
requires (!forward_range<_Base>)
3575 : _M_parent(__parent)
3579 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3580 requires forward_range<_Base>
3581 : _M_parent(__parent),
3586 _OuterIter(_OuterIter<!_Const> __i)
3588 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3589 : _M_parent(__i._M_parent), _M_current(
std::move(__i._M_current)),
3590 _M_trailing_empty(__i._M_trailing_empty)
3593 constexpr value_type
3595 {
return value_type{*
this}; }
3597 constexpr _OuterIter&
3602 const auto __end = ranges::end(_M_parent->_M_base);
3603 if (__current() == __end)
3605 _M_trailing_empty =
false;
3608 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3609 if (__pbegin == __pend)
3611 else if constexpr (__detail::__tiny_range<_Pattern>)
3613 __current() = ranges::find(
std::move(__current()), __end,
3615 if (__current() != __end)
3618 if (__current() == __end)
3619 _M_trailing_empty =
true;
3626 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3630 if (__current() == __end)
3631 _M_trailing_empty =
true;
3634 }
while (++__current() != __end);
3638 constexpr decltype(
auto)
3641 if constexpr (forward_range<_Base>)
3651 friend constexpr bool
3652 operator==(
const _OuterIter& __x,
const _OuterIter& __y)
3653 requires forward_range<_Base>
3655 return __x._M_current == __y._M_current
3656 && __x._M_trailing_empty == __y._M_trailing_empty;
3659 friend constexpr bool
3660 operator==(
const _OuterIter& __x, default_sentinel_t)
3661 {
return __x.__at_end(); };
3663 friend _OuterIter<!_Const>;
3664 friend _InnerIter<_Const>;
3667 template<
bool _Const>
3669 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3672 using _Base = lazy_split_view::_Base<_Const>;
3677 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3678 auto __end = ranges::end(_M_i._M_parent->_M_base);
3679 if constexpr (__detail::__tiny_range<_Pattern>)
3681 const auto& __cur = _M_i_current();
3684 if (__pcur == __pend)
3685 return _M_incremented;
3686 return *__cur == *__pcur;
3690 auto __cur = _M_i_current();
3693 if (__pcur == __pend)
3694 return _M_incremented;
3697 if (*__cur != *__pcur)
3699 if (++__pcur == __pend)
3701 }
while (++__cur != __end);
3707 _M_i_current() noexcept
3708 {
return _M_i.__current(); }
3711 _M_i_current() const noexcept
3712 {
return _M_i.__current(); }
3714 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3715 bool _M_incremented =
false;
3718 using iterator_concept
3719 =
typename _OuterIter<_Const>::iterator_concept;
3721 using value_type = range_value_t<_Base>;
3722 using difference_type = range_difference_t<_Base>;
3724 _InnerIter() =
default;
3727 _InnerIter(_OuterIter<_Const> __i)
3728 : _M_i(std::
move(__i))
3731 constexpr const iterator_t<_Base>&
3732 base() const& noexcept
3733 {
return _M_i_current(); }
3735 constexpr iterator_t<_Base>
3736 base() &&
requires forward_range<_Vp>
3739 constexpr decltype(
auto)
3741 {
return *_M_i_current(); }
3743 constexpr _InnerIter&
3746 _M_incremented =
true;
3747 if constexpr (!forward_range<_Base>)
3748 if constexpr (_Pattern::size() == 0)
3754 constexpr decltype(
auto)
3757 if constexpr (forward_range<_Base>)
3767 friend constexpr bool
3768 operator==(
const _InnerIter& __x,
const _InnerIter& __y)
3769 requires forward_range<_Base>
3770 {
return __x._M_i == __y._M_i; }
3772 friend constexpr bool
3773 operator==(
const _InnerIter& __x, default_sentinel_t)
3774 {
return __x.__at_end(); }
3776 friend constexpr decltype(
auto)
3777 iter_move(
const _InnerIter& __i)
3778 noexcept(
noexcept(ranges::iter_move(__i._M_i_current())))
3779 {
return ranges::iter_move(__i._M_i_current()); }
3781 friend constexpr void
3782 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
3783 noexcept(
noexcept(ranges::iter_swap(__x._M_i_current(),
3784 __y._M_i_current())))
3785 requires indirectly_swappable<iterator_t<_Base>>
3786 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3789 _Vp _M_base = _Vp();
3790 _Pattern _M_pattern = _Pattern();
3791 [[no_unique_address]]
3792 __detail::__maybe_present_t<!forward_range<_Vp>,
3793 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3797 lazy_split_view()
requires (default_initializable<_Vp>
3798 && default_initializable<_Pattern>)
3802 lazy_split_view(_Vp __base, _Pattern __pattern)
3806 template<input_range _Range>
3807 requires constructible_from<_Vp, views::all_t<_Range>>
3808 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3810 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3811 : _M_base(views::all(
std::
forward<_Range>(__r))),
3812 _M_pattern(views::single(
std::
move(__e)))
3816 base() const& requires copy_constructible<_Vp>
3826 if constexpr (forward_range<_Vp>)
3828 constexpr bool __simple
3829 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3830 return _OuterIter<__simple>{
this, ranges::begin(_M_base)};
3834 _M_current = ranges::begin(_M_base);
3835 return _OuterIter<false>{
this};
3840 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3842 return _OuterIter<true>{
this, ranges::begin(_M_base)};
3846 end()
requires forward_range<_Vp> && common_range<_Vp>
3848 constexpr bool __simple
3849 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3850 return _OuterIter<__simple>{
this, ranges::end(_M_base)};
3856 if constexpr (forward_range<_Vp>
3857 && forward_range<const _Vp>
3858 && common_range<const _Vp>)
3859 return _OuterIter<true>{
this, ranges::end(_M_base)};
3865 template<
typename _Range,
typename _Pattern>
3866 lazy_split_view(_Range&&, _Pattern&&)
3867 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3869 template<input_range _Range>
3870 lazy_split_view(_Range&&, range_value_t<_Range>)
3871 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3877 template<
typename _Range,
typename _Pattern>
3878 concept __can_lazy_split_view
3882 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3884 template<viewable_range _Range,
typename _Pattern>
3885 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3887 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
3892 using _RangeAdaptor<_LazySplit>::operator();
3893 static constexpr int _S_arity = 2;
3898 template<
typename _Pattern>
3899 static constexpr bool _S_has_simple_extra_args
3900 = is_scalar_v<_Pattern> || (view<_Pattern>
3901 && copy_constructible<_Pattern>);
3904 inline constexpr _LazySplit lazy_split;
3907 template<forward_range _Vp, forward_range _Pattern>
3908 requires view<_Vp> && view<_Pattern>
3909 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3911 class split_view :
public view_interface<split_view<_Vp, _Pattern>>
3914 _Vp _M_base = _Vp();
3915 _Pattern _M_pattern = _Pattern();
3916 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3922 split_view()
requires (default_initializable<_Vp>
3923 && default_initializable<_Pattern>)
3927 split_view(_Vp __base, _Pattern __pattern)
3931 template<forward_range _Range>
3932 requires constructible_from<_Vp, views::all_t<_Range>>
3933 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3935 split_view(_Range&& __r, range_value_t<_Range> __e)
3936 : _M_base(views::all(std::
forward<_Range>(__r))),
3937 _M_pattern(views::single(std::
move(__e)))
3941 base() const& requires copy_constructible<_Vp>
3951 if (!_M_cached_begin)
3952 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3953 return {
this, ranges::begin(_M_base), *_M_cached_begin};
3959 if constexpr (common_range<_Vp>)
3960 return _Iterator{
this, ranges::end(_M_base), {}};
3962 return _Sentinel{
this};
3965 constexpr subrange<iterator_t<_Vp>>
3966 _M_find_next(iterator_t<_Vp> __it)
3968 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3969 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3981 split_view* _M_parent =
nullptr;
3982 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3983 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3984 bool _M_trailing_empty =
false;
3986 friend struct _Sentinel;
3989 using iterator_concept = forward_iterator_tag;
3990 using iterator_category = input_iterator_tag;
3991 using value_type = subrange<iterator_t<_Vp>>;
3992 using difference_type = range_difference_t<_Vp>;
3994 _Iterator() =
default;
3997 _Iterator(split_view* __parent,
3998 iterator_t<_Vp> __current,
3999 subrange<iterator_t<_Vp>> __next)
4000 : _M_parent(__parent),
4001 _M_cur(std::
move(__current)),
4002 _M_next(std::
move(__next))
4005 constexpr iterator_t<_Vp>
4009 constexpr value_type
4011 {
return {_M_cur, _M_next.begin()}; }
4013 constexpr _Iterator&
4016 _M_cur = _M_next.begin();
4017 if (_M_cur != ranges::end(_M_parent->_M_base))
4019 _M_cur = _M_next.end();
4020 if (_M_cur == ranges::end(_M_parent->_M_base))
4022 _M_trailing_empty =
true;
4023 _M_next = {_M_cur, _M_cur};
4026 _M_next = _M_parent->_M_find_next(_M_cur);
4029 _M_trailing_empty =
false;
4041 friend constexpr bool
4042 operator==(
const _Iterator& __x,
const _Iterator& __y)
4044 return __x._M_cur == __y._M_cur
4045 && __x._M_trailing_empty == __y._M_trailing_empty;
4052 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
4055 _M_equal(
const _Iterator& __x)
const
4056 {
return __x._M_cur == _M_end && !__x._M_trailing_empty; }
4059 _Sentinel() =
default;
4062 _Sentinel(split_view* __parent)
4063 : _M_end(ranges::
end(__parent->_M_base))
4066 friend constexpr bool
4067 operator==(
const _Iterator& __x,
const _Sentinel& __y)
4068 {
return __y._M_equal(__x); }
4072 template<
typename _Range,
typename _Pattern>
4073 split_view(_Range&&, _Pattern&&)
4074 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
4076 template<forward_range _Range>
4077 split_view(_Range&&, range_value_t<_Range>)
4078 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
4084 template<
typename _Range,
typename _Pattern>
4085 concept __can_split_view
4089 struct _Split : __adaptor::_RangeAdaptor<_Split>
4091 template<viewable_range _Range,
typename _Pattern>
4092 requires __detail::__can_split_view<_Range, _Pattern>
4094 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
4099 using _RangeAdaptor<_Split>::operator();
4100 static constexpr int _S_arity = 2;
4101 template<
typename _Pattern>
4102 static constexpr bool _S_has_simple_extra_args
4103 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
4106 inline constexpr _Split split;
4113 template<input_or_output_iterator _Iter>
4115 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n)
const
4117 if constexpr (contiguous_iterator<_Iter>)
4119 else if constexpr (random_access_iterator<_Iter>)
4120 return subrange(__i, __i + __n);
4122 return subrange(counted_iterator(
std::move(__i), __n),
4127 inline constexpr _Counted counted{};
4131 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
4132 class common_view : public view_interface<common_view<_Vp>>
4135 _Vp _M_base = _Vp();
4138 common_view()
requires default_initializable<_Vp> = default;
4141 common_view(_Vp __r)
4142 : _M_base(
std::move(__r))
4146 base() const& requires copy_constructible<_Vp>
4156 begin()
requires (!__detail::__simple_view<_Vp>)
4158 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4159 return ranges::begin(_M_base);
4161 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4162 (ranges::begin(_M_base));
4166 begin() const requires range<const _Vp>
4168 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4169 return ranges::begin(_M_base);
4171 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4172 (ranges::begin(_M_base));
4176 end()
requires (!__detail::__simple_view<_Vp>)
4178 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4179 return ranges::begin(_M_base) + ranges::size(_M_base);
4181 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4182 (ranges::end(_M_base));
4186 end() const requires range<const _Vp>
4188 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4189 return ranges::begin(_M_base) + ranges::size(_M_base);
4191 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4192 (ranges::end(_M_base));
4196 size()
requires sized_range<_Vp>
4197 {
return ranges::size(_M_base); }
4200 size() const requires sized_range<const _Vp>
4201 {
return ranges::size(_M_base); }
4204 template<
typename _Range>
4205 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4207 template<
typename _Tp>
4208 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4209 = enable_borrowed_range<_Tp>;
4215 template<
typename _Range>
4216 concept __already_common = common_range<_Range>
4219 template<
typename _Range>
4220 concept __can_common_view
4224 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4226 template<viewable_range _Range>
4227 requires __detail::__already_common<_Range>
4228 || __detail::__can_common_view<_Range>
4230 operator() [[nodiscard]] (_Range&& __r)
const
4232 if constexpr (__detail::__already_common<_Range>)
4238 static constexpr bool _S_has_simple_call_op =
true;
4241 inline constexpr _Common common;
4245 requires bidirectional_range<_Vp>
4246 class reverse_view :
public view_interface<reverse_view<_Vp>>
4249 static constexpr bool _S_needs_cached_begin
4250 = !common_range<_Vp> && !(random_access_range<_Vp>
4251 && sized_sentinel_for<sentinel_t<_Vp>,
4254 _Vp _M_base = _Vp();
4255 [[no_unique_address]]
4256 __detail::__maybe_present_t<_S_needs_cached_begin,
4257 __detail::_CachedPosition<_Vp>>
4261 reverse_view()
requires default_initializable<_Vp> = default;
4264 reverse_view(_Vp __r)
4265 : _M_base(std::move(__r))
4269 base() const& requires copy_constructible<_Vp>
4276 constexpr reverse_iterator<iterator_t<_Vp>>
4279 if constexpr (_S_needs_cached_begin)
4280 if (_M_cached_begin._M_has_value())
4283 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4284 if constexpr (_S_needs_cached_begin)
4285 _M_cached_begin._M_set(_M_base, __it);
4290 begin()
requires common_range<_Vp>
4294 begin() const requires common_range<const _Vp>
4297 constexpr reverse_iterator<iterator_t<_Vp>>
4302 end() const requires common_range<const _Vp>
4306 size()
requires sized_range<_Vp>
4307 {
return ranges::size(_M_base); }
4310 size() const requires sized_range<const _Vp>
4311 {
return ranges::size(_M_base); }
4314 template<
typename _Range>
4315 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4317 template<
typename _Tp>
4318 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4319 = enable_borrowed_range<_Tp>;
4326 inline constexpr bool __is_reversible_subrange =
false;
4328 template<
typename _Iter, subrange_kind _Kind>
4329 inline constexpr bool
4330 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4331 reverse_iterator<_Iter>,
4335 inline constexpr bool __is_reverse_view =
false;
4337 template<
typename _Vp>
4338 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> =
true;
4340 template<
typename _Range>
4341 concept __can_reverse_view
4345 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4347 template<viewable_range _Range>
4348 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4349 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4350 || __detail::__can_reverse_view<_Range>
4352 operator() [[nodiscard]] (_Range&& __r)
const
4354 using _Tp = remove_cvref_t<_Range>;
4355 if constexpr (__detail::__is_reverse_view<_Tp>)
4357#ifdef __cpp_lib_optional_range_support
4358 else if constexpr (__is_optional_v<_Tp> && view<_Tp>)
4361 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4363 using _Iter =
decltype(ranges::begin(__r).base());
4364 if constexpr (sized_range<_Tp>)
4365 return subrange<_Iter, _Iter, subrange_kind::sized>
4366 {__r.end().base(), __r.begin().base(), __r.size()};
4368 return subrange<_Iter, _Iter, subrange_kind::unsized>
4369 {__r.end().base(), __r.begin().base()};
4375 static constexpr bool _S_has_simple_call_op =
true;
4378 inline constexpr _Reverse reverse;
4383#if __cpp_lib_tuple_like
4384 template<
typename _Tp,
size_t _Nm>
4385 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4387 template<
typename _Tp,
size_t _Nm>
4388 concept __has_tuple_element =
requires(_Tp __t)
4390 typename tuple_size<_Tp>::type;
4391 requires _Nm < tuple_size_v<_Tp>;
4392 typename tuple_element_t<_Nm, _Tp>;
4393 { std::get<_Nm>(__t) }
4394 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4398 template<
typename _Tp,
size_t _Nm>
4399 concept __returnable_element
4400 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4403 template<input_range _Vp,
size_t _Nm>
4405 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4406 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4408 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4409 class elements_view :
public view_interface<elements_view<_Vp, _Nm>>
4412 elements_view()
requires default_initializable<_Vp> = default;
4415 elements_view(_Vp __base)
4416 : _M_base(std::move(__base))
4420 base() const& requires copy_constructible<_Vp>
4428 begin()
requires (!__detail::__simple_view<_Vp>)
4429 {
return _Iterator<false>(ranges::begin(_M_base)); }
4432 begin() const requires range<const _Vp>
4433 {
return _Iterator<true>(ranges::begin(_M_base)); }
4436 end()
requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4437 {
return _Sentinel<false>{ranges::end(_M_base)}; }
4440 end()
requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4441 {
return _Iterator<false>{ranges::end(_M_base)}; }
4444 end() const requires range<const _Vp>
4445 {
return _Sentinel<true>{ranges::end(_M_base)}; }
4448 end() const requires common_range<const _Vp>
4449 {
return _Iterator<true>{ranges::end(_M_base)}; }
4452 size()
requires sized_range<_Vp>
4453 {
return ranges::size(_M_base); }
4456 size() const requires sized_range<const _Vp>
4457 {
return ranges::size(_M_base); }
4460 template<
bool _Const>
4461 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4463 template<
bool _Const>
4467 template<
bool _Const>
4468 requires forward_range<_Base<_Const>>
4469 struct __iter_cat<_Const>
4472 static auto _S_iter_cat()
4474 using _Base = elements_view::_Base<_Const>;
4475 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
4476 using _Res =
decltype((std::get<_Nm>(*
std::declval<iterator_t<_Base>>())));
4477 if constexpr (!is_lvalue_reference_v<_Res>)
4478 return input_iterator_tag{};
4479 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4480 return random_access_iterator_tag{};
4485 using iterator_category =
decltype(_S_iter_cat());
4488 template<
bool _Const>
4491 template<
bool _Const>
4492 struct _Iterator : __iter_cat<_Const>
4495 using _Base = elements_view::_Base<_Const>;
4497 iterator_t<_Base> _M_current = iterator_t<_Base>();
4499 static constexpr decltype(
auto)
4500 _S_get_element(
const iterator_t<_Base>& __i)
4502 if constexpr (is_reference_v<range_reference_t<_Base>>)
4503 return std::get<_Nm>(*__i);
4506 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4507 return static_cast<_Et
>(std::get<_Nm>(*__i));
4514 if constexpr (random_access_range<_Base>)
4515 return random_access_iterator_tag{};
4516 else if constexpr (bidirectional_range<_Base>)
4517 return bidirectional_iterator_tag{};
4518 else if constexpr (forward_range<_Base>)
4519 return forward_iterator_tag{};
4521 return input_iterator_tag{};
4524 friend _Iterator<!_Const>;
4527 using iterator_concept =
decltype(_S_iter_concept());
4530 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4531 using difference_type = range_difference_t<_Base>;
4533 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
4536 _Iterator(iterator_t<_Base> __current)
4537 : _M_current(std::move(__current))
4541 _Iterator(_Iterator<!_Const> __i)
4542 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4546 constexpr const iterator_t<_Base>&
4547 base() const& noexcept
4548 {
return _M_current; }
4550 constexpr iterator_t<_Base>
4554 constexpr decltype(
auto)
4556 {
return _S_get_element(_M_current); }
4558 constexpr _Iterator&
4570 operator++(
int)
requires forward_range<_Base>
4577 constexpr _Iterator&
4578 operator--()
requires bidirectional_range<_Base>
4585 operator--(
int)
requires bidirectional_range<_Base>
4592 constexpr _Iterator&
4593 operator+=(difference_type __n)
4594 requires random_access_range<_Base>
4600 constexpr _Iterator&
4601 operator-=(difference_type __n)
4602 requires random_access_range<_Base>
4608 constexpr decltype(
auto)
4609 operator[](difference_type __n)
const
4610 requires random_access_range<_Base>
4611 {
return _S_get_element(_M_current + __n); }
4613 friend constexpr bool
4614 operator==(
const _Iterator& __x,
const _Iterator& __y)
4615 requires equality_comparable<iterator_t<_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 __x._M_current < __y._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 !(__y._M_current > __x._M_current); }
4633 friend constexpr bool
4634 operator>=(
const _Iterator& __x,
const _Iterator& __y)
4635 requires random_access_range<_Base>
4636 {
return !(__x._M_current > __y._M_current); }
4638#ifdef __cpp_lib_three_way_comparison
4639 friend constexpr auto
4640 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
4641 requires random_access_range<_Base>
4642 && three_way_comparable<iterator_t<_Base>>
4643 {
return __x._M_current <=> __y._M_current; }
4646 friend constexpr _Iterator
4647 operator+(
const _Iterator& __x, difference_type __y)
4648 requires random_access_range<_Base>
4649 {
return _Iterator{__x} += __y; }
4651 friend constexpr _Iterator
4652 operator+(difference_type __x,
const _Iterator& __y)
4653 requires random_access_range<_Base>
4654 {
return __y + __x; }
4656 friend constexpr _Iterator
4657 operator-(
const _Iterator& __x, difference_type __y)
4658 requires random_access_range<_Base>
4659 {
return _Iterator{__x} -= __y; }
4663 friend constexpr difference_type
4664 operator-(
const _Iterator& __x,
const _Iterator& __y)
4665 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4666 {
return __x._M_current - __y._M_current; }
4668 template <
bool>
friend struct _Sentinel;
4671 template<
bool _Const>
4675 template<
bool _Const2>
4677 _M_equal(
const _Iterator<_Const2>& __x)
const
4678 {
return __x._M_current == _M_end; }
4680 template<
bool _Const2>
4682 _M_distance_from(
const _Iterator<_Const2>& __i)
const
4683 {
return _M_end - __i._M_current; }
4685 using _Base = elements_view::_Base<_Const>;
4686 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4689 _Sentinel() =
default;
4692 _Sentinel(sentinel_t<_Base> __end)
4693 : _M_end(std::
move(__end))
4697 _Sentinel(_Sentinel<!_Const> __other)
4699 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4703 constexpr sentinel_t<_Base>
4707 template<
bool _Const2>
4708 requires sentinel_for<sentinel_t<_Base>,
4709 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4710 friend constexpr bool
4711 operator==(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4712 {
return __y._M_equal(__x); }
4714 template<
bool _Const2,
4715 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4716 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4717 friend constexpr range_difference_t<_Base2>
4718 operator-(
const _Iterator<_Const2>& __x,
const _Sentinel& __y)
4719 {
return -__y._M_distance_from(__x); }
4721 template<
bool _Const2,
4722 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4723 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4724 friend constexpr range_difference_t<_Base2>
4725 operator-(
const _Sentinel& __x,
const _Iterator<_Const2>& __y)
4726 {
return __x._M_distance_from(__y); }
4728 friend _Sentinel<!_Const>;
4731 _Vp _M_base = _Vp();
4734 template<
typename _Tp,
size_t _Nm>
4735 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4736 = enable_borrowed_range<_Tp>;
4740 template<
typename _Range>
4741 using keys_view = elements_view<_Range, 0>;
4743 template<
typename _Range>
4744 using values_view = elements_view<_Range, 1>;
4750 template<
size_t _Nm,
typename _Range>
4751 concept __can_elements_view
4755 template<
size_t _Nm>
4756 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4758 template<viewable_range _Range>
4759 requires __detail::__can_elements_view<_Nm, _Range>
4761 operator() [[nodiscard]] (_Range&& __r)
const
4766 static constexpr bool _S_has_simple_call_op =
true;
4769 template<
size_t _Nm>
4770 inline constexpr _Elements<_Nm> elements;
4771 inline constexpr auto keys = elements<0>;
4772 inline constexpr auto values = elements<1>;
4775#ifdef __cpp_lib_ranges_zip
4778 template<
typename... _Rs>
4779 concept __zip_is_common = (
sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4780 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4781 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4783 template<
typename _Fp,
typename _Tuple>
4785 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4787 return std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4788 return tuple<invoke_result_t<_Fp&, _Ts>...>
4793 template<
typename _Fp,
typename _Tuple>
4795 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4797 std::apply([&]<
typename... _Ts>(_Ts&&... __elts) {
4803 template<input_range... _Vs>
4804 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4805 class zip_view : public view_interface<zip_view<_Vs...>>
4807 tuple<_Vs...> _M_views;
4809 template<
bool>
class _Iterator;
4810 template<
bool>
class _Sentinel;
4813 zip_view() =
default;
4816 zip_view(_Vs... __views)
4817 : _M_views(
std::
move(__views)...)
4821 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
4822 {
return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4825 begin() const requires (range<const _Vs> && ...)
4826 {
return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4829 end()
requires (!(__detail::__simple_view<_Vs> && ...))
4831 if constexpr (!__detail::__zip_is_common<_Vs...>)
4832 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4833 else if constexpr ((random_access_range<_Vs> && ...))
4834 return begin() + iter_difference_t<_Iterator<false>>(
size());
4836 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4840 end() const requires (range<const _Vs> && ...)
4842 if constexpr (!__detail::__zip_is_common<
const _Vs...>)
4843 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4844 else if constexpr ((random_access_range<const _Vs> && ...))
4845 return begin() + iter_difference_t<_Iterator<true>>(
size());
4847 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4851 size()
requires (sized_range<_Vs> && ...)
4853 return std::apply([](
auto... sizes) {
4854 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4855 return ranges::min({_CT(sizes)...});
4856 }, __detail::__tuple_transform(ranges::size, _M_views));
4860 size() const requires (sized_range<const _Vs> && ...)
4862 return std::apply([](
auto... sizes) {
4863 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(sizes)...>>;
4864 return ranges::min({_CT(sizes)...});
4865 }, __detail::__tuple_transform(ranges::size, _M_views));
4869 template<
typename... _Rs>
4870 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4872 template<
typename... _Views>
4873 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4874 = (enable_borrowed_range<_Views> && ...);
4878 template<
bool _Const,
typename... _Vs>
4879 concept __all_random_access
4880 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4882 template<
bool _Const,
typename... _Vs>
4883 concept __all_bidirectional
4884 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4886 template<
bool _Const,
typename... _Vs>
4887 concept __all_forward
4888 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4890 template<
bool _Const,
typename... _Views>
4891 struct __zip_view_iter_cat
4894 template<
bool _Const,
typename... _Views>
4895 requires __all_forward<_Const, _Views...>
4896 struct __zip_view_iter_cat<_Const, _Views...>
4897 {
using iterator_category = input_iterator_tag; };
4900 template<input_range... _Vs>
4901 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
4902 template<bool _Const>
4903 class zip_view<_Vs...>::_Iterator
4904 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4906#ifdef _GLIBCXX_CLANG
4909 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4912 _Iterator(
decltype(_M_current) __current)
4913 : _M_current(
std::
move(__current))
4919 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4920 return random_access_iterator_tag{};
4921 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4922 return bidirectional_iterator_tag{};
4923 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4924 return forward_iterator_tag{};
4926 return input_iterator_tag{};
4929#ifndef _GLIBCXX_CLANG
4930 template<move_constructible _Fp, input_range... _Ws>
4931 requires (view<_Ws> && ...) && (
sizeof...(_Ws) > 0) && is_object_v<_Fp>
4932 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4933 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4934 friend class zip_transform_view;
4939 using iterator_concept =
decltype(_S_iter_concept());
4941 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4942 using difference_type
4943 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4945 _Iterator() =
default;
4948 _Iterator(_Iterator<!_Const> __i)
4950 && (convertible_to<iterator_t<_Vs>,
4951 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4952 : _M_current(
std::
move(__i._M_current))
4958 auto __f = [](
auto& __i) ->
decltype(
auto) {
4961 return __detail::__tuple_transform(__f, _M_current);
4964 constexpr _Iterator&
4967 __detail::__tuple_for_each([](
auto& __i) { ++__i; }, _M_current);
4977 requires __detail::__all_forward<_Const, _Vs...>
4984 constexpr _Iterator&
4986 requires __detail::__all_bidirectional<_Const, _Vs...>
4988 __detail::__tuple_for_each([](
auto& __i) { --__i; }, _M_current);
4994 requires __detail::__all_bidirectional<_Const, _Vs...>
5001 constexpr _Iterator&
5002 operator+=(difference_type __x)
5003 requires __detail::__all_random_access<_Const, _Vs...>
5005 auto __f = [&]<
typename _It>(_It& __i) {
5006 __i += iter_difference_t<_It>(__x);
5008 __detail::__tuple_for_each(__f, _M_current);
5012 constexpr _Iterator&
5013 operator-=(difference_type __x)
5014 requires __detail::__all_random_access<_Const, _Vs...>
5016 auto __f = [&]<
typename _It>(_It& __i) {
5017 __i -= iter_difference_t<_It>(__x);
5019 __detail::__tuple_for_each(__f, _M_current);
5024 operator[](difference_type __n)
const
5025 requires __detail::__all_random_access<_Const, _Vs...>
5027 auto __f = [&]<
typename _It>(_It& __i) ->
decltype(
auto) {
5028 return __i[iter_difference_t<_It>(__n)];
5030 return __detail::__tuple_transform(__f, _M_current);
5033 friend constexpr bool
5034 operator==(
const _Iterator& __x,
const _Iterator& __y)
5035 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5037 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
5038 return __x._M_current == __y._M_current;
5041 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
5045 friend constexpr auto
5046 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5047 requires __detail::__all_random_access<_Const, _Vs...>
5048 {
return __x._M_current <=> __y._M_current; }
5050 friend constexpr _Iterator
5051 operator+(
const _Iterator& __i, difference_type __n)
5052 requires __detail::__all_random_access<_Const, _Vs...>
5059 friend constexpr _Iterator
5060 operator+(difference_type __n,
const _Iterator& __i)
5061 requires __detail::__all_random_access<_Const, _Vs...>
5068 friend constexpr _Iterator
5069 operator-(
const _Iterator& __i, difference_type __n)
5070 requires __detail::__all_random_access<_Const, _Vs...>
5077 friend constexpr difference_type
5078 operator-(
const _Iterator& __x,
const _Iterator& __y)
5079 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
5080 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5083 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
5084 - std::get<_Is>(__y._M_current))...},
5086 [](difference_type __i) {
5087 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5092 friend constexpr auto
5093 iter_move(
const _Iterator& __i)
5094 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5096 friend constexpr void
5097 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5098 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5101 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
5105 friend class zip_view;
5108 template<input_range... _Vs>
5109 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0)
5110 template<bool _Const>
5111 class zip_view<_Vs...>::_Sentinel
5113 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
5116 _Sentinel(
decltype(_M_end) __end)
5120 friend class zip_view;
5123 _Sentinel() =
default;
5126 _Sentinel(_Sentinel<!_Const> __i)
5128 && (convertible_to<sentinel_t<_Vs>,
5129 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
5130 : _M_end(
std::
move(__i._M_end))
5133 template<
bool _OtherConst>
5134 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5135 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5136 friend constexpr bool
5137 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5140 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
5144 template<
bool _OtherConst>
5145 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5146 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5147 friend constexpr auto
5148 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5151 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
5153 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
5156 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
5161 template<
bool _OtherConst>
5162 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
5163 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
5164 friend constexpr auto
5165 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5166 {
return -(__x - __y); }
5173 template<
typename... _Ts>
5174 concept __can_zip_view
5180 template<
typename... _Ts>
5181 requires (
sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5183 operator() [[nodiscard]] (_Ts&&... __ts)
const
5185 if constexpr (
sizeof...(_Ts) == 0)
5186 return views::empty<tuple<>>;
5192 inline constexpr _Zip zip;
5197 template<
typename _Range,
bool _Const>
5198 using __range_iter_cat
5199 =
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5202 template<move_constructible _Fp, input_range... _Vs>
5203 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5204 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5205 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5206 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5208 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5209 zip_view<_Vs...> _M_zip;
5211 using _InnerView = zip_view<_Vs...>;
5213 template<
bool _Const>
5214 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5216 template<
bool _Const>
5217 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5219 template<
bool _Const>
5220 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5222 template<
bool _Const>
5226 template<
bool _Const>
5227 requires forward_range<_Base<_Const>>
5228 struct __iter_cat<_Const>
5234 using __detail::__maybe_const_t;
5235 using __detail::__range_iter_cat;
5236 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5237 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5240 if constexpr (!is_reference_v<_Res>)
5241 return input_iterator_tag{};
5242 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5243 random_access_iterator_tag> && ...))
5244 return random_access_iterator_tag{};
5245 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5246 bidirectional_iterator_tag> && ...))
5247 return bidirectional_iterator_tag{};
5248 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5249 forward_iterator_tag> && ...))
5250 return forward_iterator_tag{};
5252 return input_iterator_tag{};
5255 using iterator_category =
decltype(_S_iter_cat());
5258 template<
bool>
class _Iterator;
5259 template<
bool>
class _Sentinel;
5262 zip_transform_view() =
default;
5265 zip_transform_view(_Fp __fun, _Vs... __views)
5271 {
return _Iterator<false>(*
this, _M_zip.begin()); }
5275 requires range<const _InnerView>
5276 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5277 {
return _Iterator<true>(*
this, _M_zip.begin()); }
5282 if constexpr (common_range<_InnerView>)
5283 return _Iterator<false>(*
this, _M_zip.end());
5285 return _Sentinel<false>(_M_zip.end());
5290 requires range<const _InnerView>
5291 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5293 if constexpr (common_range<const _InnerView>)
5294 return _Iterator<true>(*
this, _M_zip.end());
5296 return _Sentinel<true>(_M_zip.end());
5300 size()
requires sized_range<_InnerView>
5301 {
return _M_zip.size(); }
5304 size() const requires sized_range<const _InnerView>
5305 {
return _M_zip.size(); }
5308 template<
class _Fp,
class... Rs>
5309 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5311 template<move_constructible _Fp, input_range... _Vs>
5312 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5313 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5314 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5315 template<bool _Const>
5316 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5318 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5319 using _Fun_handle = __detail::__func_handle_t<
5320 __detail::__maybe_const_t<_Const, _Fp>,
5321 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
5323 [[no_unique_address]] _Fun_handle _M_fun;
5324 __ziperator<_Const> _M_inner;
5327 _Iterator(_Fun_handle __fun, __ziperator<_Const> __inner)
5328 : _M_fun(__fun), _M_inner(
std::
move(__inner))
5332 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5333 : _M_fun(*__parent._M_fun), _M_inner(
std::
move(__inner))
5336 friend class zip_transform_view;
5340 using iterator_concept =
typename __ziperator<_Const>::iterator_concept;
5342 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5343 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5344 using difference_type = range_difference_t<_Base<_Const>>;
5346 _Iterator() =
default;
5349 _Iterator(_Iterator<!_Const> __i)
5350 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5351 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
5354 constexpr decltype(
auto)
5357 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
5358 return _M_fun._M_call_deref(__iters...);
5359 }, _M_inner._M_current);
5362 constexpr _Iterator&
5374 operator++(
int)
requires forward_range<_Base<_Const>>
5381 constexpr _Iterator&
5382 operator--()
requires bidirectional_range<_Base<_Const>>
5389 operator--(
int)
requires bidirectional_range<_Base<_Const>>
5396 constexpr _Iterator&
5397 operator+=(difference_type __x)
requires random_access_range<_Base<_Const>>
5403 constexpr _Iterator&
5404 operator-=(difference_type __x)
requires random_access_range<_Base<_Const>>
5410 constexpr decltype(
auto)
5411 operator[](difference_type __n)
const requires random_access_range<_Base<_Const>>
5413 return std::apply([&]<
typename... _Is>(
const _Is&... __iters) ->
decltype(
auto) {
5414 return _M_fun._M_call_subscript(__n, __iters...);
5415 }, _M_inner._M_current);
5418 friend constexpr bool
5419 operator==(
const _Iterator& __x,
const _Iterator& __y)
5420 requires equality_comparable<__ziperator<_Const>>
5421 {
return __x._M_inner == __y._M_inner; }
5423 friend constexpr auto
5424 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5425 requires random_access_range<_Base<_Const>>
5426 {
return __x._M_inner <=> __y._M_inner; }
5428 friend constexpr _Iterator
5429 operator+(
const _Iterator& __i, difference_type __n)
5430 requires random_access_range<_Base<_Const>>
5431 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5433 friend constexpr _Iterator
5434 operator+(difference_type __n,
const _Iterator& __i)
5435 requires random_access_range<_Base<_Const>>
5436 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
5438 friend constexpr _Iterator
5439 operator-(
const _Iterator& __i, difference_type __n)
5440 requires random_access_range<_Base<_Const>>
5441 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
5443 friend constexpr difference_type
5444 operator-(
const _Iterator& __x,
const _Iterator& __y)
5445 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5446 {
return __x._M_inner - __y._M_inner; }
5449 template<move_constructible _Fp, input_range... _Vs>
5450 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && is_object_v<_Fp>
5451 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5452 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5453 template<bool _Const>
5454 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5456 __zentinel<_Const> _M_inner;
5459 _Sentinel(__zentinel<_Const> __inner)
5463 friend class zip_transform_view;
5466 _Sentinel() =
default;
5469 _Sentinel(_Sentinel<!_Const> __i)
5470 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5474 template<
bool _OtherConst>
5475 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5476 friend constexpr bool
5477 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5478 {
return __x._M_inner == __y._M_inner; }
5480 template<
bool _OtherConst>
5481 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5482 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5483 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5484 {
return __x._M_inner - __y._M_inner; }
5486 template<
bool _OtherConst>
5487 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5488 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5489 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
5490 {
return __x._M_inner - __y._M_inner; }
5497 template<
typename _Fp,
typename... _Ts>
5498 concept __can_zip_transform_view
5502 struct _ZipTransform
5504 template<
typename _Fp>
5505 requires move_constructible<decay_t<_Fp>> && regular_invocable<decay_t<_Fp>&>
5506 && is_object_v<decay_t<invoke_result_t<decay_t<_Fp>&>>>
5508 operator() [[nodiscard]] (_Fp&&)
const
5510 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5513 template<
typename _Fp,
typename... _Ts>
5514 requires (
sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...>
5516 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts)
const
5522 inline constexpr _ZipTransform zip_transform;
5525 template<forward_range _Vp,
size_t _Nm>
5526 requires view<_Vp> && (_Nm > 0)
5527 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5529 _Vp _M_base = _Vp();
5531 template<
bool>
class _Iterator;
5532 template<
bool>
class _Sentinel;
5534 struct __as_sentinel
5538 adjacent_view()
requires default_initializable<_Vp> = default;
5541 adjacent_view(_Vp __base)
5542 : _M_base(
std::move(__base))
5548 base() const & requires copy_constructible<_Vp>
5556 begin()
requires (!__detail::__simple_view<_Vp>)
5557 {
return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5560 begin() const requires range<const _Vp>
5561 {
return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5564 end()
requires (!__detail::__simple_view<_Vp>)
5566 if constexpr (common_range<_Vp>)
5567 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5569 return _Sentinel<false>(ranges::end(_M_base));
5573 end() const requires range<const _Vp>
5575 if constexpr (common_range<const _Vp>)
5576 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5578 return _Sentinel<true>(ranges::end(_M_base));
5582 size()
requires sized_range<_Vp>
5584 using _ST =
decltype(ranges::size(_M_base));
5585 using _CT = common_type_t<_ST, size_t>;
5586 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5588 return static_cast<_ST
>(__sz);
5592 size() const requires sized_range<const _Vp>
5594 using _ST =
decltype(ranges::size(_M_base));
5595 using _CT = common_type_t<_ST, size_t>;
5596 auto __sz =
static_cast<_CT
>(ranges::size(_M_base));
5598 return static_cast<_ST
>(__sz);
5602 template<
typename _Vp,
size_t _Nm>
5603 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5604 = enable_borrowed_range<_Vp>;
5609 template<
typename _Tp,
size_t _Nm>
5610 using __repeated_tuple =
typename __make_tuple<array<_Tp, _Nm>>::__type;
5614 template<
typename _Fp,
size_t _Nm>
5617 template<
typename... _Ts>
5618 static invoke_result_t<_Fp, _Ts...>
5619 __tuple_apply(
const tuple<_Ts...>&);
5621 template<
typename _Tp>
5622 decltype(__tuple_apply(
std::declval<__repeated_tuple<_Tp, _Nm>>()))
5627 template<forward_range _Vp,
size_t _Nm>
5628 requires view<_Vp> && (_Nm > 0)
5629 template<bool _Const>
5630 class adjacent_view<_Vp, _Nm>::_Iterator
5632#ifdef _GLIBCXX_CLANG
5635 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5636 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5639 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5641 for (
auto& __i : _M_current)
5644 ranges::advance(__first, 1, __last);
5649 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5651 if constexpr (!bidirectional_range<_Base>)
5652 for (
auto& __it : _M_current)
5655 for (
size_t __i = 0; __i < _Nm; ++__i)
5657 _M_current[_Nm - 1 - __i] = __last;
5658 ranges::advance(__last, -1, __first);
5665 if constexpr (random_access_range<_Base>)
5666 return random_access_iterator_tag{};
5667 else if constexpr (bidirectional_range<_Base>)
5668 return bidirectional_iterator_tag{};
5670 return forward_iterator_tag{};
5673 friend class adjacent_view;
5675#ifndef _GLIBCXX_CLANG
5676 template<forward_range _Wp, move_constructible _Fp,
size_t _Mm>
5677 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5678 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5679 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5680 range_reference_t<_Wp>>>
5681 friend class adjacent_transform_view;
5685 using iterator_category = input_iterator_tag;
5686 using iterator_concept =
decltype(_S_iter_concept());
5687 using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
5688 using difference_type = range_difference_t<_Base>;
5690 _Iterator() =
default;
5693 _Iterator(_Iterator<!_Const> __i)
5694 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5696 for (
size_t __j = 0; __j < _Nm; ++__j)
5697 _M_current[__j] =
std::move(__i._M_current[__j]);
5703 auto __f = [](
auto& __i) ->
decltype(
auto) {
return *__i; };
5704 return __detail::__tuple_transform(__f, _M_current);
5707 constexpr _Iterator&
5710 for (
auto& __i : _M_current)
5723 constexpr _Iterator&
5724 operator--()
requires bidirectional_range<_Base>
5726 for (
auto& __i : _M_current)
5732 operator--(
int)
requires bidirectional_range<_Base>
5739 constexpr _Iterator&
5740 operator+=(difference_type __x)
5741 requires random_access_range<_Base>
5743 for (
auto& __i : _M_current)
5748 constexpr _Iterator&
5749 operator-=(difference_type __x)
5750 requires random_access_range<_Base>
5752 for (
auto& __i : _M_current)
5758 operator[](difference_type __n)
const
5759 requires random_access_range<_Base>
5761 auto __f = [&](
auto& __i) ->
decltype(
auto) {
return __i[__n]; };
5762 return __detail::__tuple_transform(__f, _M_current);
5765 friend constexpr bool
5766 operator==(
const _Iterator& __x,
const _Iterator& __y)
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 __x._M_current.back() < __y._M_current.back(); }
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 !(__y < __x); }
5784 friend constexpr bool
5785 operator>=(
const _Iterator& __x,
const _Iterator& __y)
5786 requires random_access_range<_Base>
5787 {
return !(__x < __y); }
5789 friend constexpr auto
5790 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
5791 requires random_access_range<_Base>
5792 && three_way_comparable<iterator_t<_Base>>
5793 {
return __x._M_current.back() <=> __y._M_current.back(); }
5795 friend constexpr _Iterator
5796 operator+(
const _Iterator& __i, difference_type __n)
5797 requires random_access_range<_Base>
5804 friend constexpr _Iterator
5805 operator+(difference_type __n,
const _Iterator& __i)
5806 requires random_access_range<_Base>
5813 friend constexpr _Iterator
5814 operator-(
const _Iterator& __i, difference_type __n)
5815 requires random_access_range<_Base>
5822 friend constexpr difference_type
5823 operator-(
const _Iterator& __x,
const _Iterator& __y)
5824 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5825 {
return __x._M_current.back() - __y._M_current.back(); }
5827 friend constexpr auto
5828 iter_move(
const _Iterator& __i)
5829 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5831 friend constexpr void
5832 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
5833 requires indirectly_swappable<iterator_t<_Base>>
5835 for (
size_t __i = 0; __i < _Nm; __i++)
5836 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5840 template<forward_range _Vp,
size_t _Nm>
5841 requires view<_Vp> && (_Nm > 0)
5842 template<bool _Const>
5843 class adjacent_view<_Vp, _Nm>::_Sentinel
5845 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5847 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5850 _Sentinel(sentinel_t<_Base> __end)
5854 friend class adjacent_view;
5857 _Sentinel() =
default;
5860 _Sentinel(_Sentinel<!_Const> __i)
5861 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5865 template<
bool _OtherConst>
5866 requires sentinel_for<sentinel_t<_Base>,
5867 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5868 friend constexpr bool
5869 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5870 {
return __x._M_current.back() == __y._M_end; }
5872 template<
bool _OtherConst>
5873 requires sized_sentinel_for<sentinel_t<_Base>,
5874 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5875 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5876 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
5877 {
return __x._M_current.back() - __y._M_end; }
5879 template<
bool _OtherConst>
5880 requires sized_sentinel_for<sentinel_t<_Base>,
5881 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5882 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5883 operator-(
const _Sentinel& __y,
const _Iterator<_OtherConst>& __x)
5884 {
return __y._M_end - __x._M_current.back(); }
5891 template<
size_t _Nm,
typename _Range>
5892 concept __can_adjacent_view
5896 template<
size_t _Nm>
5897 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5899 template<viewable_range _Range>
5900 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5902 operator() [[nodiscard]] (_Range&& __r)
const
5904 if constexpr (_Nm == 0)
5905 return views::empty<tuple<>>;
5911 template<
size_t _Nm>
5912 inline constexpr _Adjacent<_Nm> adjacent;
5914 inline constexpr auto pairwise = adjacent<2>;
5917 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5918 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5919 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5920 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5921 range_reference_t<_Vp>>>
5922 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5924 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5925 adjacent_view<_Vp, _Nm> _M_inner;
5927 using _InnerView = adjacent_view<_Vp, _Nm>;
5929 template<
bool _Const>
5930 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5932 template<
bool _Const>
5933 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5935 template<
bool>
class _Iterator;
5936 template<
bool>
class _Sentinel;
5939 adjacent_transform_view() =
default;
5942 adjacent_transform_view(_Vp __base, _Fp __fun)
5950 base() const & requires copy_constructible<_Vp>
5951 {
return _M_inner.base(); }
5959 {
return _Iterator<false>(*
this, _M_inner.begin()); }
5963 requires range<const _InnerView>
5964 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5965 range_reference_t<const _Vp>>
5966 {
return _Iterator<true>(*
this, _M_inner.begin()); }
5971 if constexpr (common_range<_InnerView>)
5972 return _Iterator<false>(*
this, _M_inner.end());
5974 return _Sentinel<false>(_M_inner.end());
5979 requires range<const _InnerView>
5980 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5981 range_reference_t<const _Vp>>
5983 if constexpr (common_range<const _InnerView>)
5984 return _Iterator<true>(*
this, _M_inner.end());
5986 return _Sentinel<true>(_M_inner.end());
5990 size()
requires sized_range<_InnerView>
5991 {
return _M_inner.size(); }
5994 size() const requires sized_range<const _InnerView>
5995 {
return _M_inner.size(); }
5998 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
5999 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6000 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6001 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6002 range_reference_t<_Vp>>>
6003 template<bool _Const>
6004 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
6006 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
6007 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6009 return __detail::__func_handle_t<
6010 __detail::__maybe_const_t<_Const, _Fp>,
6011 iterator_t<__detail::__maybe_const_t<(_Ids, _Const), _Vp>>...>();
6012 }(make_index_sequence<_Nm>()));
6014 [[no_unique_address]] _Fun_handle _M_fun;
6015 _InnerIter<_Const> _M_inner;
6018 _Iterator(_Fun_handle __fun, _InnerIter<_Const> __inner)
6019 : _M_fun(__fun), _M_inner(
std::
move(__inner))
6023 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
6024 : _M_fun(*__parent._M_fun), _M_inner(
std::
move(__inner))
6030 using __detail::__maybe_const_t;
6031 using __detail::__unarize;
6032 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
6033 range_reference_t<_Base>>;
6034 using _Cat =
typename iterator_traits<iterator_t<_Base>>::iterator_category;
6037 if constexpr (!is_reference_v<_Res>)
6038 return input_iterator_tag{};
6039 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
6040 return random_access_iterator_tag{};
6041 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
6042 return bidirectional_iterator_tag{};
6043 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
6044 return forward_iterator_tag{};
6046 return input_iterator_tag{};
6049 friend class adjacent_transform_view;
6052 using iterator_category =
decltype(_S_iter_cat());
6053 using iterator_concept =
typename _InnerIter<_Const>::iterator_concept;
6055 = remove_cvref_t<invoke_result_t
6056 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
6057 range_reference_t<_Base>>>;
6058 using difference_type = range_difference_t<_Base>;
6060 _Iterator() =
default;
6063 _Iterator(_Iterator<!_Const> __i)
6064 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
6065 : _M_fun(__i._M_fun), _M_inner(
std::move(__i._M_inner))
6068 constexpr decltype(
auto)
6071 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6072 return _M_fun._M_call_deref(__iters...);
6073 }, _M_inner._M_current);
6076 constexpr _Iterator&
6091 constexpr _Iterator&
6092 operator--()
requires bidirectional_range<_Base>
6099 operator--(
int)
requires bidirectional_range<_Base>
6106 constexpr _Iterator&
6107 operator+=(difference_type __x)
requires random_access_range<_Base>
6113 constexpr _Iterator&
6114 operator-=(difference_type __x)
requires random_access_range<_Base>
6120 constexpr decltype(
auto)
6121 operator[](difference_type __n)
const requires random_access_range<_Base>
6123 return std::apply([&](
const auto&... __iters) ->
decltype(
auto) {
6124 return _M_fun._M_call_subscript(__n, __iters...);
6125 }, _M_inner._M_current);
6128 friend constexpr bool
6129 operator==(
const _Iterator& __x,
const _Iterator& __y)
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 bool
6148 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6149 requires random_access_range<_Base>
6150 {
return __x._M_inner >= __y._M_inner; }
6152 friend constexpr auto
6153 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6154 requires random_access_range<_Base> &&
6155 three_way_comparable<_InnerIter<_Const>>
6156 {
return __x._M_inner <=> __y._M_inner; }
6158 friend constexpr _Iterator
6159 operator+(
const _Iterator& __i, difference_type __n)
6160 requires random_access_range<_Base>
6161 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6163 friend constexpr _Iterator
6164 operator+(difference_type __n,
const _Iterator& __i)
6165 requires random_access_range<_Base>
6166 {
return _Iterator(__i._M_fun, __i._M_inner + __n); }
6168 friend constexpr _Iterator
6169 operator-(
const _Iterator& __i, difference_type __n)
6170 requires random_access_range<_Base>
6171 {
return _Iterator(__i._M_fun, __i._M_inner - __n); }
6173 friend constexpr difference_type
6174 operator-(
const _Iterator& __x,
const _Iterator& __y)
6175 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
6176 {
return __x._M_inner - __y._M_inner; }
6179 template<forward_range _Vp, move_constructible _Fp,
size_t _Nm>
6180 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
6181 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
6182 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
6183 range_reference_t<_Vp>>>
6184 template<bool _Const>
6185 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6187 _InnerSent<_Const> _M_inner;
6190 _Sentinel(_InnerSent<_Const> __inner)
6194 friend class adjacent_transform_view;
6197 _Sentinel() =
default;
6200 _Sentinel(_Sentinel<!_Const> __i)
6201 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6205 template<
bool _OtherConst>
6206 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6207 friend constexpr bool
6208 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6209 {
return __x._M_inner == __y._M_inner; }
6211 template<
bool _OtherConst>
6212 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6213 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6214 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
6215 {
return __x._M_inner - __y._M_inner; }
6217 template<
bool _OtherConst>
6218 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6219 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6220 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
6221 {
return __x._M_inner - __y._M_inner; }
6228 template<
size_t _Nm,
typename _Range,
typename _Fp>
6229 concept __can_adjacent_transform_view
6230 =
requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6234 template<
size_t _Nm>
6235 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6237 template<viewable_range _Range,
typename _Fp>
6238 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6240 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f)
const
6242 if constexpr (_Nm == 0)
6245 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6249 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6250 static constexpr int _S_arity = 2;
6251 static constexpr bool _S_has_simple_extra_args =
true;
6254 template<
size_t _Nm>
6255 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6257 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6261#ifdef __cpp_lib_ranges_chunk
6264 template<
typename _Tp>
6265 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6267 _Tp __r = __num / __denom;
6268 if (__num % __denom)
6275 requires input_range<_Vp>
6276 class chunk_view :
public view_interface<chunk_view<_Vp>>
6279 range_difference_t<_Vp> _M_n;
6280 range_difference_t<_Vp> _M_remainder = 0;
6281 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6288 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6290 { __glibcxx_assert(__n >= 0); }
6293 base() const & requires copy_constructible<_Vp>
6300 constexpr _OuterIter
6303 _M_current = ranges::begin(_M_base);
6304 _M_remainder = _M_n;
6305 return _OuterIter(*
this);
6308 constexpr default_sentinel_t
6309 end() const noexcept
6313 size()
requires sized_range<_Vp>
6315 return __detail::__to_unsigned_like(__detail::__div_ceil
6316 (ranges::distance(_M_base), _M_n));
6320 size() const requires sized_range<const _Vp>
6322 return __detail::__to_unsigned_like(__detail::__div_ceil
6323 (ranges::distance(_M_base), _M_n));
6327 template<
typename _Range>
6328 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6331 requires input_range<_Vp>
6332 class chunk_view<_Vp>::_OuterIter
6334 chunk_view* _M_parent;
6337 _OuterIter(chunk_view& __parent) noexcept
6344 using iterator_concept = input_iterator_tag;
6345 using difference_type = range_difference_t<_Vp>;
6349 _OuterIter(_OuterIter&&) =
default;
6350 _OuterIter& operator=(_OuterIter&&) =
default;
6352 constexpr value_type
6355 __glibcxx_assert(*
this != default_sentinel);
6356 return value_type(*_M_parent);
6359 constexpr _OuterIter&
6362 __glibcxx_assert(*
this != default_sentinel);
6363 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6364 ranges::end(_M_parent->_M_base));
6365 _M_parent->_M_remainder = _M_parent->_M_n;
6373 friend constexpr bool
6374 operator==(
const _OuterIter& __x, default_sentinel_t)
6376 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6377 && __x._M_parent->_M_remainder != 0;
6380 friend constexpr difference_type
6381 operator-(default_sentinel_t,
const _OuterIter& __x)
6382 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6384 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6386 if (__dist < __x._M_parent->_M_remainder)
6387 return __dist == 0 ? 0 : 1;
6389 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6390 __x._M_parent->_M_n);
6393 friend constexpr difference_type
6394 operator-(
const _OuterIter& __x, default_sentinel_t __y)
6395 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6396 {
return -(__y - __x); }
6400 requires input_range<_Vp>
6401 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6404 chunk_view* _M_parent;
6407 value_type(chunk_view& __parent) noexcept
6414 constexpr _InnerIter
6415 begin() const noexcept
6416 {
return _InnerIter(*_M_parent); }
6418 constexpr default_sentinel_t
6419 end() const noexcept
6424 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6426 return __detail::__to_unsigned_like
6427 (ranges::min(_M_parent->_M_remainder,
6428 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6433 requires input_range<_Vp>
6434 class chunk_view<_Vp>::_InnerIter
6436 chunk_view* _M_parent;
6439 _InnerIter(chunk_view& __parent) noexcept
6443 friend _OuterIter::value_type;
6446 using iterator_concept = input_iterator_tag;
6447 using difference_type = range_difference_t<_Vp>;
6448 using value_type = range_value_t<_Vp>;
6450 _InnerIter(_InnerIter&&) =
default;
6451 _InnerIter& operator=(_InnerIter&&) =
default;
6453 constexpr const iterator_t<_Vp>&
6455 {
return *_M_parent->_M_current; }
6457 constexpr range_reference_t<_Vp>
6460 __glibcxx_assert(*
this != default_sentinel);
6461 return **_M_parent->_M_current;
6464 constexpr _InnerIter&
6467 __glibcxx_assert(*
this != default_sentinel);
6468 ++*_M_parent->_M_current;
6469 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6470 _M_parent->_M_remainder = 0;
6472 --_M_parent->_M_remainder;
6480 friend constexpr bool
6481 operator==(
const _InnerIter& __x, default_sentinel_t)
noexcept
6482 {
return __x._M_parent->_M_remainder == 0; }
6484 friend constexpr difference_type
6485 operator-(default_sentinel_t,
const _InnerIter& __x)
6486 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6488 return ranges::min(__x._M_parent->_M_remainder,
6489 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6492 friend constexpr difference_type
6493 operator-(
const _InnerIter& __x, default_sentinel_t __y)
6494 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6495 {
return -(__y - __x); }
6499 friend constexpr range_rvalue_reference_t<_Vp>
6500 iter_move(
const _InnerIter& __i)
6501 noexcept(
noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6502 {
return ranges::iter_move(*__i._M_parent->_M_current); }
6504 friend constexpr void
6505 iter_swap(
const _InnerIter& __x,
const _InnerIter& __y)
6506 noexcept(
noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6507 *__x._M_parent->_M_current)))
6508 requires indirectly_swappable<iterator_t<_Vp>>
6509 {
return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6513 requires forward_range<_Vp>
6514 class chunk_view<_Vp> :
public view_interface<chunk_view<_Vp>>
6517 range_difference_t<_Vp> _M_n;
6518 template<
bool>
class _Iterator;
6522 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6524 { __glibcxx_assert(__n > 0); }
6527 base() const & requires copy_constructible<_Vp>
6535 begin()
requires (!__detail::__simple_view<_Vp>)
6536 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
6539 begin() const requires forward_range<const _Vp>
6540 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
6543 end()
requires (!__detail::__simple_view<_Vp>)
6545 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6547 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6548 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
6550 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6551 return _Iterator<false>(
this, ranges::end(_M_base));
6557 end() const requires forward_range<const _Vp>
6559 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6561 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6562 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
6564 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6565 return _Iterator<true>(
this, ranges::end(_M_base));
6571 size()
requires sized_range<_Vp>
6573 return __detail::__to_unsigned_like(__detail::__div_ceil
6574 (ranges::distance(_M_base), _M_n));
6578 size() const requires sized_range<const _Vp>
6580 return __detail::__to_unsigned_like(__detail::__div_ceil
6581 (ranges::distance(_M_base), _M_n));
6585 template<
typename _Vp>
6586 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6587 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6590 requires forward_range<_Vp>
6591 template<
bool _Const>
6592 class chunk_view<_Vp>::_Iterator
6594 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6595 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6597 iterator_t<_Base> _M_current = iterator_t<_Base>();
6598 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6599 range_difference_t<_Base> _M_n = 0;
6600 range_difference_t<_Base> _M_missing = 0;
6603 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6604 range_difference_t<_Base> __missing = 0)
6605 : _M_current(__current), _M_end(ranges::
end(__parent->_M_base)),
6606 _M_n(__parent->_M_n), _M_missing(__missing)
6612 if constexpr (random_access_range<_Base>)
6613 return random_access_iterator_tag{};
6614 else if constexpr (bidirectional_range<_Base>)
6615 return bidirectional_iterator_tag{};
6617 return forward_iterator_tag{};
6623 using iterator_category = input_iterator_tag;
6624 using iterator_concept =
decltype(_S_iter_cat());
6625 using value_type =
decltype(views::take(subrange(_M_current, _M_end), _M_n));
6626 using difference_type = range_difference_t<_Base>;
6628 _Iterator() =
default;
6630 constexpr _Iterator(_Iterator<!_Const> __i)
6632 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6633 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6635 _M_n(__i._M_n), _M_missing(__i._M_missing)
6638 constexpr iterator_t<_Base>
6640 {
return _M_current; }
6642 constexpr value_type
6645 __glibcxx_assert(_M_current != _M_end);
6646 return views::take(subrange(_M_current, _M_end), _M_n);
6649 constexpr _Iterator&
6652 __glibcxx_assert(_M_current != _M_end);
6653 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6665 constexpr _Iterator&
6666 operator--()
requires bidirectional_range<_Base>
6668 ranges::advance(_M_current, _M_missing - _M_n);
6674 operator--(
int)
requires bidirectional_range<_Base>
6681 constexpr _Iterator&
6682 operator+=(difference_type __x)
6683 requires random_access_range<_Base>
6687 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6688 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6692 ranges::advance(_M_current, _M_n * __x + _M_missing);
6698 constexpr _Iterator&
6699 operator-=(difference_type __x)
6700 requires random_access_range<_Base>
6701 {
return *
this += -__x; }
6703 constexpr value_type
6704 operator[](difference_type __n)
const
6705 requires random_access_range<_Base>
6706 {
return *(*
this + __n); }
6708 friend constexpr bool
6709 operator==(
const _Iterator& __x,
const _Iterator& __y)
6710 {
return __x._M_current == __y._M_current; }
6712 friend constexpr bool
6713 operator==(
const _Iterator& __x, default_sentinel_t)
6714 {
return __x._M_current == __x._M_end; }
6716 friend constexpr bool
6717 operator<(
const _Iterator& __x,
const _Iterator& __y)
6718 requires random_access_range<_Base>
6719 {
return __x._M_current > __y._M_current; }
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 !(__y < __x); }
6731 friend constexpr bool
6732 operator>=(
const _Iterator& __x,
const _Iterator& __y)
6733 requires random_access_range<_Base>
6734 {
return !(__x < __y); }
6736 friend constexpr auto
6737 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
6738 requires random_access_range<_Base>
6739 && three_way_comparable<iterator_t<_Base>>
6740 {
return __x._M_current <=> __y._M_current; }
6742 friend constexpr _Iterator
6743 operator+(
const _Iterator& __i, difference_type __n)
6744 requires random_access_range<_Base>
6751 friend constexpr _Iterator
6752 operator+(difference_type __n,
const _Iterator& __i)
6753 requires random_access_range<_Base>
6760 friend constexpr _Iterator
6761 operator-(
const _Iterator& __i, difference_type __n)
6762 requires random_access_range<_Base>
6769 friend constexpr difference_type
6770 operator-(
const _Iterator& __x,
const _Iterator& __y)
6771 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6773 return (__x._M_current - __y._M_current
6774 + __x._M_missing - __y._M_missing) / __x._M_n;
6777 friend constexpr difference_type
6778 operator-(default_sentinel_t,
const _Iterator& __x)
6779 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6780 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6782 friend constexpr difference_type
6783 operator-(
const _Iterator& __x, default_sentinel_t __y)
6784 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6785 {
return -(__y - __x); }
6792 template<
typename _Range,
typename _Dp>
6793 concept __can_chunk_view
6797 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6799 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
6800 requires __detail::__can_chunk_view<_Range, _Dp>
6802 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
6805 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6806 static constexpr int _S_arity = 2;
6807 static constexpr bool _S_has_simple_extra_args =
true;
6810 inline constexpr _Chunk chunk;
6814#ifdef __cpp_lib_ranges_slide
6817 template<
typename _Vp>
6818 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6820 template<
typename _Vp>
6821 concept __slide_caches_last
6822 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6824 template<
typename _Vp>
6825 concept __slide_caches_first
6826 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6829 template<forward_range _Vp>
6831 class slide_view :
public view_interface<slide_view<_Vp>>
6834 range_difference_t<_Vp> _M_n;
6835 [[no_unique_address]]
6836 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6837 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6838 [[no_unique_address]]
6839 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6840 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6842 template<
bool>
class _Iterator;
6847 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6849 { __glibcxx_assert(__n > 0); }
6854 base() const & requires copy_constructible<_Vp>
6862 begin()
requires (!(__detail::__simple_view<_Vp>
6863 && __detail::__slide_caches_nothing<const _Vp>))
6865 if constexpr (__detail::__slide_caches_first<_Vp>)
6867 iterator_t<_Vp> __it;
6868 if (_M_cached_begin._M_has_value())
6869 __it = _M_cached_begin._M_get(_M_base);
6872 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6873 _M_cached_begin._M_set(_M_base, __it);
6875 return _Iterator<false>(ranges::begin(_M_base),
std::move(__it), _M_n);
6878 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6882 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6883 {
return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6886 end()
requires (!(__detail::__simple_view<_Vp>
6887 && __detail::__slide_caches_nothing<const _Vp>))
6889 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6890 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(
size()),
6892 else if constexpr (__detail::__slide_caches_last<_Vp>)
6894 iterator_t<_Vp> __it;
6895 if (_M_cached_end._M_has_value())
6896 __it = _M_cached_end._M_get(_M_base);
6899 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6900 _M_cached_end._M_set(_M_base, __it);
6902 return _Iterator<false>(
std::move(__it), _M_n);
6904 else if constexpr (common_range<_Vp>)
6905 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6907 return _Sentinel(ranges::end(_M_base));
6911 end() const requires __detail::__slide_caches_nothing<const _Vp>
6912 {
return begin() + range_difference_t<const _Vp>(
size()); }
6915 size()
requires sized_range<_Vp>
6917 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6920 return __detail::__to_unsigned_like(__sz);
6924 size() const requires sized_range<const _Vp>
6926 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6929 return __detail::__to_unsigned_like(__sz);
6933 template<
typename _Range>
6934 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6936 template<
typename _Vp>
6937 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6938 = enable_borrowed_range<_Vp>;
6940 template<forward_range _Vp>
6942 template<
bool _Const>
6943 class slide_view<_Vp>::_Iterator
6945 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6946 static constexpr bool _S_last_elt_present
6947 = __detail::__slide_caches_first<_Base>;
6949 iterator_t<_Base> _M_current = iterator_t<_Base>();
6950 [[no_unique_address]]
6951 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6952 _M_last_elt =
decltype(_M_last_elt)();
6953 range_difference_t<_Base> _M_n = 0;
6956 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6957 requires (!_S_last_elt_present)
6958 : _M_current(__current), _M_n(__n)
6962 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6963 range_difference_t<_Base> __n)
6964 requires _S_last_elt_present
6965 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6971 if constexpr (random_access_range<_Base>)
6972 return random_access_iterator_tag{};
6973 else if constexpr (bidirectional_range<_Base>)
6974 return bidirectional_iterator_tag{};
6976 return forward_iterator_tag{};
6980 friend slide_view::_Sentinel;
6983 using iterator_category = input_iterator_tag;
6984 using iterator_concept =
decltype(_S_iter_concept());
6985 using value_type =
decltype(views::counted(_M_current, _M_n));
6986 using difference_type = range_difference_t<_Base>;
6988 _Iterator() =
default;
6991 _Iterator(_Iterator<!_Const> __i)
6992 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6993 : _M_current(
std::move(__i._M_current)), _M_n(__i._M_n)
6998 {
return views::counted(_M_current, _M_n); }
7000 constexpr _Iterator&
7004 if constexpr (_S_last_elt_present)
7017 constexpr _Iterator&
7018 operator--()
requires bidirectional_range<_Base>
7021 if constexpr (_S_last_elt_present)
7027 operator--(
int)
requires bidirectional_range<_Base>
7034 constexpr _Iterator&
7035 operator+=(difference_type __x)
7036 requires random_access_range<_Base>
7039 if constexpr (_S_last_elt_present)
7044 constexpr _Iterator&
7045 operator-=(difference_type __x)
7046 requires random_access_range<_Base>
7049 if constexpr (_S_last_elt_present)
7055 operator[](difference_type __n)
const
7056 requires random_access_range<_Base>
7057 {
return views::counted(_M_current + __n, _M_n); }
7059 friend constexpr bool
7060 operator==(
const _Iterator& __x,
const _Iterator& __y)
7062 if constexpr (_S_last_elt_present)
7063 return __x._M_last_elt == __y._M_last_elt;
7065 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 __x._M_current < __y._M_current; }
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 !(__y < __x); }
7083 friend constexpr bool
7084 operator>=(
const _Iterator& __x,
const _Iterator& __y)
7085 requires random_access_range<_Base>
7086 {
return !(__x < __y); }
7088 friend constexpr auto
7089 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
7090 requires random_access_range<_Base>
7091 && three_way_comparable<iterator_t<_Base>>
7092 {
return __x._M_current <=> __y._M_current; }
7094 friend constexpr _Iterator
7095 operator+(
const _Iterator& __i, difference_type __n)
7096 requires random_access_range<_Base>
7103 friend constexpr _Iterator
7104 operator+(difference_type __n,
const _Iterator& __i)
7105 requires random_access_range<_Base>
7112 friend constexpr _Iterator
7113 operator-(
const _Iterator& __i, difference_type __n)
7114 requires random_access_range<_Base>
7121 friend constexpr difference_type
7122 operator-(
const _Iterator& __x,
const _Iterator& __y)
7123 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7125 if constexpr (_S_last_elt_present)
7126 return __x._M_last_elt - __y._M_last_elt;
7128 return __x._M_current - __y._M_current;
7132 template<forward_range _Vp>
7134 class slide_view<_Vp>::_Sentinel
7136 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
7139 _Sentinel(sentinel_t<_Vp> __end)
7146 _Sentinel() =
default;
7148 friend constexpr bool
7149 operator==(
const _Iterator<false>& __x,
const _Sentinel& __y)
7150 {
return __x._M_last_elt == __y._M_end; }
7152 friend constexpr range_difference_t<_Vp>
7153 operator-(
const _Iterator<false>& __x,
const _Sentinel& __y)
7154 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7155 {
return __x._M_last_elt - __y._M_end; }
7157 friend constexpr range_difference_t<_Vp>
7158 operator-(
const _Sentinel& __y,
const _Iterator<false>& __x)
7159 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
7160 {
return __y._M_end -__x._M_last_elt; }
7167 template<
typename _Range,
typename _Dp>
7168 concept __can_slide_view
7172 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
7174 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
7175 requires __detail::__can_slide_view<_Range, _Dp>
7177 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
7180 using __adaptor::_RangeAdaptor<_Slide>::operator();
7181 static constexpr int _S_arity = 2;
7182 static constexpr bool _S_has_simple_extra_args =
true;
7185 inline constexpr _Slide slide;
7189#ifdef __cpp_lib_ranges_chunk_by
7190 template<forward_range _Vp,
7191 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7192 requires view<_Vp> && is_object_v<_Pred>
7193 class chunk_by_view :
public view_interface<chunk_by_view<_Vp, _Pred>>
7195 _Vp _M_base = _Vp();
7196 __detail::__box<_Pred> _M_pred;
7197 __detail::_CachedPosition<_Vp> _M_cached_begin;
7199 constexpr iterator_t<_Vp>
7200 _M_find_next(iterator_t<_Vp> __current)
7202 __glibcxx_assert(_M_pred.has_value());
7203 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7206 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7207 return ranges::next(__it, 1, ranges::end(_M_base));
7210 constexpr iterator_t<_Vp>
7211 _M_find_prev(iterator_t<_Vp> __current)
requires bidirectional_range<_Vp>
7213 __glibcxx_assert(_M_pred.has_value());
7214 auto __pred = [
this]<
typename _Tp,
typename _Up>(_Tp&& __x, _Up&& __y) {
7219 __glibcxx_assert(__rbegin != __rend);
7220 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7221 return ranges::prev(__it, 1, ranges::begin(_M_base));
7227 chunk_by_view()
requires (default_initializable<_Vp>
7228 && default_initializable<_Pred>)
7232 chunk_by_view(_Vp __base, _Pred __pred)
7237 base() const & requires copy_constructible<_Vp>
7244 constexpr const _Pred&
7246 {
return *_M_pred; }
7251 __glibcxx_assert(_M_pred.has_value());
7252 iterator_t<_Vp> __it;
7253 if (_M_cached_begin._M_has_value())
7254 __it = _M_cached_begin._M_get(_M_base);
7257 __it = _M_find_next(ranges::begin(_M_base));
7258 _M_cached_begin._M_set(_M_base, __it);
7260 return _Iterator(*
this, ranges::begin(_M_base), __it);
7266 if constexpr (common_range<_Vp>)
7267 return _Iterator(*
this, ranges::end(_M_base), ranges::end(_M_base));
7273 template<
typename _Range,
typename _Pred>
7274 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7276 template<forward_range _Vp,
7277 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7278 requires view<_Vp> && is_object_v<_Pred>
7279 class chunk_by_view<_Vp, _Pred>::_Iterator
7281 chunk_by_view* _M_parent =
nullptr;
7282 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7283 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7286 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7287 : _M_parent(std::
__addressof(__parent)), _M_current(__current), _M_next(__next)
7293 if constexpr (bidirectional_range<_Vp>)
7294 return bidirectional_iterator_tag{};
7296 return forward_iterator_tag{};
7299 friend chunk_by_view;
7302 using value_type = subrange<iterator_t<_Vp>>;
7303 using difference_type = range_difference_t<_Vp>;
7304 using iterator_category = input_iterator_tag;
7305 using iterator_concept =
decltype(_S_iter_concept());
7307 _Iterator() =
default;
7309 constexpr value_type
7312 __glibcxx_assert(_M_current != _M_next);
7313 return ranges::subrange(_M_current, _M_next);
7316 constexpr _Iterator&
7319 __glibcxx_assert(_M_current != _M_next);
7320 _M_current = _M_next;
7321 _M_next = _M_parent->_M_find_next(_M_current);
7333 constexpr _Iterator&
7334 operator--()
requires bidirectional_range<_Vp>
7336 _M_next = _M_current;
7337 _M_current = _M_parent->_M_find_prev(_M_next);
7342 operator--(
int)
requires bidirectional_range<_Vp>
7349 friend constexpr bool
7350 operator==(
const _Iterator& __x,
const _Iterator& __y)
7351 {
return __x._M_current == __y._M_current; }
7353 friend constexpr bool
7354 operator==(
const _Iterator& __x, default_sentinel_t)
7355 {
return __x._M_current == __x._M_next; }
7362 template<
typename _Range,
typename _Pred>
7363 concept __can_chunk_by_view
7367 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7369 template<viewable_range _Range,
typename _Pred>
7370 requires __detail::__can_chunk_by_view<_Range, _Pred>
7372 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred)
const
7375 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7376 static constexpr int _S_arity = 2;
7377 static constexpr bool _S_has_simple_extra_args =
true;
7380 inline constexpr _ChunkBy chunk_by;
7384#ifdef __cpp_lib_ranges_join_with
7387 template<
typename _Range,
typename _Pattern>
7388 concept __compatible_joinable_ranges
7389 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7390 && common_reference_with<range_reference_t<_Range>,
7391 range_reference_t<_Pattern>>
7392 && common_reference_with<range_rvalue_reference_t<_Range>,
7393 range_rvalue_reference_t<_Pattern>>;
7395 template<
typename _Range>
7396 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7399 template<input_range _Vp, forward_range _Pattern>
7400 requires view<_Vp> && view<_Pattern>
7401 && input_range<range_reference_t<_Vp>>
7402 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7403 class join_with_view :
public view_interface<join_with_view<_Vp, _Pattern>>
7405 using _InnerRange = range_reference_t<_Vp>;
7407 _Vp _M_base = _Vp();
7408 [[no_unique_address]]
7409 __detail::__maybe_present_t<!forward_range<_Vp>,
7410 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7411 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7412 _Pattern _M_pattern = _Pattern();
7414 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7415 template<
bool _Const>
using _InnerBase = range_reference_t<_Base<_Const>>;
7416 template<
bool _Const>
using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7418 template<
bool _Const>
using _OuterIter = iterator_t<_Base<_Const>>;
7419 template<
bool _Const>
using _InnerIter = iterator_t<_InnerBase<_Const>>;
7420 template<
bool _Const>
using _PatternIter = iterator_t<_PatternBase<_Const>>;
7422 template<
bool _Const>
7423 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7425 template<
bool _Const>
7429 template<
bool _Const>
7430 requires _S_ref_is_glvalue<_Const>
7431 && forward_range<_Base<_Const>>
7432 && forward_range<_InnerBase<_Const>>
7433 struct __iter_cat<_Const>
7439 using _OuterIter = join_with_view::_OuterIter<_Const>;
7440 using _InnerIter = join_with_view::_InnerIter<_Const>;
7441 using _PatternIter = join_with_view::_PatternIter<_Const>;
7442 using _OuterCat =
typename iterator_traits<_OuterIter>::iterator_category;
7443 using _InnerCat =
typename iterator_traits<_InnerIter>::iterator_category;
7444 using _PatternCat =
typename iterator_traits<_PatternIter>::iterator_category;
7447 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7448 iter_reference_t<_PatternIter>>>)
7449 return input_iterator_tag{};
7450 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7451 && derived_from<_InnerCat, bidirectional_iterator_tag>
7452 && derived_from<_PatternCat, bidirectional_iterator_tag>
7453 && common_range<_InnerBase<_Const>>
7454 && common_range<_PatternBase<_Const>>)
7455 return bidirectional_iterator_tag{};
7456 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7457 && derived_from<_InnerCat, forward_iterator_tag>
7458 && derived_from<_PatternCat, forward_iterator_tag>)
7459 return forward_iterator_tag{};
7461 return input_iterator_tag{};
7464 using iterator_category =
decltype(_S_iter_cat());
7467 template<
bool>
class _Iterator;
7468 template<
bool>
class _Sentinel;
7471 join_with_view()
requires (default_initializable<_Vp>
7472 && default_initializable<_Pattern>)
7476 join_with_view(_Vp __base, _Pattern __pattern)
7480 template<input_range _Range>
7481 requires constructible_from<_Vp, views::all_t<_Range>>
7482 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7484 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7485 : _M_base(views::all(std::
forward<_Range>(__r))),
7486 _M_pattern(views::single(std::
move(__e)))
7490 base() const& requires copy_constructible<_Vp>
7500 if constexpr (forward_range<_Vp>)
7502 constexpr bool __use_const = is_reference_v<_InnerRange>
7503 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7504 return _Iterator<__use_const>{*
this, ranges::begin(_M_base)};
7508 _M_outer_it = ranges::begin(_M_base);
7509 return _Iterator<false>{*
this};
7515 requires forward_range<const _Vp>
7516 && forward_range<const _Pattern>
7517 && is_reference_v<range_reference_t<const _Vp>>
7518 && input_range<range_reference_t<const _Vp>>
7519 {
return _Iterator<true>{*
this, ranges::begin(_M_base)}; }
7524 constexpr bool __use_const
7525 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7526 if constexpr (is_reference_v<_InnerRange>
7527 && forward_range<_Vp> && common_range<_Vp>
7528 && forward_range<_InnerRange> && common_range<_InnerRange>)
7529 return _Iterator<__use_const>{*
this, ranges::end(_M_base)};
7531 return _Sentinel<__use_const>{*
this};
7536 requires forward_range<const _Vp>
7537 && forward_range<const _Pattern>
7538 && is_reference_v<range_reference_t<const _Vp>>
7539 && input_range<range_reference_t<const _Vp>>
7541 using _InnerConstRange = range_reference_t<const _Vp>;
7542 if constexpr (forward_range<_InnerConstRange>
7543 && common_range<const _Vp>
7544 && common_range<_InnerConstRange>)
7545 return _Iterator<true>{*
this, ranges::end(_M_base)};
7547 return _Sentinel<true>{*
this};
7551 template<
typename _Range,
typename _Pattern>
7552 join_with_view(_Range&&, _Pattern&&)
7553 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7555 template<input_range _Range>
7556 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7557 -> join_with_view<views::all_t<_Range>,
7558 single_view<range_value_t<range_reference_t<_Range>>>>;
7560 template<input_range _Vp, forward_range _Pattern>
7561 requires view<_Vp> && view<_Pattern>
7562 && input_range<range_reference_t<_Vp>>
7563 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7564 template<
bool _Const>
7565 class join_with_view<_Vp, _Pattern>::_Iterator :
public __iter_cat<_Const>
7567 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7568 using _Base = join_with_view::_Base<_Const>;
7569 using _InnerBase = join_with_view::_InnerBase<_Const>;
7570 using _PatternBase = join_with_view::_PatternBase<_Const>;
7572 using _OuterIter = join_with_view::_OuterIter<_Const>;
7573 using _InnerIter = join_with_view::_InnerIter<_Const>;
7574 using _PatternIter = join_with_view::_PatternIter<_Const>;
7576 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7578 _Parent* _M_parent =
nullptr;
7579 [[no_unique_address]]
7580 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it
7581 =
decltype(_M_outer_it)();
7582 variant<_PatternIter, _InnerIter> _M_inner_it;
7584 constexpr _OuterIter&
7587 if constexpr (forward_range<_Base>)
7590 return *_M_parent->_M_outer_it;
7593 constexpr const _OuterIter&
7594 _M_get_outer()
const
7596 if constexpr (forward_range<_Base>)
7599 return *_M_parent->_M_outer_it;
7603 _Iterator(_Parent& __parent, _OuterIter __outer)
7604 requires forward_range<_Base>
7607 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7609 auto&& __inner = _M_update_inner();
7610 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7616 _Iterator(_Parent& __parent)
7617 requires (!forward_range<_Base>)
7620 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7622 auto&& __inner = _M_update_inner();
7623 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7631 _OuterIter& __outer = _M_get_outer();
7632 if constexpr (_S_ref_is_glvalue)
7633 return __detail::__as_lvalue(*__outer);
7635 return _M_parent->_M_inner._M_emplace_deref(__outer);
7641 if constexpr (_S_ref_is_glvalue)
7642 return __detail::__as_lvalue(*_M_get_outer());
7644 return *_M_parent->_M_inner;
7652 if (_M_inner_it.index() == 0)
7654 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7657 auto&& __inner = _M_update_inner();
7658 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7662 auto&& __inner = _M_get_inner();
7663 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7666 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7668 if constexpr (_S_ref_is_glvalue)
7669 _M_inner_it.template emplace<0>();
7673 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7681 if constexpr (_S_ref_is_glvalue
7682 && bidirectional_range<_Base>
7683 && __detail::__bidirectional_common<_InnerBase>
7684 && __detail::__bidirectional_common<_PatternBase>)
7685 return bidirectional_iterator_tag{};
7686 else if constexpr (_S_ref_is_glvalue
7687 && forward_range<_Base>
7688 && forward_range<_InnerBase>)
7689 return forward_iterator_tag{};
7691 return input_iterator_tag{};
7694 friend join_with_view;
7697 using iterator_concept =
decltype(_S_iter_concept());
7699 using value_type = common_type_t<iter_value_t<_InnerIter>,
7700 iter_value_t<_PatternIter>>;
7701 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7702 iter_difference_t<_InnerIter>,
7703 iter_difference_t<_PatternIter>>;
7705 _Iterator() =
default;
7708 _Iterator(_Iterator<!_Const> __i)
7710 && convertible_to<iterator_t<_Vp>, _OuterIter>
7711 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7712 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7713 : _M_parent(__i._M_parent),
7716 if (__i._M_inner_it.index() == 0)
7717 _M_inner_it.template emplace<0>(std::get<0>(
std::move(__i._M_inner_it)));
7719 _M_inner_it.template emplace<1>(std::get<1>(
std::move(__i._M_inner_it)));
7722 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7723 iter_reference_t<_PatternIter>>
7726 if (_M_inner_it.index() == 0)
7727 return *std::get<0>(_M_inner_it);
7729 return *std::get<1>(_M_inner_it);
7732 constexpr _Iterator&
7735 if (_M_inner_it.index() == 0)
7736 ++std::get<0>(_M_inner_it);
7738 ++std::get<1>(_M_inner_it);
7749 requires _S_ref_is_glvalue
7750 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7752 _Iterator __tmp = *
this;
7757 constexpr _Iterator&
7759 requires _S_ref_is_glvalue
7760 && bidirectional_range<_Base>
7761 && __detail::__bidirectional_common<_InnerBase>
7762 && __detail::__bidirectional_common<_PatternBase>
7764 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7766 auto&& __inner = *--_M_outer_it;
7767 _M_inner_it.template emplace<1>(ranges::end(__inner));
7772 if (_M_inner_it.index() == 0)
7774 auto& __it = std::get<0>(_M_inner_it);
7775 if (__it == ranges::begin(_M_parent->_M_pattern))
7777 auto&& __inner = *--_M_outer_it;
7778 _M_inner_it.template emplace<1>(ranges::end(__inner));
7785 auto& __it = std::get<1>(_M_inner_it);
7786 auto&& __inner = *_M_outer_it;
7787 if (__it == ranges::begin(__inner))
7788 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7794 if (_M_inner_it.index() == 0)
7795 --std::get<0>(_M_inner_it);
7797 --std::get<1>(_M_inner_it);
7803 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7804 && __detail::__bidirectional_common<_InnerBase>
7805 && __detail::__bidirectional_common<_PatternBase>
7807 _Iterator __tmp = *
this;
7812 friend constexpr bool
7813 operator==(
const _Iterator& __x,
const _Iterator& __y)
7814 requires _S_ref_is_glvalue
7815 && forward_range<_Base> && equality_comparable<_InnerIter>
7816 {
return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7818 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7819 iter_rvalue_reference_t<_PatternIter>>
7820 iter_move(
const _Iterator& __x)
7822 if (__x._M_inner_it.index() == 0)
7823 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7825 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7828 friend constexpr void
7829 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
7830 requires indirectly_swappable<_InnerIter, _PatternIter>
7832 if (__x._M_inner_it.index() == 0)
7834 if (__y._M_inner_it.index() == 0)
7835 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7837 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7841 if (__y._M_inner_it.index() == 0)
7842 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7844 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7849 template<input_range _Vp, forward_range _Pattern>
7850 requires view<_Vp> && view<_Pattern>
7851 && input_range<range_reference_t<_Vp>>
7852 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7853 template<
bool _Const>
7854 class join_with_view<_Vp, _Pattern>::_Sentinel
7856 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7857 using _Base = join_with_view::_Base<_Const>;
7859 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7862 _Sentinel(_Parent& __parent)
7863 : _M_end(ranges::
end(__parent._M_base))
7866 friend join_with_view;
7869 _Sentinel() =
default;
7872 _Sentinel(_Sentinel<!_Const> __s)
7873 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7877 template<
bool _OtherConst>
7878 requires sentinel_for<sentinel_t<_Base>,
7879 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7880 friend constexpr bool
7881 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
7882 {
return __x._M_get_outer() == __y._M_end; }
7889 template<
typename _Range,
typename _Pattern>
7890 concept __can_join_with_view
7894 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7896 template<viewable_range _Range,
typename _Pattern>
7897 requires __detail::__can_join_with_view<_Range, _Pattern>
7899 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f)
const
7904 using _RangeAdaptor<_JoinWith>::operator();
7905 static constexpr int _S_arity = 2;
7906 template<
typename _Pattern>
7907 static constexpr bool _S_has_simple_extra_args
7908 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7911 inline constexpr _JoinWith join_with;
7915#ifdef __cpp_lib_ranges_repeat
7916 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7917 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7918 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7919 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7921 __detail::__box<_Tp> _M_value;
7922 [[no_unique_address]] _Bound _M_bound = _Bound();
7926 template<
typename _Range>
7927 friend constexpr auto
7928 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7930 template<
typename _Range>
7931 friend constexpr auto
7932 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7935 repeat_view()
requires default_initializable<_Tp> = default;
7938 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7939 requires copy_constructible<_Tp>
7940 : _M_value(__value), _M_bound(__bound)
7942 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7943 __glibcxx_assert(__bound >= 0);
7947 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7948 : _M_value(
std::
move(__value)), _M_bound(__bound)
7951 template<
typename... _Args,
typename... _BoundArgs>
7952 requires constructible_from<_Tp, _Args...>
7953 && constructible_from<_Bound, _BoundArgs...>
7955 repeat_view(piecewise_construct_t,
7956 tuple<_Args...> __args,
7957 tuple<_BoundArgs...> __bound_args = tuple<>{})
7958 : _M_value(
std::make_from_tuple<_Tp>(
std::
move(__args))),
7959 _M_bound(
std::make_from_tuple<_Bound>(
std::
move(__bound_args)))
7967 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7970 constexpr unreachable_sentinel_t
7971 end() const noexcept
7972 {
return unreachable_sentinel; }
7975 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7976 {
return __detail::__to_unsigned_like(_M_bound); }
7981 template<
typename _Tp,
typename _Bound = unreachable_sentinel_t>
7982 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7984 template<move_constructible _Tp, semiregular _Bound>
7985 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7986 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7987 class repeat_view<_Tp, _Bound>::_Iterator
7990 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7992 const _Tp* _M_value =
nullptr;
7993 __index_type _M_current = __index_type();
7996 _Iterator(
const _Tp* __value, __index_type __bound = __index_type())
7997 : _M_value(__value), _M_current(__bound)
7999 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8000 __glibcxx_assert(__bound >= 0);
8006 using iterator_concept = random_access_iterator_tag;
8007 using iterator_category = random_access_iterator_tag;
8008 using value_type = _Tp;
8009 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
8011 __detail::__iota_diff_t<__index_type>>;
8013 _Iterator() =
default;
8015 constexpr const _Tp&
8017 {
return *_M_value; }
8019 constexpr _Iterator&
8034 constexpr _Iterator&
8037 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8038 __glibcxx_assert(_M_current > 0);
8051 constexpr _Iterator&
8052 operator+=(difference_type __n)
8054 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8055 __glibcxx_assert(_M_current + __n >= 0);
8060 constexpr _Iterator&
8061 operator-=(difference_type __n)
8063 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
8064 __glibcxx_assert(_M_current - __n >= 0);
8069 constexpr const _Tp&
8070 operator[](difference_type __n)
const noexcept
8071 {
return *(*
this + __n); }
8073 friend constexpr bool
8074 operator==(
const _Iterator& __x,
const _Iterator& __y)
8075 {
return __x._M_current == __y._M_current; }
8077 friend constexpr auto
8078 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8079 {
return __x._M_current <=> __y._M_current; }
8081 friend constexpr _Iterator
8082 operator+(_Iterator __i, difference_type __n)
8088 friend constexpr _Iterator
8089 operator+(difference_type __n, _Iterator __i)
8090 {
return __i + __n; }
8092 friend constexpr _Iterator
8093 operator-(_Iterator __i, difference_type __n)
8099 friend constexpr difference_type
8100 operator-(
const _Iterator& __x,
const _Iterator& __y)
8102 return (
static_cast<difference_type
>(__x._M_current)
8103 -
static_cast<difference_type
>(__y._M_current));
8111 template<
typename _Tp,
typename _Bound>
8112 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> =
true;
8114 template<
typename _Tp>
8115 concept __can_repeat_view
8118 template<
typename _Tp,
typename _Bound>
8119 concept __can_bounded_repeat_view
8125 template<
typename _Tp>
8126 requires __detail::__can_repeat_view<_Tp>
8128 operator() [[nodiscard]] (_Tp&& __value)
const
8135 template<
typename _Tp,
typename _Bound>
8136 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
8138 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound)
const
8142 inline constexpr _Repeat repeat;
8146 template<
typename _Range>
8148 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8150 using _Tp = remove_cvref_t<_Range>;
8151 static_assert(__is_repeat_view<_Tp>);
8152 if constexpr (sized_range<_Tp>)
8154 std::min(ranges::distance(__r), __n));
8159 template<
typename _Range>
8161 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
8163 using _Tp = remove_cvref_t<_Range>;
8164 static_assert(__is_repeat_view<_Tp>);
8165 if constexpr (sized_range<_Tp>)
8167 auto __sz = ranges::distance(__r);
8178#ifdef __cpp_lib_ranges_stride
8179 template<input_range _Vp>
8181 class stride_view :
public view_interface<stride_view<_Vp>>
8184 range_difference_t<_Vp> _M_stride;
8186 template<
bool _Const>
using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8188 template<
bool _Const>
8192 template<
bool _Const>
8193 requires forward_range<_Base<_Const>>
8194 struct __iter_cat<_Const>
8200 using _Cat =
typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8201 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8202 return random_access_iterator_tag{};
8207 using iterator_category =
decltype(_S_iter_cat());
8210 template<
bool>
class _Iterator;
8214 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8215 : _M_base(std::
move(
__base)), _M_stride(__stride)
8216 { __glibcxx_assert(__stride > 0); }
8219 base() const& requires copy_constructible<_Vp>
8226 constexpr range_difference_t<_Vp>
8227 stride() const noexcept
8228 {
return _M_stride; }
8231 begin()
requires (!__detail::__simple_view<_Vp>)
8232 {
return _Iterator<false>(
this, ranges::begin(_M_base)); }
8235 begin() const requires range<const _Vp>
8236 {
return _Iterator<true>(
this, ranges::begin(_M_base)); }
8239 end()
requires (!__detail::__simple_view<_Vp>)
8241 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8243 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8244 return _Iterator<false>(
this, ranges::end(_M_base), __missing);
8246 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8247 return _Iterator<false>(
this, ranges::end(_M_base));
8253 end() const requires range<const _Vp>
8255 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8256 && forward_range<const _Vp>)
8258 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8259 return _Iterator<true>(
this, ranges::end(_M_base), __missing);
8261 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8262 return _Iterator<true>(
this, ranges::end(_M_base));
8268 size()
requires sized_range<_Vp>
8270 return __detail::__to_unsigned_like
8271 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8275 size() const requires sized_range<const _Vp>
8277 return __detail::__to_unsigned_like
8278 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8282 template<
typename _Range>
8283 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8285 template<
typename _Vp>
8286 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8287 = enable_borrowed_range<_Vp>;
8289 template<input_range _Vp>
8291 template<
bool _Const>
8292 class stride_view<_Vp>::_Iterator :
public __iter_cat<_Const>
8294 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8295 using _Base = stride_view::_Base<_Const>;
8297 iterator_t<_Base> _M_current = iterator_t<_Base>();
8298 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8299 range_difference_t<_Base> _M_stride = 0;
8300 range_difference_t<_Base> _M_missing = 0;
8303 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8304 range_difference_t<_Base> __missing = 0)
8305 : _M_current(std::
move(__current)), _M_end(ranges::
end(__parent->_M_base)),
8306 _M_stride(__parent->_M_stride), _M_missing(__missing)
8312 if constexpr (random_access_range<_Base>)
8313 return random_access_iterator_tag{};
8314 else if constexpr (bidirectional_range<_Base>)
8315 return bidirectional_iterator_tag{};
8316 else if constexpr (forward_range<_Base>)
8317 return forward_iterator_tag{};
8319 return input_iterator_tag{};
8325 using difference_type = range_difference_t<_Base>;
8326 using value_type = range_value_t<_Base>;
8327 using iterator_concept =
decltype(_S_iter_concept());
8330 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
8333 _Iterator(_Iterator<!_Const> __other)
8335 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8336 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8337 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8338 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8341 constexpr iterator_t<_Base>
8345 constexpr const iterator_t<_Base>&
8346 base() const & noexcept
8347 {
return _M_current; }
8349 constexpr decltype(
auto)
8351 {
return *_M_current; }
8353 constexpr _Iterator&
8356 __glibcxx_assert(_M_current != _M_end);
8357 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8366 operator++(
int)
requires forward_range<_Base>
8373 constexpr _Iterator&
8374 operator--()
requires bidirectional_range<_Base>
8376 ranges::advance(_M_current, _M_missing - _M_stride);
8382 operator--(
int)
requires bidirectional_range<_Base>
8389 constexpr _Iterator&
8390 operator+=(difference_type __n)
requires random_access_range<_Base>
8394 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8395 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8399 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8405 constexpr _Iterator&
8406 operator-=(difference_type __n)
requires random_access_range<_Base>
8407 {
return *
this += -__n; }
8409 constexpr decltype(
auto)
operator[](difference_type __n)
const
8410 requires random_access_range<_Base>
8411 {
return *(*
this + __n); }
8413 friend constexpr bool
8414 operator==(
const _Iterator& __x, default_sentinel_t)
8415 {
return __x._M_current == __x._M_end; }
8417 friend constexpr bool
8418 operator==(
const _Iterator& __x,
const _Iterator& __y)
8419 requires equality_comparable<iterator_t<_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 __x._M_current < __y._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 !(__y._M_current < __x._M_current); }
8437 friend constexpr bool
8438 operator>=(
const _Iterator& __x,
const _Iterator& __y)
8439 requires random_access_range<_Base>
8440 {
return !(__x._M_current < __y._M_current); }
8442 friend constexpr auto
8443 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8444 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8445 {
return __x._M_current <=> __y._M_current; }
8447 friend constexpr _Iterator
8448 operator+(
const _Iterator& __i, difference_type __n)
8449 requires random_access_range<_Base>
8456 friend constexpr _Iterator
8457 operator+(difference_type __n,
const _Iterator& __i)
8458 requires random_access_range<_Base>
8459 {
return __i + __n; }
8461 friend constexpr _Iterator
8462 operator-(
const _Iterator& __i, difference_type __n)
8463 requires random_access_range<_Base>
8470 friend constexpr difference_type
8471 operator-(
const _Iterator& __x,
const _Iterator& __y)
8472 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8474 auto __n = __x._M_current - __y._M_current;
8475 if constexpr (forward_range<_Base>)
8476 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8478 return -__detail::__div_ceil(-__n, __x._M_stride);
8480 return __detail::__div_ceil(__n, __x._M_stride);
8483 friend constexpr difference_type
8484 operator-(default_sentinel_t,
const _Iterator& __x)
8485 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8486 {
return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8488 friend constexpr difference_type
8489 operator-(
const _Iterator& __x, default_sentinel_t __y)
8490 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8491 {
return -(__y - __x); }
8493 friend constexpr range_rvalue_reference_t<_Base>
8494 iter_move(
const _Iterator& __i)
8495 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
8496 {
return ranges::iter_move(__i._M_current); }
8498 friend constexpr void
8499 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
8500 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8501 requires indirectly_swappable<iterator_t<_Base>>
8502 { ranges::iter_swap(__x._M_current, __y._M_current); }
8509 template<
typename _Range,
typename _Dp>
8510 concept __can_stride_view
8514 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8516 template<viewable_range _Range,
typename _Dp = range_difference_t<_Range>>
8517 requires __detail::__can_stride_view<_Range, _Dp>
8519 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n)
const
8522 using __adaptor::_RangeAdaptor<_Stride>::operator();
8523 static constexpr int _S_arity = 2;
8524 static constexpr bool _S_has_simple_extra_args =
true;
8527 inline constexpr _Stride stride;
8531#ifdef __cpp_lib_ranges_cartesian_product
8534 template<
bool _Const,
typename _First,
typename... _Vs>
8535 concept __cartesian_product_is_random_access
8536 = (random_access_range<__maybe_const_t<_Const, _First>>
8538 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8539 && sized_range<__maybe_const_t<_Const, _Vs>>));
8541 template<
typename _Range>
8542 concept __cartesian_product_common_arg
8543 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8545 template<
bool _Const,
typename _First,
typename... _Vs>
8546 concept __cartesian_product_is_bidirectional
8547 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8549 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8550 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8552 template<
typename _First,
typename... _Vs>
8553 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8555 template<
typename... _Vs>
8556 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8558 template<
bool _Const,
template<
typename>
class FirstSent,
typename _First,
typename... _Vs>
8559 concept __cartesian_is_sized_sentinel
8560 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8561 iterator_t<__maybe_const_t<_Const, _First>>>
8563 && (sized_range<__maybe_const_t<_Const, _Vs>>
8564 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8565 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8567 template<__cartesian_product_common_arg _Range>
8569 __cartesian_common_arg_end(_Range& __r)
8571 if constexpr (common_range<_Range>)
8572 return ranges::end(__r);
8574 return ranges::begin(__r) + ranges::distance(__r);
8578 template<input_range _First, forward_range... _Vs>
8579 requires (view<_First> && ... && view<_Vs>)
8580 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8582 tuple<_First, _Vs...> _M_bases;
8584 template<
bool>
class _Iterator;
8587 _S_difference_type()
8593 range_difference_t<_First>,
8594 range_difference_t<_Vs>...>{};
8598 cartesian_product_view() =
default;
8601 cartesian_product_view(_First __first, _Vs... __rest)
8605 constexpr _Iterator<false>
8606 begin()
requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8607 {
return _Iterator<false>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8609 constexpr _Iterator<true>
8610 begin() const requires (range<const _First> && ... && range<const _Vs>)
8611 {
return _Iterator<true>(*
this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8613 constexpr _Iterator<false>
8614 end()
requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8615 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8618 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8619 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8620 auto& __first = std::get<0>(_M_bases);
8621 return _Ret{(__empty_tail
8622 ? ranges::begin(__first)
8623 : __detail::__cartesian_common_arg_end(__first)),
8624 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8627 return _Iterator<false>{*
this,
std::move(__its)};
8630 constexpr _Iterator<true>
8631 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8634 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8635 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8636 auto& __first = std::get<0>(_M_bases);
8637 return _Ret{(__empty_tail
8638 ? ranges::begin(__first)
8639 : __detail::__cartesian_common_arg_end(__first)),
8640 ranges::
begin(
std::get<1 + _Is>(_M_bases))...};
8643 return _Iterator<true>{*
this,
std::move(__its)};
8646 constexpr default_sentinel_t
8647 end() const noexcept
8651 size()
requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8653 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8655 auto __size =
static_cast<_ST
>(1);
8656#ifdef _GLIBCXX_ASSERTIONS
8657 if constexpr (integral<_ST>)
8660 = (__builtin_mul_overflow(__size,
8661 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8664 __glibcxx_assert(!__overflow);
8668 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8674 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8676 using _ST = __detail::__make_unsigned_like_t<
decltype(_S_difference_type())>;
8678 auto __size =
static_cast<_ST
>(1);
8679#ifdef _GLIBCXX_ASSERTIONS
8680 if constexpr (integral<_ST>)
8683 = (__builtin_mul_overflow(__size,
8684 static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))),
8687 __glibcxx_assert(!__overflow);
8691 __size = (
static_cast<_ST
>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8697 template<
typename... _Vs>
8698 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8700 template<input_range _First, forward_range... _Vs>
8701 requires (view<_First> && ... && view<_Vs>)
8702 template<bool _Const>
8703 class cartesian_product_view<_First, _Vs...>::_Iterator
8705 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8706 _Parent* _M_parent =
nullptr;
8707 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8708 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8711 _Iterator(_Parent& __parent,
decltype(_M_current) __current)
8713 _M_current(
std::
move(__current))
8719 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8720 return random_access_iterator_tag{};
8721 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8722 return bidirectional_iterator_tag{};
8723 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8724 return forward_iterator_tag{};
8726 return input_iterator_tag{};
8729 friend cartesian_product_view;
8732 using iterator_category = input_iterator_tag;
8733 using iterator_concept =
decltype(_S_iter_concept());
8735 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8736 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8738 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8739 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8740 using difference_type =
decltype(cartesian_product_view::_S_difference_type());
8742 _Iterator() =
default;
8745 _Iterator(_Iterator<!_Const> __i)
8747 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8748 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8750 _M_current(
std::
move(__i._M_current))
8756 auto __f = [](
auto& __i) ->
decltype(
auto) {
8759 return __detail::__tuple_transform(__f, _M_current);
8762 constexpr _Iterator&
8774 operator++(
int)
requires forward_range<__maybe_const_t<_Const, _First>>
8781 constexpr _Iterator&
8783 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8791 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8798 constexpr _Iterator&
8799 operator+=(difference_type __x)
8800 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8806 constexpr _Iterator&
8807 operator-=(difference_type __x)
8808 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8809 {
return *
this += -__x; }
8812 operator[](difference_type __n)
const
8813 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8814 {
return *((*this) + __n); }
8816 friend constexpr bool
8817 operator==(
const _Iterator& __x,
const _Iterator& __y)
8818 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8819 {
return __x._M_current == __y._M_current; }
8821 friend constexpr bool
8822 operator==(
const _Iterator& __x, default_sentinel_t)
8825 return ((std::get<_Is>(__x._M_current)
8826 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8831 friend constexpr auto
8832 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
8833 requires __detail::__all_random_access<_Const, _First, _Vs...>
8834 {
return __x._M_current <=> __y._M_current; }
8836 friend constexpr _Iterator
8837 operator+(_Iterator __x, difference_type __y)
8838 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8839 {
return __x += __y; }
8841 friend constexpr _Iterator
8842 operator+(difference_type __x, _Iterator __y)
8843 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8844 {
return __y += __x; }
8846 friend constexpr _Iterator
8847 operator-(_Iterator __x, difference_type __y)
8848 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8849 {
return __x -= __y; }
8851 friend constexpr difference_type
8852 operator-(
const _Iterator& __x,
const _Iterator& __y)
8853 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8854 {
return __x._M_distance_from(__y._M_current); }
8856 friend constexpr difference_type
8857 operator-(
const _Iterator& __i, default_sentinel_t)
8858 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8861 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8862 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8864 return __i._M_distance_from(__end_tuple);
8867 friend constexpr difference_type
8868 operator-(default_sentinel_t,
const _Iterator& __i)
8869 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8872 friend constexpr auto
8873 iter_move(
const _Iterator& __i)
8874 {
return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8876 friend constexpr void
8877 iter_swap(
const _Iterator& __l,
const _Iterator& __r)
8878 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8880 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8883 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8888 template<
size_t _Nm =
sizeof...(_Vs)>
8892 auto& __it = std::get<_Nm>(_M_current);
8894 if constexpr (_Nm > 0)
8895 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8897 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8902 template<
size_t _Nm =
sizeof...(_Vs)>
8906 auto& __it = std::get<_Nm>(_M_current);
8907 if constexpr (_Nm > 0)
8908 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8910 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8916 template<
size_t _Nm =
sizeof...(_Vs)>
8918 _M_advance(difference_type __x)
8919 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8928 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8929 auto& __it = std::get<_Nm>(_M_current);
8930 if constexpr (_Nm == 0)
8932#ifdef _GLIBCXX_ASSERTIONS
8933 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8935 auto __size = ranges::ssize(__r);
8936 auto __begin = ranges::begin(__r);
8937 auto __offset = __it - __begin;
8938 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8945 auto __size = ranges::ssize(__r);
8946 auto __begin = ranges::begin(__r);
8947 auto __offset = __it - __begin;
8949 __x = __offset / __size;
8953 __offset = __size + __offset;
8956 __it = __begin + __offset;
8957 _M_advance<_Nm - 1>(__x);
8962 template<
typename _Tuple>
8963 constexpr difference_type
8964 _M_distance_from(
const _Tuple& __t)
const
8967 auto __sum =
static_cast<difference_type
>(0);
8968#ifdef _GLIBCXX_ASSERTIONS
8969 if constexpr (integral<difference_type>)
8972 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8974 __glibcxx_assert(!__overflow);
8978 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8983 template<
size_t _Nm,
typename _Tuple>
8984 constexpr difference_type
8985 _M_scaled_distance(
const _Tuple& __t)
const
8987 auto __dist =
static_cast<difference_type
>(std::get<_Nm>(_M_current)
8988 - std::get<_Nm>(__t));
8989#ifdef _GLIBCXX_ASSERTIONS
8990 if constexpr (integral<difference_type>)
8992 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8993 __glibcxx_assert(!__overflow);
8997 __dist *= _M_scaled_size<_Nm+1>();
9001 template<
size_t _Nm>
9002 constexpr difference_type
9003 _M_scaled_size()
const
9005 if constexpr (_Nm <=
sizeof...(_Vs))
9007 auto __size =
static_cast<difference_type
>(ranges::size
9008 (std::get<_Nm>(_M_parent->_M_bases)));
9009#ifdef _GLIBCXX_ASSERTIONS
9010 if constexpr (integral<difference_type>)
9012 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
9013 __glibcxx_assert(!__overflow);
9017 __size *= _M_scaled_size<_Nm+1>();
9021 return static_cast<difference_type
>(1);
9029 template<
typename... _Ts>
9030 concept __can_cartesian_product_view
9034 struct _CartesianProduct
9036 template<
typename... _Ts>
9037 requires (
sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
9039 operator() [[nodiscard]] (_Ts&&... __ts)
const
9041 if constexpr (
sizeof...(_Ts) == 0)
9042 return views::single(tuple{});
9048 inline constexpr _CartesianProduct cartesian_product;
9052#ifdef __cpp_lib_ranges_as_rvalue
9053 template<input_range _Vp>
9055 class as_rvalue_view :
public view_interface<as_rvalue_view<_Vp>>
9057 _Vp _M_base = _Vp();
9060 as_rvalue_view()
requires default_initializable<_Vp> = default;
9063 as_rvalue_view(_Vp __base)
9064 : _M_base(std::move(__base))
9068 base() const& requires copy_constructible<_Vp>
9076 begin()
requires (!__detail::__simple_view<_Vp>)
9077 {
return move_iterator(ranges::begin(_M_base)); }
9080 begin() const requires range<const _Vp>
9081 {
return move_iterator(ranges::begin(_M_base)); }
9084 end()
requires (!__detail::__simple_view<_Vp>)
9086 if constexpr (common_range<_Vp>)
9087 return move_iterator(ranges::end(_M_base));
9089 return move_sentinel(ranges::end(_M_base));
9093 end() const requires range<const _Vp>
9095 if constexpr (common_range<const _Vp>)
9096 return move_iterator(ranges::end(_M_base));
9098 return move_sentinel(ranges::end(_M_base));
9102 size()
requires sized_range<_Vp>
9103 {
return ranges::size(_M_base); }
9106 size() const requires sized_range<const _Vp>
9107 {
return ranges::size(_M_base); }
9110 template<
typename _Range>
9111 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
9113 template<
typename _Tp>
9114 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
9115 = enable_borrowed_range<_Tp>;
9121 template<
typename _Tp>
9122 concept __can_as_rvalue_view =
requires { as_rvalue_view(
std::declval<_Tp>()); };
9125 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
9127 template<viewable_range _Range>
9128 requires __detail::__can_as_rvalue_view<_Range>
9130 operator() [[nodiscard]] (_Range&& __r)
const
9132 if constexpr (same_as<range_rvalue_reference_t<_Range>,
9133 range_reference_t<_Range>>)
9140 inline constexpr _AsRvalue as_rvalue;
9144#ifdef __cpp_lib_ranges_enumerate
9147 template<
typename _Range>
9148 concept __range_with_movable_reference = input_range<_Range>
9149 && move_constructible<range_reference_t<_Range>>
9150 && move_constructible<range_rvalue_reference_t<_Range>>;
9154 requires __detail::__range_with_movable_reference<_Vp>
9155 class enumerate_view :
public view_interface<enumerate_view<_Vp>>
9157 _Vp _M_base = _Vp();
9159 template<
bool _Const>
class _Iterator;
9160 template<
bool _Const>
class _Sentinel;
9163 enumerate_view()
requires default_initializable<_Vp> = default;
9166 enumerate_view(_Vp __base)
9167 : _M_base(std::move(__base))
9171 begin()
requires (!__detail::__simple_view<_Vp>)
9172 {
return _Iterator<false>(ranges::begin(_M_base), 0); }
9175 begin() const requires __detail::__range_with_movable_reference<const _Vp>
9176 {
return _Iterator<true>(ranges::begin(_M_base), 0); }
9179 end()
requires (!__detail::__simple_view<_Vp>)
9181 if constexpr (common_range<_Vp> && sized_range<_Vp>)
9182 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
9184 return _Sentinel<false>(ranges::end(_M_base));
9188 end() const requires __detail::__range_with_movable_reference<const _Vp>
9190 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9191 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9193 return _Sentinel<true>(ranges::end(_M_base));
9197 size()
requires sized_range<_Vp>
9198 {
return ranges::size(_M_base); }
9201 size() const requires sized_range<const _Vp>
9202 {
return ranges::size(_M_base); }
9205 base() const & requires copy_constructible<_Vp>
9213 template<
typename _Range>
9214 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9216 template<
typename _Tp>
9217 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9218 = enable_borrowed_range<_Tp>;
9221 requires __detail::__range_with_movable_reference<_Vp>
9222 template<
bool _Const>
9223 class enumerate_view<_Vp>::_Iterator
9225 using _Base = __maybe_const_t<_Const, _Vp>;
9230 if constexpr (random_access_range<_Base>)
9231 return random_access_iterator_tag{};
9232 else if constexpr (bidirectional_range<_Base>)
9233 return bidirectional_iterator_tag{};
9234 else if constexpr (forward_range<_Base>)
9235 return forward_iterator_tag{};
9237 return input_iterator_tag{};
9240 friend enumerate_view;
9243 using iterator_category = input_iterator_tag;
9244 using iterator_concept =
decltype(_S_iter_concept());
9245 using difference_type = range_difference_t<_Base>;
9246 using value_type = tuple<difference_type, range_value_t<_Base>>;
9249 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9251 iterator_t<_Base> _M_current = iterator_t<_Base>();
9252 difference_type _M_pos = 0;
9255 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9256 : _M_current(std::
move(__current)), _M_pos(__pos)
9260 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
9263 _Iterator(_Iterator<!_Const> __i)
9264 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9265 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9268 constexpr const iterator_t<_Base> &
9269 base() const & noexcept
9270 {
return _M_current; }
9272 constexpr iterator_t<_Base>
9276 constexpr difference_type
9277 index() const noexcept
9282 {
return __reference_type(_M_pos, *_M_current); }
9284 constexpr _Iterator&
9297 operator++(
int)
requires forward_range<_Base>
9304 constexpr _Iterator&
9305 operator--()
requires bidirectional_range<_Base>
9313 operator--(
int)
requires bidirectional_range<_Base>
9320 constexpr _Iterator&
9321 operator+=(difference_type __n)
requires random_access_range<_Base>
9328 constexpr _Iterator&
9329 operator-=(difference_type __n)
requires random_access_range<_Base>
9337 operator[](difference_type __n)
const requires random_access_range<_Base>
9338 {
return __reference_type(_M_pos + __n, _M_current[__n]); }
9340 friend constexpr bool
9341 operator==(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9342 {
return __x._M_pos == __y._M_pos; }
9344 friend constexpr strong_ordering
9345 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9346 {
return __x._M_pos <=> __y._M_pos; }
9348 friend constexpr _Iterator
9349 operator+(
const _Iterator& __x, difference_type __y)
9350 requires random_access_range<_Base>
9351 {
return (
auto(__x) += __y); }
9353 friend constexpr _Iterator
9354 operator+(difference_type __x,
const _Iterator& __y)
9355 requires random_access_range<_Base>
9356 {
return auto(__y) += __x; }
9358 friend constexpr _Iterator
9359 operator-(
const _Iterator& __x, difference_type __y)
9360 requires random_access_range<_Base>
9361 {
return auto(__x) -= __y; }
9363 friend constexpr difference_type
9364 operator-(
const _Iterator& __x,
const _Iterator& __y)
noexcept
9365 {
return __x._M_pos - __y._M_pos; }
9367 friend constexpr auto
9368 iter_move(
const _Iterator& __i)
9369 noexcept(
noexcept(ranges::iter_move(__i._M_current))
9370 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9372 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9373 (__i._M_pos, ranges::iter_move(__i._M_current));
9378 requires __detail::__range_with_movable_reference<_Vp>
9379 template<
bool _Const>
9380 class enumerate_view<_Vp>::_Sentinel
9382 using _Base = __maybe_const_t<_Const, _Vp>;
9384 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9387 _Sentinel(sentinel_t<_Base> __end)
9388 : _M_end(std::
move(__end))
9391 friend enumerate_view;
9394 _Sentinel() =
default;
9397 _Sentinel(_Sentinel<!_Const> __other)
9398 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9402 constexpr sentinel_t<_Base>
9406 template<
bool _OtherConst>
9407 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9408 friend constexpr bool
9409 operator==(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9410 {
return __x._M_current == __y._M_end; }
9412 template<
bool _OtherConst>
9413 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9414 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9415 operator-(
const _Iterator<_OtherConst>& __x,
const _Sentinel& __y)
9416 {
return __x._M_current - __y._M_end; }
9418 template<
bool _OtherConst>
9419 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9420 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9421 operator-(
const _Sentinel& __x,
const _Iterator<_OtherConst>& __y)
9422 {
return __x._M_end - __y._M_current; }
9429 template<
typename _Tp>
9430 concept __can_enumerate_view
9434 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9436 template<viewable_range _Range>
9437 requires __detail::__can_enumerate_view<_Range>
9439 operator() [[nodiscard]] (_Range&& __r)
const
9443 inline constexpr _Enumerate enumerate;
9447#ifdef __cpp_lib_ranges_as_const
9449 requires input_range<_Vp>
9450 class as_const_view :
public view_interface<as_const_view<_Vp>>
9452 _Vp _M_base = _Vp();
9455 as_const_view()
requires default_initializable<_Vp> = default;
9458 as_const_view(_Vp __base)
9459 noexcept(is_nothrow_move_constructible_v<_Vp>)
9460 : _M_base(std::move(__base))
9465 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9466 requires copy_constructible<_Vp>
9471 noexcept(is_nothrow_move_constructible_v<_Vp>)
9475 begin()
requires (!__detail::__simple_view<_Vp>)
9476 {
return ranges::cbegin(_M_base); }
9479 begin() const requires range<const _Vp>
9480 {
return ranges::cbegin(_M_base); }
9483 end()
requires (!__detail::__simple_view<_Vp>)
9484 {
return ranges::cend(_M_base); }
9487 end() const requires range<const _Vp>
9488 {
return ranges::cend(_M_base); }
9491 size()
requires sized_range<_Vp>
9492 {
return ranges::size(_M_base); }
9495 size() const requires sized_range<const _Vp>
9496 {
return ranges::size(_M_base); }
9499 template<
typename _Range>
9500 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9502 template<
typename _Tp>
9503 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9504 = enable_borrowed_range<_Tp>;
9510 template<
typename _Tp>
9511 inline constexpr bool __is_constable_ref_view =
false;
9513 template<
typename _Range>
9514 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9515 = constant_range<const _Range>;
9517 template<
typename _Range>
9521 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9523 template<viewable_range _Range>
9525 operator()(_Range&& __r)
const
9527 requires __detail::__can_as_const_view<_Range>
9529 using _Tp = remove_cvref_t<_Range>;
9530 using element_type = remove_reference_t<range_reference_t<_Range>>;
9531 if constexpr (constant_range<views::all_t<_Range>>)
9533 else if constexpr (__detail::__is_empty_view<_Tp>)
9534 return views::empty<const element_type>;
9535#if __cpp_lib_optional >= 202506L && __cpp_lib_optional_range_support
9536 else if constexpr (__is_optional_ref_v<_Tp>)
9537 return optional<const typename _Tp::value_type&>(__r);
9539 else if constexpr (std::__detail::__is_span<_Tp>)
9541 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9543 else if constexpr (is_lvalue_reference_v<_Range>
9544 && constant_range<const _Tp>
9546 return ref_view(
static_cast<const _Tp&
>(__r));
9552 inline constexpr _AsConst as_const;
9557 namespace views = ranges::views;
9559#if __cpp_lib_ranges_to_container
9565 template<
typename _Container>
9566 constexpr bool __reservable_container
9567 = sized_range<_Container>
9568 &&
requires(_Container& __c, range_size_t<_Container> __n) {
9570 { __c.capacity() } -> same_as<
decltype(__n)>;
9571 { __c.max_size() } -> same_as<
decltype(__n)>;
9574 template<
typename _Cont,
typename _Range>
9575 constexpr bool __toable =
requires {
9576 requires (!input_range<_Cont>
9577 || convertible_to<range_reference_t<_Range>,
9578 range_value_t<_Cont>>);
9599 template<
typename _Cont, input_range _Rg,
typename... _Args>
9600 requires (!view<_Cont>)
9602 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9604 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9605 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9607 if constexpr (__detail::__toable<_Cont, _Rg>)
9609 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9612 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9615 else if constexpr (
requires {
requires common_range<_Rg>;
9616 typename __iter_category_t<iterator_t<_Rg>>;
9617 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9618 input_iterator_tag>;
9619 requires constructible_from<_Cont, iterator_t<_Rg>,
9620 sentinel_t<_Rg>, _Args...>;
9622 return _Cont(ranges::begin(__r), ranges::end(__r),
9626 static_assert(constructible_from<_Cont, _Args...>);
9628 if constexpr (sized_range<_Rg>
9629 && __detail::__reservable_container<_Cont>)
9630 __c.reserve(
static_cast<range_size_t<_Cont>
>(ranges::size(__r)));
9634 auto __it = ranges::begin(__r);
9635 const auto __sent = ranges::end(__r);
9636 while (__it != __sent)
9638 if constexpr (
requires { __c.emplace_back(*__it); })
9639 __c.emplace_back(*__it);
9640 else if constexpr (
requires { __c.push_back(*__it); })
9641 __c.push_back(*__it);
9642 else if constexpr (
requires { __c.emplace(__c.end(), *__it); })
9643 __c.emplace(__c.end(), *__it);
9645 __c.insert(__c.end(), *__it);
9653 static_assert(input_range<range_reference_t<_Rg>>);
9656 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9657 []<
typename _Elt>(_Elt&& __elem) {
9658 using _ValT = range_value_t<_Cont>;
9667 template<
typename _Rg>
9670 using iterator_category = input_iterator_tag;
9671 using value_type = range_value_t<_Rg>;
9672 using difference_type = ptrdiff_t;
9673 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9674 using reference = range_reference_t<_Rg>;
9676 pointer operator->()
const;
9677 _InputIter& operator++();
9678 _InputIter operator++(
int);
9679 bool operator==(
const _InputIter&)
const;
9682 template<
template<
typename...>
typename _Cont, input_range _Rg,
9687 template<
template<
typename...>
typename _Cont, input_range _Rg,
9693 template<
template<
typename...>
typename _Cont, input_range _Rg,
9703 template<
template<
typename...>
typename _Cont, input_range _Rg,
9706 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9708 using __detail::_DeduceExpr1;
9709 using __detail::_DeduceExpr2;
9710 using __detail::_DeduceExpr3;
9711 if constexpr (
requires {
typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9712 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9714 else if constexpr (
requires {
typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9715 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9717 else if constexpr (
requires {
typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9718 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9721 static_assert(
false);
9727 template<
typename _Cont>
9730 template<
typename _Range,
typename... _Args>
9734 operator()(_Range&& __r, _Args&&... __args)
const
9758 template<
typename _Cont,
typename... _Args>
9759 requires (!view<_Cont>)
9761 to [[nodiscard]] (_Args&&... __args)
9763 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9764 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9766 using __detail::_To;
9767 using views::__adaptor::_Partial;
9774 template<
template<
typename...>
typename _Cont>
9777 template<
typename _Range,
typename... _Args>
9781 operator()(_Range&& __r, _Args&&... __args)
const
9807 template<
template<
typename...>
typename _Cont,
typename... _Args>
9809 to [[nodiscard]] (_Args&&... __args)
9811 using __detail::_To2;
9812 using views::__adaptor::_Partial;
9819#if __cpp_lib_ranges_concat
9824 template<
typename... _Rs>
9825 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9827 template<
typename... _Rs>
9828 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9830 template<
typename... _Rs>
9831 using __concat_rvalue_reference_t
9832 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9834 template<
typename _Ref,
typename _RRef,
typename _It>
9835 concept __concat_indirectly_readable_impl =
requires(
const _It __it) {
9836 { *__it } -> convertible_to<_Ref>;
9837 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9840 template<
typename... _Rs>
9841 concept __concat_indirectly_readable
9842 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9843 && common_reference_with<__concat_reference_t<_Rs...>&&,
9844 __concat_rvalue_reference_t<_Rs...>&&>
9845 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9846 __concat_value_t<_Rs...>
const&>
9847 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9848 __concat_rvalue_reference_t<_Rs...>,
9852 template<
typename... _Rs>
9853 concept __concatable =
requires {
9854 typename __concat_reference_t<_Rs...>;
9855 typename __concat_value_t<_Rs...>;
9856 typename __concat_rvalue_reference_t<_Rs...>;
9857 } && __concat_indirectly_readable<_Rs...>;
9859 template<
bool _Const,
typename _Range,
typename... _Rs>
9860 struct __all_but_last_common
9862 static inline constexpr bool value
9863 =
requires {
requires (common_range<__maybe_const_t<_Const, _Range>>
9864 && __all_but_last_common<_Const, _Rs...>::value); };
9867 template<
bool _Const,
typename _Range>
9868 struct __all_but_last_common<_Const, _Range>
9869 {
static inline constexpr bool value =
true; };
9871 template<
bool _Const,
typename... _Rs>
9872 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9873 && __all_but_last_common<_Const, _Rs...>::value;
9875 template<
bool _Const,
typename... _Rs>
9876 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9877 && __all_but_last_common<_Const, _Rs...>::value;
9879 template<
typename _Range,
typename... _Rs>
9880 struct __all_but_first_sized
9881 {
static inline constexpr bool value = (sized_range<_Rs> && ...); };
9884 template<input_range... _Vs>
9885 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9886 class concat_view : public view_interface<concat_view<_Vs...>>
9888 tuple<_Vs...> _M_views;
9890 template<
bool _Const>
class _Iterator;
9893 constexpr concat_view() =
default;
9896 concat_view(_Vs... __views)
9897 : _M_views(std::
move(__views)...)
9900 constexpr _Iterator<false>
9901 begin()
requires (!(__detail::__simple_view<_Vs> && ...))
9903 _Iterator<false> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9904 __it.template _M_satisfy<0>();
9908 constexpr _Iterator<true>
9909 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9911 _Iterator<true> __it(
this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9912 __it.template _M_satisfy<0>();
9917 end()
requires (!(__detail::__simple_view<_Vs> && ...))
9919 constexpr auto __n =
sizeof...(_Vs);
9920 if constexpr (__detail::__all_forward<
false, _Vs...>
9921 && common_range<_Vs...[__n - 1]>)
9922 return _Iterator<false>(
this, in_place_index<__n - 1>,
9923 ranges::end(std::get<__n - 1>(_M_views)));
9929 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9931 constexpr auto __n =
sizeof...(_Vs);
9932 if constexpr (__detail::__all_forward<
true, _Vs...>
9933 && common_range<
const _Vs...[__n - 1]>)
9934 return _Iterator<true>(
this, in_place_index<__n - 1>,
9935 ranges::end(std::get<__n - 1>(_M_views)));
9941 size()
requires (sized_range<_Vs>&&...)
9943 return std::apply([](
auto... __sizes) {
9944 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9945 return (_CT(__sizes) + ...);
9946 }, __detail::__tuple_transform(ranges::size, _M_views));
9950 size() const requires (sized_range<const _Vs>&&...)
9952 return std::apply([](
auto... __sizes) {
9953 using _CT = __detail::__make_unsigned_like_t<
common_type_t<
decltype(__sizes)...>>;
9954 return (_CT(__sizes) + ...);
9955 }, __detail::__tuple_transform(ranges::size, _M_views));
9959 template<
typename... _Rs>
9960 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9964 template<
bool _Const,
typename... _Vs>
9965 struct __concat_view_iter_cat
9968 template<
bool _Const,
typename... _Vs>
9969 requires __detail::__all_forward<_Const, _Vs...>
9970 struct __concat_view_iter_cat<_Const, _Vs...>
9975 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9976 return input_iterator_tag{};
9978 return []<
typename... _Cats>(_Cats... __cats) {
9979 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9980 && __concat_is_random_access<_Const, _Vs...>)
9981 return random_access_iterator_tag{};
9982 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9983 && __concat_is_bidirectional<_Const, _Vs...>)
9984 return bidirectional_iterator_tag{};
9985 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9986 return forward_iterator_tag{};
9988 return input_iterator_tag{};
9989 }(
typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9990 ::iterator_category{}...);
9995 template<input_range... _Vs>
9996 requires (view<_Vs> && ...) && (
sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9997 template<bool _Const>
9998 class concat_view<_Vs...>::_Iterator
9999 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
10004 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
10005 return random_access_iterator_tag{};
10006 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
10007 return bidirectional_iterator_tag{};
10008 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
10009 return forward_iterator_tag{};
10011 return input_iterator_tag{};
10014 friend concat_view;
10015 friend _Iterator<!_Const>;
10019 using iterator_concept =
decltype(_S_iter_concept());
10020 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
10021 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
10024 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
10026 __maybe_const_t<_Const, concat_view>* _M_parent =
nullptr;
10029 template<
size_t _Nm>
10033 if constexpr (_Nm < (
sizeof...(_Vs) - 1))
10035 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
10037 _M_it.template emplace<_Nm + 1>(ranges::begin
10038 (std::get<_Nm + 1>(_M_parent->_M_views)));
10039 _M_satisfy<_Nm + 1>();
10044 template<
size_t _Nm>
10048 if constexpr (_Nm == 0)
10049 --std::get<0>(_M_it);
10052 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
10054 _M_it.template emplace<_Nm - 1>(ranges::end
10055 (std::get<_Nm - 1>(_M_parent->_M_views)));
10056 _M_prev<_Nm - 1>();
10059 --std::get<_Nm>(_M_it);
10063 template<
size_t _Nm>
10065 _M_advance_fwd(difference_type __offset, difference_type __steps)
10067 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10068 if constexpr (_Nm ==
sizeof...(_Vs) - 1)
10069 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10072 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
10073 if (__offset + __steps < __n_size)
10074 std::get<_Nm>(_M_it) +=
static_cast<_Dt
>(__steps);
10077 _M_it.template emplace<_Nm + 1>(ranges::begin
10078 (std::get<_Nm + 1>(_M_parent->_M_views)));
10079 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
10084 template<
size_t _Nm>
10086 _M_advance_bwd(difference_type __offset, difference_type __steps)
10088 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
10089 if constexpr (_Nm == 0)
10090 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10092 if (__offset >= __steps)
10093 std::get<_Nm>(_M_it) -=
static_cast<_Dt
>(__steps);
10096 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
10097 _M_it.template emplace<_Nm - 1>(ranges::end
10098 (std::get<_Nm - 1>(_M_parent->_M_views)));
10099 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
10107 template<
typename _Fp>
10108 static constexpr auto
10109 _S_invoke_with_runtime_index(_Fp&& __f,
size_t __index)
10111 return [&__f, __index]<
size_t _Idx>(
this auto&& __self) {
10112 if (_Idx == __index)
10113 return __f.template operator()<_Idx>();
10114 if constexpr (_Idx + 1 <
sizeof...(_Vs))
10115 return __self.template
operator()<_Idx + 1>();
10116 __builtin_unreachable();
10117 }.template operator()<0>();
10120 template<
typename _Fp>
10122 _M_invoke_with_runtime_index(_Fp&& __f)
10123 {
return _S_invoke_with_runtime_index(
std::forward<_Fp>(__f), _M_it.index()); }
10125 template<
typename... _Args>
10127 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
10128 requires constructible_from<__base_iter, _Args&&...>
10133 _Iterator() =
default;
10136 _Iterator(_Iterator<!_Const> __it)
10137 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
10138 : _M_parent(__it._M_parent),
10139 _M_it(_S_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
10140 return __base_iter(in_place_index<_Idx>,
10141 std::get<_Idx>(
std::move(__it._M_it)));
10142 }, __it._M_it.index()))
10145 constexpr decltype(
auto)
10148 __glibcxx_assert(!_M_it.valueless_by_exception());
10149 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
10150 return std::visit([](
auto&& __it) -> reference {
return *__it; }, _M_it);
10153 constexpr _Iterator&
10156 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10157 ++std::get<_Idx>(_M_it);
10158 _M_satisfy<_Idx>();
10167 constexpr _Iterator
10169 requires __detail::__all_forward<_Const, _Vs...>
10171 auto __tmp = *
this;
10176 constexpr _Iterator&
10178 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10180 __glibcxx_assert(!_M_it.valueless_by_exception());
10181 _M_invoke_with_runtime_index([
this]<
size_t _Idx>() {
10187 constexpr _Iterator
10189 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10191 auto __tmp = *
this;
10196 constexpr _Iterator&
10197 operator+=(difference_type __n)
10198 requires __detail::__concat_is_random_access<_Const, _Vs...>
10200 __glibcxx_assert(!_M_it.valueless_by_exception());
10201 _M_invoke_with_runtime_index([
this, __n]<
size_t _Idx>() {
10202 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10204 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10206 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10211 constexpr _Iterator&
10212 operator-=(difference_type __n)
10213 requires __detail::__concat_is_random_access<_Const, _Vs...>
10219 constexpr decltype(
auto)
10220 operator[](difference_type __n)
const
10221 requires __detail::__concat_is_random_access<_Const, _Vs...>
10222 {
return *((*this) + __n); }
10224 friend constexpr bool
10225 operator==(
const _Iterator& __x,
const _Iterator& __y)
10226 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10228 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10229 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10230 return __x._M_it == __y._M_it;
10233 friend constexpr bool
10234 operator==(
const _Iterator& __it, default_sentinel_t)
10236 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10237 constexpr auto __last_idx =
sizeof...(_Vs) - 1;
10238 return (__it._M_it.index() == __last_idx
10239 && (std::get<__last_idx>(__it._M_it)
10240 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
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 bool
10259 operator>=(
const _Iterator& __x,
const _Iterator& __y)
10260 requires __detail::__all_random_access<_Const, _Vs...>
10261 {
return __x._M_it >= __y._M_it; }
10263 friend constexpr auto
10264 operator<=>(
const _Iterator& __x,
const _Iterator& __y)
10265 requires __detail::__all_random_access<_Const, _Vs...>
10266 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10267 {
return __x._M_it <=> __y._M_it; }
10269 friend constexpr _Iterator
10270 operator+(
const _Iterator& __it, difference_type __n)
10271 requires __detail::__concat_is_random_access<_Const, _Vs...>
10272 {
return auto(__it) += __n; }
10274 friend constexpr _Iterator
10275 operator+(difference_type __n,
const _Iterator& __it)
10276 requires __detail::__concat_is_random_access<_Const, _Vs...>
10277 {
return __it + __n; }
10279 friend constexpr _Iterator
10280 operator-(
const _Iterator& __it, difference_type __n)
10281 requires __detail::__concat_is_random_access<_Const, _Vs...>
10282 {
return auto(__it) -= __n; }
10284 friend constexpr difference_type
10285 operator-(
const _Iterator& __x,
const _Iterator& __y)
10286 requires __detail::__concat_is_random_access<_Const, _Vs...>
10288 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10289 return _S_invoke_with_runtime_index([&]<
size_t _Iy>() -> difference_type {
10290 if constexpr (_Ix > _Iy)
10292 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10293 ranges::end(std::get<_Iy>(__y._M_parent
10295 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10297 std::get<_Ix>(__x._M_it));
10298 difference_type __s = 0;
10299 [&]<
size_t _Idx = _Iy + 1>(
this auto&& __self) {
10300 if constexpr (_Idx < _Ix)
10302 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10303 __self.template operator()<_Idx + 1>();
10306 return __dy + __s + __dx;
10308 else if constexpr (_Ix < _Iy)
10309 return -(__y - __x);
10311 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10312 }, __y._M_it.index());
10313 }, __x._M_it.index());
10316 friend constexpr difference_type
10317 operator-(
const _Iterator& __x, default_sentinel_t)
10318 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10319 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10320 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10322 return _S_invoke_with_runtime_index([&]<
size_t _Ix>() -> difference_type {
10323 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10324 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10325 difference_type __s = 0;
10326 [&]<
size_t _Idx = _Ix + 1>(
this auto&& __self) {
10327 if constexpr (_Idx <
sizeof...(_Vs))
10329 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10330 __self.template operator()<_Idx + 1>();
10333 return -(__dx + __s);
10334 }, __x._M_it.index());
10337 friend constexpr difference_type
10338 operator-(default_sentinel_t,
const _Iterator& __x)
10339 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10340 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10341 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10344 friend constexpr decltype(
auto)
10345 iter_move(
const _Iterator& __it)
10347 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10348 return std::visit([](
const auto& __i) -> _Res {
10349 return ranges::iter_move(__i);
10353 friend constexpr void
10354 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10355 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10356 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10358 std::visit([&]<
typename _Tp,
typename _Up>(
const _Tp& __it1,
const _Up& __it2) {
10359 if constexpr (is_same_v<_Tp, _Up>)
10360 ranges::iter_swap(__it1, __it2);
10362 ranges::swap(*__it1, *__it2);
10363 }, __x._M_it, __y._M_it);
10371 template<
typename... _Ts>
10377 template<
typename... _Ts>
10378 requires __detail::__can_concat_view<_Ts...>
10380 operator() [[nodiscard]] (_Ts&&... __ts)
const
10383 template<input_range _Range>
10385 operator() [[nodiscard]] (_Range&& __t)
const
10389 inline constexpr _Concat concat;
10395#if __cpp_lib_ranges_cache_latest
10398 template<input_range _Vp>
10400 class cache_latest_view :
public view_interface<cache_latest_view<_Vp>>
10402 _Vp _M_base = _Vp();
10404 using __cache_t = __conditional_t<is_reference_v<range_reference_t<_Vp>>,
10405 add_pointer_t<range_reference_t<_Vp>>,
10406 range_reference_t<_Vp>>;
10407 __detail::__non_propagating_cache<__cache_t> _M_cache;
10413 cache_latest_view()
requires default_initializable<_Vp> = default;
10416 cache_latest_view(_Vp __base)
10417 : _M_base(std::move(__base))
10421 base() const & requires copy_constructible<_Vp>
10422 {
return _M_base; }
10430 {
return _Iterator(*
this); }
10434 {
return _Sentinel(*
this); }
10437 size()
requires sized_range<_Vp>
10438 {
return ranges::size(_M_base); }
10441 size() const requires sized_range<const _Vp>
10442 {
return ranges::size(_M_base); }
10445 template<
typename _Range>
10446 cache_latest_view(_Range&&) -> cache_latest_view<views::all_t<_Range>>;
10448 template<input_range _Vp>
10450 class cache_latest_view<_Vp>::_Iterator
10452 cache_latest_view* _M_parent;
10453 iterator_t<_Vp> _M_current;
10456 _Iterator(cache_latest_view& __parent)
10458 _M_current(ranges::
begin(__parent._M_base))
10461 friend class cache_latest_view;
10464 using difference_type = range_difference_t<_Vp>;
10465 using value_type = range_value_t<_Vp>;
10466 using iterator_concept = input_iterator_tag;
10468 _Iterator(_Iterator&&) =
default;
10471 operator=(_Iterator&&) =
default;
10473 constexpr iterator_t<_Vp>
10477 constexpr const iterator_t<_Vp>&
10478 base() const & noexcept
10479 {
return _M_current; }
10481 constexpr range_reference_t<_Vp>&
10484 if constexpr (is_reference_v<range_reference_t<_Vp>>)
10486 if (!_M_parent->_M_cache)
10487 _M_parent->_M_cache =
std::__addressof(__detail::__as_lvalue(*_M_current));
10488 return **_M_parent->_M_cache;
10492 if (!_M_parent->_M_cache)
10493 _M_parent->_M_cache._M_emplace_deref(_M_current);
10494 return *_M_parent->_M_cache;
10498 constexpr _Iterator&
10501 _M_parent->_M_cache._M_reset();
10510 friend constexpr range_rvalue_reference_t<_Vp>
10511 iter_move(
const _Iterator& __i)
10512 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10513 {
return ranges::iter_move(__i._M_current); }
10515 friend constexpr void
10516 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10517 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10518 requires indirectly_swappable<iterator_t<_Vp>>
10519 { ranges::iter_swap(__x._M_current, __y._M_current); }
10522 template<input_range _Vp>
10524 class cache_latest_view<_Vp>::_Sentinel
10526 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
10529 _Sentinel(cache_latest_view& __parent)
10530 : _M_end(ranges::
end(__parent._M_base))
10533 friend class cache_latest_view;
10536 _Sentinel() =
default;
10538 constexpr sentinel_t<_Vp>
10542 friend constexpr bool
10543 operator==(
const _Iterator& __x,
const _Sentinel& __y)
10544 {
return __x._M_current == __y._M_end; }
10546 friend constexpr range_difference_t<_Vp>
10547 operator-(
const _Iterator& __x,
const _Sentinel& __y)
10548 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10549 {
return __x._M_current - __y._M_end; }
10551 friend constexpr range_difference_t<_Vp>
10552 operator-(
const _Sentinel& __x,
const _Iterator& __y)
10553 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
10554 {
return __x._M_end - __y._M_current; }
10561 template<
typename _Tp>
10562 concept __can_cache_latest =
requires { cache_latest_view(
std::declval<_Tp>()); };
10565 struct _CacheLatest : __adaptor::_RangeAdaptorClosure<_CacheLatest>
10567 template<viewable_range _Range>
10568 requires __detail::__can_cache_latest<_Range>
10570 operator() [[nodiscard]] (_Range&& __r)
const
10573 static constexpr bool _S_has_simple_call_op =
true;
10576 inline constexpr _CacheLatest cache_latest;
10581#if __cpp_lib_ranges_to_input
10584 template<input_range _Vp>
10586 class to_input_view :
public view_interface<to_input_view<_Vp>>
10588 _Vp _M_base = _Vp();
10590 template<
bool _Const>
10594 to_input_view()
requires default_initializable<_Vp> = default;
10597 to_input_view(_Vp __base)
10598 : _M_base(std::move(__base))
10602 base() const & requires copy_constructible<_Vp>
10603 {
return _M_base; }
10610 begin()
requires (!__detail::__simple_view<_Vp>)
10611 {
return _Iterator<false>(ranges::begin(_M_base)); }
10614 begin() const requires range<const _Vp>
10615 {
return _Iterator<true>(ranges::begin(_M_base)); }
10618 end()
requires (!__detail::__simple_view<_Vp>)
10619 {
return ranges::end(_M_base); }
10622 end() const requires range<const _Vp>
10623 {
return ranges::end(_M_base); }
10626 size()
requires sized_range<_Vp>
10627 {
return ranges::size(_M_base); }
10630 size() const requires sized_range<const _Vp>
10631 {
return ranges::size(_M_base); }
10634 template<
typename _Range>
10635 to_input_view(_Range&&) -> to_input_view<views::all_t<_Range>>;
10637 template<input_range _Vp>
10639 template<
bool _Const>
10640 class to_input_view<_Vp>::_Iterator
10642 using _Base = __maybe_const_t<_Const, _Vp>;
10644 iterator_t<_Base> _M_current = iterator_t<_Base>();
10647 _Iterator(iterator_t<_Base> __current)
10648 : _M_current(std::
move(__current))
10651 friend to_input_view;
10652 friend _Iterator<!_Const>;
10655 using difference_type = range_difference_t<_Base>;
10656 using value_type = range_value_t<_Base>;
10657 using iterator_concept = input_iterator_tag;
10659 _Iterator()
requires default_initializable<iterator_t<_Base>> = default;
10661 _Iterator(_Iterator&&) = default;
10662 _Iterator& operator=(_Iterator&&) = default;
10665 _Iterator(_Iterator<!_Const> __i)
10666 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
10667 : _M_current(std::move(__i._M_current))
10670 constexpr iterator_t<_Base>
10674 constexpr const iterator_t<_Base>&
10675 base() const & noexcept
10676 {
return _M_current; }
10678 constexpr decltype(
auto)
10680 {
return *_M_current; }
10682 constexpr _Iterator&
10693 friend constexpr bool
10694 operator==(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10695 {
return __x._M_current == __y; }
10697 friend constexpr difference_type
10698 operator-(
const sentinel_t<_Base>& __y,
const _Iterator& __x)
10699 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10700 {
return __y - __x._M_current; }
10702 friend constexpr difference_type
10703 operator-(
const _Iterator& __x,
const sentinel_t<_Base>& __y)
10704 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
10705 {
return __x._M_current - __y; }
10707 friend constexpr range_rvalue_reference_t<_Base>
10708 iter_move(
const _Iterator& __i)
10709 noexcept(
noexcept(ranges::iter_move(__i._M_current)))
10710 {
return ranges::iter_move(__i._M_current); }
10712 friend constexpr void
10713 iter_swap(
const _Iterator& __x,
const _Iterator& __y)
10714 noexcept(
noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
10715 requires indirectly_swappable<iterator_t<_Base>>
10716 { ranges::iter_swap(__x._M_current, __y._M_current); }
10723 template<
typename _Tp>
10727 struct _ToInput : __adaptor::_RangeAdaptorClosure<_ToInput>
10729 template<viewable_range _Range>
10730 requires __detail::__can_to_input<_Range>
10732 operator() [[nodiscard]] (_Range&& __r)
const
10734 if constexpr (input_range<_Range>
10735 && !common_range<_Range>
10736 && !forward_range<_Range>)
10742 static constexpr bool _S_has_simple_call_op =
true;
10745 inline constexpr _ToInput to_input;
10750_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.