1 // <ranges> -*- C++ -*-
3 // Copyright (C) 2019-2023 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file include/ranges
26 * This is a Standard C++ Library header.
30 #ifndef _GLIBCXX_RANGES
31 #define _GLIBCXX_RANGES 1
33 #if __cplusplus > 201703L
35 #pragma GCC system_header
39 #if __cpp_lib_concepts
42 #include <initializer_list>
46 #include <string_view>
48 #if __cplusplus > 202002L
51 #include <bits/ranges_util.h>
52 #include <bits/refwrap.h>
55 * @defgroup ranges Ranges
57 * Components for dealing with ranges of elements.
60 namespace std _GLIBCXX_VISIBILITY(default)
62 _GLIBCXX_BEGIN_NAMESPACE_VERSION
65 // [range.access] customization point objects
66 // [range.req] range and view concepts
67 // [range.dangling] dangling iterator handling
68 // Defined in <bits/ranges_base.h>
70 // [view.interface] View interface
71 // [range.subrange] Sub-ranges
72 // Defined in <bits/ranges_util.h>
74 // C++20 24.6 [range.factories] Range factories
76 /// A view that contains no elements.
77 template<typename _Tp> requires is_object_v<_Tp>
79 : public view_interface<empty_view<_Tp>>
82 static constexpr _Tp* begin() noexcept { return nullptr; }
83 static constexpr _Tp* end() noexcept { return nullptr; }
84 static constexpr _Tp* data() noexcept { return nullptr; }
85 static constexpr size_t size() noexcept { return 0; }
86 static constexpr bool empty() noexcept { return true; }
89 template<typename _Tp>
90 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
94 template<typename _Tp>
95 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
97 template<__boxable _Tp>
98 struct __box : std::optional<_Tp>
100 using std::optional<_Tp>::optional;
104 noexcept(is_nothrow_default_constructible_v<_Tp>)
105 requires default_initializable<_Tp>
106 : std::optional<_Tp>{std::in_place}
109 __box(const __box&) = default;
110 __box(__box&&) = default;
112 using std::optional<_Tp>::operator=;
114 // _GLIBCXX_RESOLVE_LIB_DEFECTS
115 // 3477. Simplify constraints for semiregular-box
116 // 3572. copyable-box should be fully constexpr
118 operator=(const __box& __that)
119 noexcept(is_nothrow_copy_constructible_v<_Tp>)
120 requires (!copyable<_Tp>)
122 if (this != std::__addressof(__that))
125 this->emplace(*__that);
133 operator=(__box&& __that)
134 noexcept(is_nothrow_move_constructible_v<_Tp>)
135 requires (!movable<_Tp>)
137 if (this != std::__addressof(__that))
140 this->emplace(std::move(*__that));
148 // For types which are already copyable, this specialization of the
149 // copyable wrapper stores the object directly without going through
150 // std::optional. It provides just the subset of the primary template's
151 // API that we currently use.
152 template<__boxable _Tp>
153 requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
154 && is_nothrow_copy_constructible_v<_Tp>)
158 [[no_unique_address]] _Tp _M_value = _Tp();
161 __box() requires default_initializable<_Tp> = default;
164 __box(const _Tp& __t)
165 noexcept(is_nothrow_copy_constructible_v<_Tp>)
171 noexcept(is_nothrow_move_constructible_v<_Tp>)
172 : _M_value(std::move(__t))
175 template<typename... _Args>
176 requires constructible_from<_Tp, _Args...>
178 __box(in_place_t, _Args&&... __args)
179 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
180 : _M_value(std::forward<_Args>(__args)...)
183 __box(const __box&) = default;
184 __box(__box&&) = default;
185 __box& operator=(const __box&) requires copyable<_Tp> = default;
186 __box& operator=(__box&&) requires copyable<_Tp> = default;
188 // When _Tp is nothrow_copy_constructible but not copy_assignable,
189 // copy assignment is implemented via destroy-then-copy-construct.
191 operator=(const __box& __that) noexcept
193 static_assert(is_nothrow_copy_constructible_v<_Tp>);
194 if (this != std::__addressof(__that))
197 std::construct_at(std::__addressof(_M_value), *__that);
202 // Likewise for move assignment.
204 operator=(__box&& __that) noexcept
206 static_assert(is_nothrow_move_constructible_v<_Tp>);
207 if (this != std::__addressof(__that))
210 std::construct_at(std::__addressof(_M_value), std::move(*__that));
216 has_value() const noexcept
224 operator*() const noexcept
228 operator->() noexcept
229 { return std::__addressof(_M_value); }
232 operator->() const noexcept
233 { return std::__addressof(_M_value); }
235 } // namespace __detail
237 /// A view that contains exactly one element.
238 template<copy_constructible _Tp> requires is_object_v<_Tp>
239 class single_view : public view_interface<single_view<_Tp>>
242 single_view() requires default_initializable<_Tp> = default;
245 single_view(const _Tp& __t)
246 noexcept(is_nothrow_copy_constructible_v<_Tp>)
251 single_view(_Tp&& __t)
252 noexcept(is_nothrow_move_constructible_v<_Tp>)
253 : _M_value(std::move(__t))
256 // _GLIBCXX_RESOLVE_LIB_DEFECTS
257 // 3428. single_view's in place constructor should be explicit
258 template<typename... _Args>
259 requires constructible_from<_Tp, _Args...>
261 single_view(in_place_t, _Args&&... __args)
262 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
263 : _M_value{in_place, std::forward<_Args>(__args)...}
271 begin() const noexcept
276 { return data() + 1; }
280 { return data() + 1; }
282 static constexpr size_t
288 { return _M_value.operator->(); }
291 data() const noexcept
292 { return _M_value.operator->(); }
295 [[no_unique_address]] __detail::__box<_Tp> _M_value;
298 template<typename _Tp>
299 single_view(_Tp) -> single_view<_Tp>;
303 template<typename _Wp>
304 constexpr auto __to_signed_like(_Wp __w) noexcept
306 if constexpr (!integral<_Wp>)
307 return iter_difference_t<_Wp>();
308 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
309 return iter_difference_t<_Wp>(__w);
310 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
311 return ptrdiff_t(__w);
312 else if constexpr (sizeof(long long) > sizeof(_Wp))
313 return (long long)(__w);
314 #ifdef __SIZEOF_INT128__
315 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
316 return __int128(__w);
319 return __max_diff_type(__w);
322 template<typename _Wp>
323 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
325 template<typename _It>
326 concept __decrementable = incrementable<_It>
329 { --__i } -> same_as<_It&>;
330 { __i-- } -> same_as<_It>;
333 template<typename _It>
334 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
335 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
337 { __i += __n } -> same_as<_It&>;
338 { __i -= __n } -> same_as<_It&>;
342 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
345 template<typename _Winc>
346 struct __iota_view_iter_cat
349 template<incrementable _Winc>
350 struct __iota_view_iter_cat<_Winc>
351 { using iterator_category = input_iterator_tag; };
352 } // namespace __detail
354 template<weakly_incrementable _Winc,
355 semiregular _Bound = unreachable_sentinel_t>
356 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
358 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
363 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
369 using namespace __detail;
370 if constexpr (__advanceable<_Winc>)
371 return random_access_iterator_tag{};
372 else if constexpr (__decrementable<_Winc>)
373 return bidirectional_iterator_tag{};
374 else if constexpr (incrementable<_Winc>)
375 return forward_iterator_tag{};
377 return input_iterator_tag{};
381 using iterator_concept = decltype(_S_iter_concept());
382 // iterator_category defined in __iota_view_iter_cat
383 using value_type = _Winc;
384 using difference_type = __detail::__iota_diff_t<_Winc>;
386 _Iterator() requires default_initializable<_Winc> = default;
389 _Iterator(_Winc __value)
390 : _M_value(__value) { }
393 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
408 operator++(int) requires incrementable<_Winc>
416 operator--() requires __detail::__decrementable<_Winc>
423 operator--(int) requires __detail::__decrementable<_Winc>
431 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
433 using __detail::__is_integer_like;
434 using __detail::__is_signed_integer_like;
435 if constexpr (__is_integer_like<_Winc>
436 && !__is_signed_integer_like<_Winc>)
438 if (__n >= difference_type(0))
439 _M_value += static_cast<_Winc>(__n);
441 _M_value -= static_cast<_Winc>(-__n);
449 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
451 using __detail::__is_integer_like;
452 using __detail::__is_signed_integer_like;
453 if constexpr (__is_integer_like<_Winc>
454 && !__is_signed_integer_like<_Winc>)
456 if (__n >= difference_type(0))
457 _M_value -= static_cast<_Winc>(__n);
459 _M_value += static_cast<_Winc>(-__n);
467 operator[](difference_type __n) const
468 requires __detail::__advanceable<_Winc>
469 { return _Winc(_M_value + __n); }
471 friend constexpr bool
472 operator==(const _Iterator& __x, const _Iterator& __y)
473 requires equality_comparable<_Winc>
474 { return __x._M_value == __y._M_value; }
476 friend constexpr bool
477 operator<(const _Iterator& __x, const _Iterator& __y)
478 requires totally_ordered<_Winc>
479 { return __x._M_value < __y._M_value; }
481 friend constexpr bool
482 operator>(const _Iterator& __x, const _Iterator& __y)
483 requires totally_ordered<_Winc>
484 { return __y < __x; }
486 friend constexpr bool
487 operator<=(const _Iterator& __x, const _Iterator& __y)
488 requires totally_ordered<_Winc>
489 { return !(__y < __x); }
491 friend constexpr bool
492 operator>=(const _Iterator& __x, const _Iterator& __y)
493 requires totally_ordered<_Winc>
494 { return !(__x < __y); }
496 #ifdef __cpp_lib_three_way_comparison
497 friend constexpr auto
498 operator<=>(const _Iterator& __x, const _Iterator& __y)
499 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
500 { return __x._M_value <=> __y._M_value; }
503 friend constexpr _Iterator
504 operator+(_Iterator __i, difference_type __n)
505 requires __detail::__advanceable<_Winc>
511 friend constexpr _Iterator
512 operator+(difference_type __n, _Iterator __i)
513 requires __detail::__advanceable<_Winc>
514 { return __i += __n; }
516 friend constexpr _Iterator
517 operator-(_Iterator __i, difference_type __n)
518 requires __detail::__advanceable<_Winc>
524 friend constexpr difference_type
525 operator-(const _Iterator& __x, const _Iterator& __y)
526 requires __detail::__advanceable<_Winc>
528 using __detail::__is_integer_like;
529 using __detail::__is_signed_integer_like;
530 using _Dt = difference_type;
531 if constexpr (__is_integer_like<_Winc>)
533 if constexpr (__is_signed_integer_like<_Winc>)
534 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
536 return (__y._M_value > __x._M_value)
537 ? _Dt(-_Dt(__y._M_value - __x._M_value))
538 : _Dt(__x._M_value - __y._M_value);
541 return __x._M_value - __y._M_value;
545 _Winc _M_value = _Winc();
555 _M_equal(const _Iterator& __x) const
556 { return __x._M_value == _M_bound; }
559 _M_distance_from(const _Iterator& __x) const
560 { return _M_bound - __x._M_value; }
562 _Bound _M_bound = _Bound();
565 _Sentinel() = default;
568 _Sentinel(_Bound __bound)
569 : _M_bound(__bound) { }
571 friend constexpr bool
572 operator==(const _Iterator& __x, const _Sentinel& __y)
573 { return __y._M_equal(__x); }
575 friend constexpr iter_difference_t<_Winc>
576 operator-(const _Iterator& __x, const _Sentinel& __y)
577 requires sized_sentinel_for<_Bound, _Winc>
578 { return -__y._M_distance_from(__x); }
580 friend constexpr iter_difference_t<_Winc>
581 operator-(const _Sentinel& __x, const _Iterator& __y)
582 requires sized_sentinel_for<_Bound, _Winc>
583 { return __x._M_distance_from(__y); }
588 _Winc _M_value = _Winc();
589 [[no_unique_address]] _Bound _M_bound = _Bound();
592 iota_view() requires default_initializable<_Winc> = default;
595 iota_view(_Winc __value)
600 iota_view(type_identity_t<_Winc> __value,
601 type_identity_t<_Bound> __bound)
602 : _M_value(__value), _M_bound(__bound)
604 if constexpr (totally_ordered_with<_Winc, _Bound>)
605 __glibcxx_assert( bool(__value <= __bound) );
609 iota_view(_Iterator __first, _Iterator __last)
610 requires same_as<_Winc, _Bound>
611 : iota_view(__first._M_value, __last._M_value)
615 iota_view(_Iterator __first, unreachable_sentinel_t __last)
616 requires same_as<_Bound, unreachable_sentinel_t>
617 : iota_view(__first._M_value, __last)
621 iota_view(_Iterator __first, _Sentinel __last)
622 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
623 : iota_view(__first._M_value, __last._M_bound)
627 begin() const { return _Iterator{_M_value}; }
632 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
633 return unreachable_sentinel;
635 return _Sentinel{_M_bound};
639 end() const requires same_as<_Winc, _Bound>
640 { return _Iterator{_M_bound}; }
644 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
645 || (integral<_Winc> && integral<_Bound>)
646 || sized_sentinel_for<_Bound, _Winc>
648 using __detail::__is_integer_like;
649 using __detail::__to_unsigned_like;
650 if constexpr (integral<_Winc> && integral<_Bound>)
652 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
653 return _Up(_M_bound) - _Up(_M_value);
655 else if constexpr (__is_integer_like<_Winc>)
656 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
658 return __to_unsigned_like(_M_bound - _M_value);
662 template<typename _Winc, typename _Bound>
663 requires (!__detail::__is_integer_like<_Winc>
664 || !__detail::__is_integer_like<_Bound>
665 || (__detail::__is_signed_integer_like<_Winc>
666 == __detail::__is_signed_integer_like<_Bound>))
667 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
669 template<typename _Winc, typename _Bound>
670 inline constexpr bool
671 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
675 template<typename _Tp>
676 inline constexpr empty_view<_Tp> empty{};
680 template<typename _Tp>
683 operator()(_Tp&& __e) const
684 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
685 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
688 inline constexpr _Single single{};
692 template<typename _Tp>
695 operator()(_Tp&& __e) const
696 { return iota_view(std::forward<_Tp>(__e)); }
698 template<typename _Tp, typename _Up>
701 operator()(_Tp&& __e, _Up&& __f) const
702 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
705 inline constexpr _Iota iota{};
711 template<typename _Val, typename _CharT, typename _Traits>
712 concept __stream_extractable
713 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
714 } // namespace __detail
716 template<movable _Val, typename _CharT,
717 typename _Traits = char_traits<_CharT>>
718 requires default_initializable<_Val>
719 && __detail::__stream_extractable<_Val, _CharT, _Traits>
720 class basic_istream_view
721 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
725 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
726 : _M_stream(std::__addressof(__stream))
732 *_M_stream >> _M_object;
733 return _Iterator{this};
736 constexpr default_sentinel_t
738 { return default_sentinel; }
741 basic_istream<_CharT, _Traits>* _M_stream;
742 _Val _M_object = _Val();
747 using iterator_concept = input_iterator_tag;
748 using difference_type = ptrdiff_t;
749 using value_type = _Val;
752 _Iterator(basic_istream_view* __parent) noexcept
753 : _M_parent(__parent)
756 _Iterator(const _Iterator&) = delete;
757 _Iterator(_Iterator&&) = default;
758 _Iterator& operator=(const _Iterator&) = delete;
759 _Iterator& operator=(_Iterator&&) = default;
764 *_M_parent->_M_stream >> _M_parent->_M_object;
774 { return _M_parent->_M_object; }
777 operator==(const _Iterator& __x, default_sentinel_t)
778 { return __x._M_at_end(); }
781 basic_istream_view* _M_parent;
785 { return !*_M_parent->_M_stream; }
791 template<typename _Val>
792 using istream_view = basic_istream_view<_Val, char>;
794 template<typename _Val>
795 using wistream_view = basic_istream_view<_Val, wchar_t>;
799 template<typename _Tp>
802 template<typename _CharT, typename _Traits>
805 operator()(basic_istream<_CharT, _Traits>& __e) const
806 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
809 template<typename _Tp>
810 inline constexpr _Istream<_Tp> istream;
814 // C++20 24.7 [range.adaptors] Range adaptors
820 // Alias for a type that is conditionally present
821 // (and is an empty type otherwise).
822 // Data members using this alias should use [[no_unique_address]] so that
823 // they take no space when not needed.
824 template<bool _Present, typename _Tp>
825 using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;
827 // Alias for a type that is conditionally const.
828 template<bool _Const, typename _Tp>
829 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
831 } // namespace __detail
833 // Shorthand for __detail::__maybe_const_t.
834 using __detail::__maybe_const_t;
836 namespace views::__adaptor
838 // True if the range adaptor _Adaptor can be applied with _Args.
839 template<typename _Adaptor, typename... _Args>
840 concept __adaptor_invocable
841 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
843 // True if the range adaptor non-closure _Adaptor can be partially applied
845 template<typename _Adaptor, typename... _Args>
846 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
847 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
848 && (constructible_from<decay_t<_Args>, _Args> && ...);
850 template<typename _Adaptor, typename... _Args>
853 template<typename _Lhs, typename _Rhs>
856 // The base class of every range adaptor closure.
858 // The derived class should define the optional static data member
859 // _S_has_simple_call_op to true if the behavior of this adaptor is
860 // independent of the constness/value category of the adaptor object.
861 struct _RangeAdaptorClosure
863 // range | adaptor is equivalent to adaptor(range).
864 template<typename _Self, typename _Range>
865 requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
866 && __adaptor_invocable<_Self, _Range>
867 friend constexpr auto
868 operator|(_Range&& __r, _Self&& __self)
869 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
871 // Compose the adaptors __lhs and __rhs into a pipeline, returning
872 // another range adaptor closure object.
873 template<typename _Lhs, typename _Rhs>
874 requires derived_from<_Lhs, _RangeAdaptorClosure>
875 && derived_from<_Rhs, _RangeAdaptorClosure>
876 friend constexpr auto
877 operator|(_Lhs __lhs, _Rhs __rhs)
878 { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; }
881 // The base class of every range adaptor non-closure.
883 // The static data member _Derived::_S_arity must contain the total number of
884 // arguments that the adaptor takes, and the class _Derived must introduce
885 // _RangeAdaptor::operator() into the class scope via a using-declaration.
887 // The optional static data member _Derived::_S_has_simple_extra_args should
888 // be defined to true if the behavior of this adaptor is independent of the
889 // constness/value category of the extra arguments. This data member could
890 // also be defined as a variable template parameterized by the types of the
892 template<typename _Derived>
895 // Partially apply the arguments __args to the range adaptor _Derived,
896 // returning a range adaptor closure object.
897 template<typename... _Args>
898 requires __adaptor_partial_app_viable<_Derived, _Args...>
900 operator()(_Args&&... __args) const
902 return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
906 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
907 // one that's not overloaded according to constness or value category of the
909 template<typename _Adaptor>
910 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
912 // True if the behavior of the range adaptor non-closure _Adaptor is
913 // independent of the value category of its extra arguments _Args.
914 template<typename _Adaptor, typename... _Args>
915 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
916 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
918 // A range adaptor closure that represents partial application of
919 // the range adaptor _Adaptor with arguments _Args.
920 template<typename _Adaptor, typename... _Args>
921 struct _Partial : _RangeAdaptorClosure
923 tuple<_Args...> _M_args;
926 _Partial(_Args... __args)
927 : _M_args(std::move(__args)...)
930 // Invoke _Adaptor with arguments __r, _M_args... according to the
931 // value category of this _Partial object.
932 template<typename _Range>
933 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
935 operator()(_Range&& __r) const &
937 auto __forwarder = [&__r] (const auto&... __args) {
938 return _Adaptor{}(std::forward<_Range>(__r), __args...);
940 return std::apply(__forwarder, _M_args);
943 template<typename _Range>
944 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
946 operator()(_Range&& __r) &&
948 auto __forwarder = [&__r] (auto&... __args) {
949 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
951 return std::apply(__forwarder, _M_args);
954 template<typename _Range>
956 operator()(_Range&& __r) const && = delete;
959 // A lightweight specialization of the above primary template for
960 // the common case where _Adaptor accepts a single extra argument.
961 template<typename _Adaptor, typename _Arg>
962 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
968 : _M_arg(std::move(__arg))
971 template<typename _Range>
972 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
974 operator()(_Range&& __r) const &
975 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
977 template<typename _Range>
978 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
980 operator()(_Range&& __r) &&
981 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
983 template<typename _Range>
985 operator()(_Range&& __r) const && = delete;
988 // Partial specialization of the primary template for the case where the extra
989 // arguments of the adaptor can always be safely and efficiently forwarded by
990 // const reference. This lets us get away with a single operator() overload,
991 // which makes overload resolution failure diagnostics more concise.
992 template<typename _Adaptor, typename... _Args>
993 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
994 && (is_trivially_copyable_v<_Args> && ...)
995 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
997 tuple<_Args...> _M_args;
1000 _Partial(_Args... __args)
1001 : _M_args(std::move(__args)...)
1004 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1005 // of the value category of this _Partial object.
1006 template<typename _Range>
1007 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1009 operator()(_Range&& __r) const
1011 auto __forwarder = [&__r] (const auto&... __args) {
1012 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1014 return std::apply(__forwarder, _M_args);
1017 static constexpr bool _S_has_simple_call_op = true;
1020 // A lightweight specialization of the above template for the common case
1021 // where _Adaptor accepts a single extra argument.
1022 template<typename _Adaptor, typename _Arg>
1023 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1024 && is_trivially_copyable_v<_Arg>
1025 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
1030 _Partial(_Arg __arg)
1031 : _M_arg(std::move(__arg))
1034 template<typename _Range>
1035 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1037 operator()(_Range&& __r) const
1038 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1040 static constexpr bool _S_has_simple_call_op = true;
1043 template<typename _Lhs, typename _Rhs, typename _Range>
1044 concept __pipe_invocable
1045 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1047 // A range adaptor closure that represents composition of the range
1048 // adaptor closures _Lhs and _Rhs.
1049 template<typename _Lhs, typename _Rhs>
1050 struct _Pipe : _RangeAdaptorClosure
1052 [[no_unique_address]] _Lhs _M_lhs;
1053 [[no_unique_address]] _Rhs _M_rhs;
1056 _Pipe(_Lhs __lhs, _Rhs __rhs)
1057 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1060 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1061 // range adaptor closure object.
1062 template<typename _Range>
1063 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1065 operator()(_Range&& __r) const &
1066 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1068 template<typename _Range>
1069 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1071 operator()(_Range&& __r) &&
1072 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1074 template<typename _Range>
1076 operator()(_Range&& __r) const && = delete;
1079 // A partial specialization of the above primary template for the case where
1080 // both adaptor operands have a simple operator(). This in turn lets us
1081 // implement composition using a single simple operator(), which makes
1082 // overload resolution failure diagnostics more concise.
1083 template<typename _Lhs, typename _Rhs>
1084 requires __closure_has_simple_call_op<_Lhs>
1085 && __closure_has_simple_call_op<_Rhs>
1086 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
1088 [[no_unique_address]] _Lhs _M_lhs;
1089 [[no_unique_address]] _Rhs _M_rhs;
1092 _Pipe(_Lhs __lhs, _Rhs __rhs)
1093 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1096 template<typename _Range>
1097 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1099 operator()(_Range&& __r) const
1100 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1102 static constexpr bool _S_has_simple_call_op = true;
1104 } // namespace views::__adaptor
1106 template<range _Range> requires is_object_v<_Range>
1107 class ref_view : public view_interface<ref_view<_Range>>
1112 static void _S_fun(_Range&); // not defined
1113 static void _S_fun(_Range&&) = delete;
1116 template<__detail::__different_from<ref_view> _Tp>
1117 requires convertible_to<_Tp, _Range&>
1118 && requires { _S_fun(declval<_Tp>()); }
1121 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1122 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1129 constexpr iterator_t<_Range>
1131 { return ranges::begin(*_M_r); }
1133 constexpr sentinel_t<_Range>
1135 { return ranges::end(*_M_r); }
1138 empty() const requires requires { ranges::empty(*_M_r); }
1139 { return ranges::empty(*_M_r); }
1142 size() const requires sized_range<_Range>
1143 { return ranges::size(*_M_r); }
1146 data() const requires contiguous_range<_Range>
1147 { return ranges::data(*_M_r); }
1150 template<typename _Range>
1151 ref_view(_Range&) -> ref_view<_Range>;
1153 template<typename _Tp>
1154 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1156 template<range _Range>
1157 requires movable<_Range>
1158 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1159 class owning_view : public view_interface<owning_view<_Range>>
1162 _Range _M_r = _Range();
1165 owning_view() requires default_initializable<_Range> = default;
1168 owning_view(_Range&& __t)
1169 noexcept(is_nothrow_move_constructible_v<_Range>)
1170 : _M_r(std::move(__t))
1173 owning_view(owning_view&&) = default;
1174 owning_view& operator=(owning_view&&) = default;
1180 constexpr const _Range&
1181 base() const& noexcept
1186 { return std::move(_M_r); }
1188 constexpr const _Range&&
1189 base() const&& noexcept
1190 { return std::move(_M_r); }
1192 constexpr iterator_t<_Range>
1194 { return ranges::begin(_M_r); }
1196 constexpr sentinel_t<_Range>
1198 { return ranges::end(_M_r); }
1201 begin() const requires range<const _Range>
1202 { return ranges::begin(_M_r); }
1205 end() const requires range<const _Range>
1206 { return ranges::end(_M_r); }
1209 empty() requires requires { ranges::empty(_M_r); }
1210 { return ranges::empty(_M_r); }
1213 empty() const requires requires { ranges::empty(_M_r); }
1214 { return ranges::empty(_M_r); }
1217 size() requires sized_range<_Range>
1218 { return ranges::size(_M_r); }
1221 size() const requires sized_range<const _Range>
1222 { return ranges::size(_M_r); }
1225 data() requires contiguous_range<_Range>
1226 { return ranges::data(_M_r); }
1229 data() const requires contiguous_range<const _Range>
1230 { return ranges::data(_M_r); }
1233 template<typename _Tp>
1234 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1235 = enable_borrowed_range<_Tp>;
1241 template<typename _Range>
1242 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1244 template<typename _Range>
1245 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1246 } // namespace __detail
1248 struct _All : __adaptor::_RangeAdaptorClosure
1250 template<typename _Range>
1251 static constexpr bool
1254 if constexpr (view<decay_t<_Range>>)
1255 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1256 else if constexpr (__detail::__can_ref_view<_Range>)
1259 return noexcept(owning_view{std::declval<_Range>()});
1262 template<viewable_range _Range>
1263 requires view<decay_t<_Range>>
1264 || __detail::__can_ref_view<_Range>
1265 || __detail::__can_owning_view<_Range>
1267 operator() [[nodiscard]] (_Range&& __r) const
1268 noexcept(_S_noexcept<_Range>())
1270 if constexpr (view<decay_t<_Range>>)
1271 return std::forward<_Range>(__r);
1272 else if constexpr (__detail::__can_ref_view<_Range>)
1273 return ref_view{std::forward<_Range>(__r)};
1275 return owning_view{std::forward<_Range>(__r)};
1278 static constexpr bool _S_has_simple_call_op = true;
1281 inline constexpr _All all;
1283 template<viewable_range _Range>
1284 using all_t = decltype(all(std::declval<_Range>()));
1285 } // namespace views
1289 template<typename _Tp>
1290 struct __non_propagating_cache
1292 // When _Tp is not an object type (e.g. is a reference type), we make
1293 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1294 // users can easily conditionally declare data members with this type
1295 // (such as join_view::_M_inner).
1298 template<typename _Tp>
1299 requires is_object_v<_Tp>
1300 struct __non_propagating_cache<_Tp>
1301 : protected _Optional_base<_Tp>
1303 __non_propagating_cache() = default;
1306 __non_propagating_cache(const __non_propagating_cache&) noexcept
1310 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1311 { __other._M_reset(); }
1313 constexpr __non_propagating_cache&
1314 operator=(const __non_propagating_cache& __other) noexcept
1316 if (std::__addressof(__other) != this)
1321 constexpr __non_propagating_cache&
1322 operator=(__non_propagating_cache&& __other) noexcept
1329 constexpr __non_propagating_cache&
1330 operator=(_Tp __val)
1333 this->_M_payload._M_construct(std::move(__val));
1338 operator bool() const noexcept
1339 { return this->_M_is_engaged(); }
1342 operator*() noexcept
1343 { return this->_M_get(); }
1345 constexpr const _Tp&
1346 operator*() const noexcept
1347 { return this->_M_get(); }
1349 template<typename _Iter>
1351 _M_emplace_deref(const _Iter& __i)
1354 auto __f = [] (auto& __x) { return *__x; };
1355 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1356 return this->_M_get();
1360 template<range _Range>
1361 struct _CachedPosition
1364 _M_has_value() const
1367 constexpr iterator_t<_Range>
1368 _M_get(const _Range&) const
1370 __glibcxx_assert(false);
1371 __builtin_unreachable();
1375 _M_set(const _Range&, const iterator_t<_Range>&) const
1379 template<forward_range _Range>
1380 struct _CachedPosition<_Range>
1381 : protected __non_propagating_cache<iterator_t<_Range>>
1384 _M_has_value() const
1385 { return this->_M_is_engaged(); }
1387 constexpr iterator_t<_Range>
1388 _M_get(const _Range&) const
1390 __glibcxx_assert(_M_has_value());
1395 _M_set(const _Range&, const iterator_t<_Range>& __it)
1397 __glibcxx_assert(!_M_has_value());
1398 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1400 this->_M_payload._M_engaged = true;
1404 template<random_access_range _Range>
1405 requires (sizeof(range_difference_t<_Range>)
1406 <= sizeof(iterator_t<_Range>))
1407 struct _CachedPosition<_Range>
1410 range_difference_t<_Range> _M_offset = -1;
1413 _CachedPosition() = default;
1416 _CachedPosition(const _CachedPosition&) = default;
1419 _CachedPosition(_CachedPosition&& __other) noexcept
1420 { *this = std::move(__other); }
1422 constexpr _CachedPosition&
1423 operator=(const _CachedPosition&) = default;
1425 constexpr _CachedPosition&
1426 operator=(_CachedPosition&& __other) noexcept
1428 // Propagate the cached offset, but invalidate the source.
1429 _M_offset = __other._M_offset;
1430 __other._M_offset = -1;
1435 _M_has_value() const
1436 { return _M_offset >= 0; }
1438 constexpr iterator_t<_Range>
1439 _M_get(_Range& __r) const
1441 __glibcxx_assert(_M_has_value());
1442 return ranges::begin(__r) + _M_offset;
1446 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1448 __glibcxx_assert(!_M_has_value());
1449 _M_offset = __it - ranges::begin(__r);
1452 } // namespace __detail
1456 template<typename _Base>
1457 struct __filter_view_iter_cat
1460 template<forward_range _Base>
1461 struct __filter_view_iter_cat<_Base>
1467 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1468 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1469 return bidirectional_iterator_tag{};
1470 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1471 return forward_iterator_tag{};
1476 using iterator_category = decltype(_S_iter_cat());
1478 } // namespace __detail
1480 template<input_range _Vp,
1481 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1482 requires view<_Vp> && is_object_v<_Pred>
1483 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1488 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1491 static constexpr auto
1494 if constexpr (bidirectional_range<_Vp>)
1495 return bidirectional_iterator_tag{};
1496 else if constexpr (forward_range<_Vp>)
1497 return forward_iterator_tag{};
1499 return input_iterator_tag{};
1504 using _Vp_iter = iterator_t<_Vp>;
1506 _Vp_iter _M_current = _Vp_iter();
1507 filter_view* _M_parent = nullptr;
1510 using iterator_concept = decltype(_S_iter_concept());
1511 // iterator_category defined in __filter_view_iter_cat
1512 using value_type = range_value_t<_Vp>;
1513 using difference_type = range_difference_t<_Vp>;
1515 _Iterator() requires default_initializable<_Vp_iter> = default;
1518 _Iterator(filter_view* __parent, _Vp_iter __current)
1519 : _M_current(std::move(__current)),
1523 constexpr const _Vp_iter&
1524 base() const & noexcept
1525 { return _M_current; }
1529 { return std::move(_M_current); }
1531 constexpr range_reference_t<_Vp>
1533 { return *_M_current; }
1537 requires __detail::__has_arrow<_Vp_iter>
1538 && copyable<_Vp_iter>
1539 { return _M_current; }
1541 constexpr _Iterator&
1544 _M_current = ranges::find_if(std::move(++_M_current),
1545 ranges::end(_M_parent->_M_base),
1546 std::ref(*_M_parent->_M_pred));
1555 operator++(int) requires forward_range<_Vp>
1562 constexpr _Iterator&
1563 operator--() requires bidirectional_range<_Vp>
1567 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1572 operator--(int) requires bidirectional_range<_Vp>
1579 friend constexpr bool
1580 operator==(const _Iterator& __x, const _Iterator& __y)
1581 requires equality_comparable<_Vp_iter>
1582 { return __x._M_current == __y._M_current; }
1584 friend constexpr range_rvalue_reference_t<_Vp>
1585 iter_move(const _Iterator& __i)
1586 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1587 { return ranges::iter_move(__i._M_current); }
1589 friend constexpr void
1590 iter_swap(const _Iterator& __x, const _Iterator& __y)
1591 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1592 requires indirectly_swappable<_Vp_iter>
1593 { ranges::iter_swap(__x._M_current, __y._M_current); }
1599 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1602 __equal(const _Iterator& __i) const
1603 { return __i._M_current == _M_end; }
1606 _Sentinel() = default;
1609 _Sentinel(filter_view* __parent)
1610 : _M_end(ranges::end(__parent->_M_base))
1613 constexpr sentinel_t<_Vp>
1617 friend constexpr bool
1618 operator==(const _Iterator& __x, const _Sentinel& __y)
1619 { return __y.__equal(__x); }
1622 _Vp _M_base = _Vp();
1623 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1624 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1627 filter_view() requires (default_initializable<_Vp>
1628 && default_initializable<_Pred>)
1632 filter_view(_Vp __base, _Pred __pred)
1633 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1637 base() const& requires copy_constructible<_Vp>
1642 { return std::move(_M_base); }
1644 constexpr const _Pred&
1646 { return *_M_pred; }
1651 if (_M_cached_begin._M_has_value())
1652 return {this, _M_cached_begin._M_get(_M_base)};
1654 __glibcxx_assert(_M_pred.has_value());
1655 auto __it = ranges::find_if(ranges::begin(_M_base),
1656 ranges::end(_M_base),
1657 std::ref(*_M_pred));
1658 _M_cached_begin._M_set(_M_base, __it);
1659 return {this, std::move(__it)};
1665 if constexpr (common_range<_Vp>)
1666 return _Iterator{this, ranges::end(_M_base)};
1668 return _Sentinel{this};
1672 template<typename _Range, typename _Pred>
1673 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1679 template<typename _Range, typename _Pred>
1680 concept __can_filter_view
1681 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1682 } // namespace __detail
1684 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1686 template<viewable_range _Range, typename _Pred>
1687 requires __detail::__can_filter_view<_Range, _Pred>
1689 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1691 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1694 using _RangeAdaptor<_Filter>::operator();
1695 static constexpr int _S_arity = 2;
1696 static constexpr bool _S_has_simple_extra_args = true;
1699 inline constexpr _Filter filter;
1700 } // namespace views
1702 template<input_range _Vp, copy_constructible _Fp>
1703 requires view<_Vp> && is_object_v<_Fp>
1704 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1705 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1706 range_reference_t<_Vp>>>
1707 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1710 template<bool _Const>
1711 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1713 template<bool _Const>
1717 template<bool _Const>
1718 requires forward_range<_Base<_Const>>
1719 struct __iter_cat<_Const>
1725 using _Base = transform_view::_Base<_Const>;
1726 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1727 if constexpr (is_lvalue_reference_v<_Res>)
1730 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1731 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1732 return random_access_iterator_tag{};
1737 return input_iterator_tag{};
1740 using iterator_category = decltype(_S_iter_cat());
1743 template<bool _Const>
1746 template<bool _Const>
1747 struct _Iterator : __iter_cat<_Const>
1750 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1751 using _Base = transform_view::_Base<_Const>;
1756 if constexpr (random_access_range<_Base>)
1757 return random_access_iterator_tag{};
1758 else if constexpr (bidirectional_range<_Base>)
1759 return bidirectional_iterator_tag{};
1760 else if constexpr (forward_range<_Base>)
1761 return forward_iterator_tag{};
1763 return input_iterator_tag{};
1766 using _Base_iter = iterator_t<_Base>;
1768 _Base_iter _M_current = _Base_iter();
1769 _Parent* _M_parent = nullptr;
1772 using iterator_concept = decltype(_S_iter_concept());
1773 // iterator_category defined in __transform_view_iter_cat
1775 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1776 using difference_type = range_difference_t<_Base>;
1778 _Iterator() requires default_initializable<_Base_iter> = default;
1781 _Iterator(_Parent* __parent, _Base_iter __current)
1782 : _M_current(std::move(__current)),
1787 _Iterator(_Iterator<!_Const> __i)
1789 && convertible_to<iterator_t<_Vp>, _Base_iter>
1790 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1793 constexpr const _Base_iter&
1794 base() const & noexcept
1795 { return _M_current; }
1797 constexpr _Base_iter
1799 { return std::move(_M_current); }
1801 constexpr decltype(auto)
1803 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1804 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1806 constexpr _Iterator&
1818 operator++(int) requires forward_range<_Base>
1825 constexpr _Iterator&
1826 operator--() requires bidirectional_range<_Base>
1833 operator--(int) requires bidirectional_range<_Base>
1840 constexpr _Iterator&
1841 operator+=(difference_type __n) requires random_access_range<_Base>
1847 constexpr _Iterator&
1848 operator-=(difference_type __n) requires random_access_range<_Base>
1854 constexpr decltype(auto)
1855 operator[](difference_type __n) const
1856 requires random_access_range<_Base>
1857 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1859 friend constexpr bool
1860 operator==(const _Iterator& __x, const _Iterator& __y)
1861 requires equality_comparable<_Base_iter>
1862 { return __x._M_current == __y._M_current; }
1864 friend constexpr bool
1865 operator<(const _Iterator& __x, const _Iterator& __y)
1866 requires random_access_range<_Base>
1867 { return __x._M_current < __y._M_current; }
1869 friend constexpr bool
1870 operator>(const _Iterator& __x, const _Iterator& __y)
1871 requires random_access_range<_Base>
1872 { return __y < __x; }
1874 friend constexpr bool
1875 operator<=(const _Iterator& __x, const _Iterator& __y)
1876 requires random_access_range<_Base>
1877 { return !(__y < __x); }
1879 friend constexpr bool
1880 operator>=(const _Iterator& __x, const _Iterator& __y)
1881 requires random_access_range<_Base>
1882 { return !(__x < __y); }
1884 #ifdef __cpp_lib_three_way_comparison
1885 friend constexpr auto
1886 operator<=>(const _Iterator& __x, const _Iterator& __y)
1887 requires random_access_range<_Base>
1888 && three_way_comparable<_Base_iter>
1889 { return __x._M_current <=> __y._M_current; }
1892 friend constexpr _Iterator
1893 operator+(_Iterator __i, difference_type __n)
1894 requires random_access_range<_Base>
1895 { return {__i._M_parent, __i._M_current + __n}; }
1897 friend constexpr _Iterator
1898 operator+(difference_type __n, _Iterator __i)
1899 requires random_access_range<_Base>
1900 { return {__i._M_parent, __i._M_current + __n}; }
1902 friend constexpr _Iterator
1903 operator-(_Iterator __i, difference_type __n)
1904 requires random_access_range<_Base>
1905 { return {__i._M_parent, __i._M_current - __n}; }
1907 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1908 // 3483. transform_view::iterator's difference is overconstrained
1909 friend constexpr difference_type
1910 operator-(const _Iterator& __x, const _Iterator& __y)
1911 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1912 { return __x._M_current - __y._M_current; }
1914 friend constexpr decltype(auto)
1915 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1917 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1918 return std::move(*__i);
1923 friend _Iterator<!_Const>;
1924 template<bool> friend struct _Sentinel;
1927 template<bool _Const>
1931 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1932 using _Base = transform_view::_Base<_Const>;
1934 template<bool _Const2>
1936 __distance_from(const _Iterator<_Const2>& __i) const
1937 { return _M_end - __i._M_current; }
1939 template<bool _Const2>
1941 __equal(const _Iterator<_Const2>& __i) const
1942 { return __i._M_current == _M_end; }
1944 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1947 _Sentinel() = default;
1950 _Sentinel(sentinel_t<_Base> __end)
1955 _Sentinel(_Sentinel<!_Const> __i)
1957 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1958 : _M_end(std::move(__i._M_end))
1961 constexpr sentinel_t<_Base>
1965 template<bool _Const2>
1966 requires sentinel_for<sentinel_t<_Base>,
1967 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1968 friend constexpr bool
1969 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1970 { return __y.__equal(__x); }
1972 template<bool _Const2,
1973 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1974 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1975 friend constexpr range_difference_t<_Base2>
1976 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1977 { return -__y.__distance_from(__x); }
1979 template<bool _Const2,
1980 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
1981 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
1982 friend constexpr range_difference_t<_Base2>
1983 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
1984 { return __y.__distance_from(__x); }
1986 friend _Sentinel<!_Const>;
1989 _Vp _M_base = _Vp();
1990 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
1993 transform_view() requires (default_initializable<_Vp>
1994 && default_initializable<_Fp>)
1998 transform_view(_Vp __base, _Fp __fun)
1999 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2003 base() const& requires copy_constructible<_Vp>
2004 { return _M_base ; }
2008 { return std::move(_M_base); }
2010 constexpr _Iterator<false>
2012 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2014 constexpr _Iterator<true>
2016 requires range<const _Vp>
2017 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2018 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2020 constexpr _Sentinel<false>
2022 { return _Sentinel<false>{ranges::end(_M_base)}; }
2024 constexpr _Iterator<false>
2025 end() requires common_range<_Vp>
2026 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2028 constexpr _Sentinel<true>
2030 requires range<const _Vp>
2031 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2032 { return _Sentinel<true>{ranges::end(_M_base)}; }
2034 constexpr _Iterator<true>
2036 requires common_range<const _Vp>
2037 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2038 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2041 size() requires sized_range<_Vp>
2042 { return ranges::size(_M_base); }
2045 size() const requires sized_range<const _Vp>
2046 { return ranges::size(_M_base); }
2049 template<typename _Range, typename _Fp>
2050 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2056 template<typename _Range, typename _Fp>
2057 concept __can_transform_view
2058 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2059 } // namespace __detail
2061 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2063 template<viewable_range _Range, typename _Fp>
2064 requires __detail::__can_transform_view<_Range, _Fp>
2066 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2068 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2071 using _RangeAdaptor<_Transform>::operator();
2072 static constexpr int _S_arity = 2;
2073 static constexpr bool _S_has_simple_extra_args = true;
2076 inline constexpr _Transform transform;
2077 } // namespace views
2080 class take_view : public view_interface<take_view<_Vp>>
2083 template<bool _Const>
2084 using _CI = counted_iterator<
2085 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2087 template<bool _Const>
2091 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2092 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2095 _Sentinel() = default;
2098 _Sentinel(sentinel_t<_Base> __end)
2103 _Sentinel(_Sentinel<!_Const> __s)
2104 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2105 : _M_end(std::move(__s._M_end))
2108 constexpr sentinel_t<_Base>
2112 friend constexpr bool
2113 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2114 { return __y.count() == 0 || __y.base() == __x._M_end; }
2116 template<bool _OtherConst = !_Const,
2117 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2118 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2119 friend constexpr bool
2120 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2121 { return __y.count() == 0 || __y.base() == __x._M_end; }
2123 friend _Sentinel<!_Const>;
2126 _Vp _M_base = _Vp();
2127 range_difference_t<_Vp> _M_count = 0;
2130 take_view() requires default_initializable<_Vp> = default;
2133 take_view(_Vp __base, range_difference_t<_Vp> __count)
2134 : _M_base(std::move(__base)), _M_count(std::move(__count))
2138 base() const& requires copy_constructible<_Vp>
2143 { return std::move(_M_base); }
2146 begin() requires (!__detail::__simple_view<_Vp>)
2148 if constexpr (sized_range<_Vp>)
2150 if constexpr (random_access_range<_Vp>)
2151 return ranges::begin(_M_base);
2155 return counted_iterator(ranges::begin(_M_base), __sz);
2159 return counted_iterator(ranges::begin(_M_base), _M_count);
2163 begin() const requires range<const _Vp>
2165 if constexpr (sized_range<const _Vp>)
2167 if constexpr (random_access_range<const _Vp>)
2168 return ranges::begin(_M_base);
2172 return counted_iterator(ranges::begin(_M_base), __sz);
2176 return counted_iterator(ranges::begin(_M_base), _M_count);
2180 end() requires (!__detail::__simple_view<_Vp>)
2182 if constexpr (sized_range<_Vp>)
2184 if constexpr (random_access_range<_Vp>)
2185 return ranges::begin(_M_base) + size();
2187 return default_sentinel;
2190 return _Sentinel<false>{ranges::end(_M_base)};
2194 end() const requires range<const _Vp>
2196 if constexpr (sized_range<const _Vp>)
2198 if constexpr (random_access_range<const _Vp>)
2199 return ranges::begin(_M_base) + size();
2201 return default_sentinel;
2204 return _Sentinel<true>{ranges::end(_M_base)};
2208 size() requires sized_range<_Vp>
2210 auto __n = ranges::size(_M_base);
2211 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2215 size() const requires sized_range<const _Vp>
2217 auto __n = ranges::size(_M_base);
2218 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2222 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2223 // 3447. Deduction guides for take_view and drop_view have different
2225 template<typename _Range>
2226 take_view(_Range&&, range_difference_t<_Range>)
2227 -> take_view<views::all_t<_Range>>;
2229 template<typename _Tp>
2230 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2231 = enable_borrowed_range<_Tp>;
2237 template<typename _Range>
2238 inline constexpr bool __is_empty_view = false;
2240 template<typename _Tp>
2241 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2243 template<typename _Range>
2244 inline constexpr bool __is_basic_string_view = false;
2246 template<typename _CharT, typename _Traits>
2247 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2250 template<typename _Range>
2251 inline constexpr bool __is_subrange = false;
2253 template<typename _Iter, typename _Sent, subrange_kind _Kind>
2254 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
2256 template<typename _Range>
2257 inline constexpr bool __is_iota_view = false;
2259 template<typename _Winc, typename _Bound>
2260 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2262 template<typename _Range>
2263 inline constexpr bool __is_repeat_view = false;
2265 template<typename _Range>
2267 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2269 template<typename _Range, typename _Dp>
2270 concept __can_take_view
2271 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2272 } // namespace __detail
2274 struct _Take : __adaptor::_RangeAdaptor<_Take>
2276 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2277 requires __detail::__can_take_view<_Range, _Dp>
2279 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2281 using _Tp = remove_cvref_t<_Range>;
2282 if constexpr (__detail::__is_empty_view<_Tp>)
2284 else if constexpr (random_access_range<_Tp>
2286 && (std::__detail::__is_span<_Tp>
2287 || __detail::__is_basic_string_view<_Tp>
2288 || __detail::__is_subrange<_Tp>
2289 || __detail::__is_iota_view<_Tp>))
2291 __n = std::min<_Dp>(ranges::distance(__r), __n);
2292 auto __begin = ranges::begin(__r);
2293 auto __end = __begin + __n;
2294 if constexpr (std::__detail::__is_span<_Tp>)
2295 return span<typename _Tp::element_type>(__begin, __end);
2296 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2297 return _Tp(__begin, __end);
2298 else if constexpr (__detail::__is_subrange<_Tp>)
2299 return subrange<iterator_t<_Tp>>(__begin, __end);
2301 return iota_view(*__begin, *__end);
2303 else if constexpr (__detail::__is_repeat_view<_Tp>)
2304 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2306 return take_view(std::forward<_Range>(__r), __n);
2309 using _RangeAdaptor<_Take>::operator();
2310 static constexpr int _S_arity = 2;
2311 // The count argument of views::take is not always simple -- it can be
2312 // e.g. a move-only class that's implicitly convertible to the difference
2313 // type. But an integer-like count argument is surely simple.
2314 template<typename _Tp>
2315 static constexpr bool _S_has_simple_extra_args
2316 = ranges::__detail::__is_integer_like<_Tp>;
2319 inline constexpr _Take take;
2320 } // namespace views
2322 template<view _Vp, typename _Pred>
2323 requires input_range<_Vp> && is_object_v<_Pred>
2324 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2325 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2327 template<bool _Const>
2331 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2333 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2334 const _Pred* _M_pred = nullptr;
2337 _Sentinel() = default;
2340 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2341 : _M_end(__end), _M_pred(__pred)
2345 _Sentinel(_Sentinel<!_Const> __s)
2346 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2347 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2350 constexpr sentinel_t<_Base>
2351 base() const { return _M_end; }
2353 friend constexpr bool
2354 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2355 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2357 template<bool _OtherConst = !_Const,
2358 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2359 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2360 friend constexpr bool
2361 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2362 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2364 friend _Sentinel<!_Const>;
2367 _Vp _M_base = _Vp();
2368 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2371 take_while_view() requires (default_initializable<_Vp>
2372 && default_initializable<_Pred>)
2376 take_while_view(_Vp __base, _Pred __pred)
2377 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2381 base() const& requires copy_constructible<_Vp>
2386 { return std::move(_M_base); }
2388 constexpr const _Pred&
2390 { return *_M_pred; }
2393 begin() requires (!__detail::__simple_view<_Vp>)
2394 { return ranges::begin(_M_base); }
2397 begin() const requires range<const _Vp>
2398 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2399 { return ranges::begin(_M_base); }
2402 end() requires (!__detail::__simple_view<_Vp>)
2403 { return _Sentinel<false>(ranges::end(_M_base),
2404 std::__addressof(*_M_pred)); }
2407 end() const requires range<const _Vp>
2408 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2409 { return _Sentinel<true>(ranges::end(_M_base),
2410 std::__addressof(*_M_pred)); }
2413 template<typename _Range, typename _Pred>
2414 take_while_view(_Range&&, _Pred)
2415 -> take_while_view<views::all_t<_Range>, _Pred>;
2421 template<typename _Range, typename _Pred>
2422 concept __can_take_while_view
2423 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2424 } // namespace __detail
2426 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2428 template<viewable_range _Range, typename _Pred>
2429 requires __detail::__can_take_while_view<_Range, _Pred>
2431 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2433 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2436 using _RangeAdaptor<_TakeWhile>::operator();
2437 static constexpr int _S_arity = 2;
2438 static constexpr bool _S_has_simple_extra_args = true;
2441 inline constexpr _TakeWhile take_while;
2442 } // namespace views
2445 class drop_view : public view_interface<drop_view<_Vp>>
2448 _Vp _M_base = _Vp();
2449 range_difference_t<_Vp> _M_count = 0;
2451 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2452 // both random_access_range and sized_range. Otherwise, cache its result.
2453 static constexpr bool _S_needs_cached_begin
2454 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2455 [[no_unique_address]]
2456 __detail::__maybe_present_t<_S_needs_cached_begin,
2457 __detail::_CachedPosition<_Vp>>
2461 drop_view() requires default_initializable<_Vp> = default;
2464 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2465 : _M_base(std::move(__base)), _M_count(__count)
2466 { __glibcxx_assert(__count >= 0); }
2469 base() const& requires copy_constructible<_Vp>
2474 { return std::move(_M_base); }
2476 // This overload is disabled for simple views with constant-time begin().
2479 requires (!(__detail::__simple_view<_Vp>
2480 && random_access_range<const _Vp>
2481 && sized_range<const _Vp>))
2483 if constexpr (_S_needs_cached_begin)
2484 if (_M_cached_begin._M_has_value())
2485 return _M_cached_begin._M_get(_M_base);
2487 auto __it = ranges::next(ranges::begin(_M_base),
2488 _M_count, ranges::end(_M_base));
2489 if constexpr (_S_needs_cached_begin)
2490 _M_cached_begin._M_set(_M_base, __it);
2494 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2495 // 3482. drop_view's const begin should additionally require sized_range
2498 requires random_access_range<const _Vp> && sized_range<const _Vp>
2500 return ranges::next(ranges::begin(_M_base), _M_count,
2501 ranges::end(_M_base));
2505 end() requires (!__detail::__simple_view<_Vp>)
2506 { return ranges::end(_M_base); }
2509 end() const requires range<const _Vp>
2510 { return ranges::end(_M_base); }
2513 size() requires sized_range<_Vp>
2515 const auto __s = ranges::size(_M_base);
2516 const auto __c = static_cast<decltype(__s)>(_M_count);
2517 return __s < __c ? 0 : __s - __c;
2521 size() const requires sized_range<const _Vp>
2523 const auto __s = ranges::size(_M_base);
2524 const auto __c = static_cast<decltype(__s)>(_M_count);
2525 return __s < __c ? 0 : __s - __c;
2529 template<typename _Range>
2530 drop_view(_Range&&, range_difference_t<_Range>)
2531 -> drop_view<views::all_t<_Range>>;
2533 template<typename _Tp>
2534 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2535 = enable_borrowed_range<_Tp>;
2541 template<typename _Range>
2543 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2545 template<typename _Range, typename _Dp>
2546 concept __can_drop_view
2547 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2548 } // namespace __detail
2550 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2552 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2553 requires __detail::__can_drop_view<_Range, _Dp>
2555 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2557 using _Tp = remove_cvref_t<_Range>;
2558 if constexpr (__detail::__is_empty_view<_Tp>)
2560 else if constexpr (random_access_range<_Tp>
2562 && (std::__detail::__is_span<_Tp>
2563 || __detail::__is_basic_string_view<_Tp>
2564 || __detail::__is_iota_view<_Tp>
2565 || __detail::__is_subrange<_Tp>))
2567 __n = std::min<_Dp>(ranges::distance(__r), __n);
2568 auto __begin = ranges::begin(__r) + __n;
2569 auto __end = ranges::end(__r);
2570 if constexpr (std::__detail::__is_span<_Tp>)
2571 return span<typename _Tp::element_type>(__begin, __end);
2572 else if constexpr (__detail::__is_subrange<_Tp>)
2574 if constexpr (_Tp::_S_store_size)
2576 using ranges::__detail::__to_unsigned_like;
2577 auto __m = ranges::distance(__r) - __n;
2578 return _Tp(__begin, __end, __to_unsigned_like(__m));
2581 return _Tp(__begin, __end);
2584 return _Tp(__begin, __end);
2586 else if constexpr (__detail::__is_repeat_view<_Tp>)
2587 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2589 return drop_view(std::forward<_Range>(__r), __n);
2592 using _RangeAdaptor<_Drop>::operator();
2593 static constexpr int _S_arity = 2;
2594 template<typename _Tp>
2595 static constexpr bool _S_has_simple_extra_args
2596 = _Take::_S_has_simple_extra_args<_Tp>;
2599 inline constexpr _Drop drop;
2600 } // namespace views
2602 template<view _Vp, typename _Pred>
2603 requires input_range<_Vp> && is_object_v<_Pred>
2604 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2605 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2608 _Vp _M_base = _Vp();
2609 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2610 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2613 drop_while_view() requires (default_initializable<_Vp>
2614 && default_initializable<_Pred>)
2618 drop_while_view(_Vp __base, _Pred __pred)
2619 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2623 base() const& requires copy_constructible<_Vp>
2628 { return std::move(_M_base); }
2630 constexpr const _Pred&
2632 { return *_M_pred; }
2637 if (_M_cached_begin._M_has_value())
2638 return _M_cached_begin._M_get(_M_base);
2640 __glibcxx_assert(_M_pred.has_value());
2641 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2642 ranges::end(_M_base),
2643 std::cref(*_M_pred));
2644 _M_cached_begin._M_set(_M_base, __it);
2650 { return ranges::end(_M_base); }
2653 template<typename _Range, typename _Pred>
2654 drop_while_view(_Range&&, _Pred)
2655 -> drop_while_view<views::all_t<_Range>, _Pred>;
2657 template<typename _Tp, typename _Pred>
2658 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2659 = enable_borrowed_range<_Tp>;
2665 template<typename _Range, typename _Pred>
2666 concept __can_drop_while_view
2667 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2668 } // namespace __detail
2670 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2672 template<viewable_range _Range, typename _Pred>
2673 requires __detail::__can_drop_while_view<_Range, _Pred>
2675 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2677 return drop_while_view(std::forward<_Range>(__r),
2678 std::forward<_Pred>(__p));
2681 using _RangeAdaptor<_DropWhile>::operator();
2682 static constexpr int _S_arity = 2;
2683 static constexpr bool _S_has_simple_extra_args = true;
2686 inline constexpr _DropWhile drop_while;
2687 } // namespace views
2689 template<input_range _Vp>
2690 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2691 class join_view : public view_interface<join_view<_Vp>>
2694 using _InnerRange = range_reference_t<_Vp>;
2696 template<bool _Const>
2697 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2699 template<bool _Const>
2700 using _Outer_iter = iterator_t<_Base<_Const>>;
2702 template<bool _Const>
2703 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2705 template<bool _Const>
2706 static constexpr bool _S_ref_is_glvalue
2707 = is_reference_v<range_reference_t<_Base<_Const>>>;
2709 template<bool _Const>
2713 template<bool _Const>
2714 requires _S_ref_is_glvalue<_Const>
2715 && forward_range<_Base<_Const>>
2716 && forward_range<range_reference_t<_Base<_Const>>>
2717 struct __iter_cat<_Const>
2720 static constexpr auto
2723 using _Outer_iter = join_view::_Outer_iter<_Const>;
2724 using _Inner_iter = join_view::_Inner_iter<_Const>;
2725 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2726 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2727 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2728 && derived_from<_InnerCat, bidirectional_iterator_tag>
2729 && common_range<range_reference_t<_Base<_Const>>>)
2730 return bidirectional_iterator_tag{};
2731 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2732 && derived_from<_InnerCat, forward_iterator_tag>)
2733 return forward_iterator_tag{};
2735 return input_iterator_tag{};
2738 using iterator_category = decltype(_S_iter_cat());
2741 template<bool _Const>
2744 template<bool _Const>
2745 struct _Iterator : __iter_cat<_Const>
2748 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2749 using _Base = join_view::_Base<_Const>;
2751 static constexpr bool _S_ref_is_glvalue
2752 = join_view::_S_ref_is_glvalue<_Const>;
2757 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2758 if constexpr (_S_ref_is_glvalue)
2761 return _M_parent->_M_inner._M_emplace_deref(__x);
2764 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2766 auto&& __inner = __update_inner(_M_outer);
2767 _M_inner = ranges::begin(__inner);
2768 if (_M_inner != ranges::end(__inner))
2772 if constexpr (_S_ref_is_glvalue)
2776 static constexpr auto
2779 if constexpr (_S_ref_is_glvalue
2780 && bidirectional_range<_Base>
2781 && bidirectional_range<range_reference_t<_Base>>
2782 && common_range<range_reference_t<_Base>>)
2783 return bidirectional_iterator_tag{};
2784 else if constexpr (_S_ref_is_glvalue
2785 && forward_range<_Base>
2786 && forward_range<range_reference_t<_Base>>)
2787 return forward_iterator_tag{};
2789 return input_iterator_tag{};
2792 using _Outer_iter = join_view::_Outer_iter<_Const>;
2793 using _Inner_iter = join_view::_Inner_iter<_Const>;
2795 _Outer_iter _M_outer = _Outer_iter();
2796 optional<_Inner_iter> _M_inner;
2797 _Parent* _M_parent = nullptr;
2800 using iterator_concept = decltype(_S_iter_concept());
2801 // iterator_category defined in __join_view_iter_cat
2802 using value_type = range_value_t<range_reference_t<_Base>>;
2803 using difference_type
2804 = common_type_t<range_difference_t<_Base>,
2805 range_difference_t<range_reference_t<_Base>>>;
2807 _Iterator() requires default_initializable<_Outer_iter> = default;
2810 _Iterator(_Parent* __parent, _Outer_iter __outer)
2811 : _M_outer(std::move(__outer)),
2816 _Iterator(_Iterator<!_Const> __i)
2818 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2819 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2820 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2821 _M_parent(__i._M_parent)
2824 constexpr decltype(auto)
2826 { return **_M_inner; }
2828 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2829 // 3500. join_view::iterator::operator->() is bogus
2830 constexpr _Inner_iter
2832 requires __detail::__has_arrow<_Inner_iter>
2833 && copyable<_Inner_iter>
2834 { return *_M_inner; }
2836 constexpr _Iterator&
2839 auto&& __inner_range = [this] () -> auto&& {
2840 if constexpr (_S_ref_is_glvalue)
2843 return *_M_parent->_M_inner;
2845 if (++*_M_inner == ranges::end(__inner_range))
2859 requires _S_ref_is_glvalue && forward_range<_Base>
2860 && forward_range<range_reference_t<_Base>>
2867 constexpr _Iterator&
2869 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2870 && bidirectional_range<range_reference_t<_Base>>
2871 && common_range<range_reference_t<_Base>>
2873 if (_M_outer == ranges::end(_M_parent->_M_base))
2874 _M_inner = ranges::end(*--_M_outer);
2875 while (*_M_inner == ranges::begin(*_M_outer))
2876 *_M_inner = ranges::end(*--_M_outer);
2883 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2884 && bidirectional_range<range_reference_t<_Base>>
2885 && common_range<range_reference_t<_Base>>
2892 friend constexpr bool
2893 operator==(const _Iterator& __x, const _Iterator& __y)
2894 requires _S_ref_is_glvalue
2895 && equality_comparable<_Outer_iter>
2896 && equality_comparable<_Inner_iter>
2898 return (__x._M_outer == __y._M_outer
2899 && __x._M_inner == __y._M_inner);
2902 friend constexpr decltype(auto)
2903 iter_move(const _Iterator& __i)
2904 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
2905 { return ranges::iter_move(*__i._M_inner); }
2907 friend constexpr void
2908 iter_swap(const _Iterator& __x, const _Iterator& __y)
2909 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
2910 requires indirectly_swappable<_Inner_iter>
2911 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
2913 friend _Iterator<!_Const>;
2914 template<bool> friend struct _Sentinel;
2917 template<bool _Const>
2921 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2922 using _Base = join_view::_Base<_Const>;
2924 template<bool _Const2>
2926 __equal(const _Iterator<_Const2>& __i) const
2927 { return __i._M_outer == _M_end; }
2929 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2932 _Sentinel() = default;
2935 _Sentinel(_Parent* __parent)
2936 : _M_end(ranges::end(__parent->_M_base))
2940 _Sentinel(_Sentinel<!_Const> __s)
2941 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2942 : _M_end(std::move(__s._M_end))
2945 template<bool _Const2>
2946 requires sentinel_for<sentinel_t<_Base>,
2947 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2948 friend constexpr bool
2949 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2950 { return __y.__equal(__x); }
2952 friend _Sentinel<!_Const>;
2955 _Vp _M_base = _Vp();
2956 [[no_unique_address]]
2957 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2960 join_view() requires default_initializable<_Vp> = default;
2963 join_view(_Vp __base)
2964 : _M_base(std::move(__base))
2968 base() const& requires copy_constructible<_Vp>
2973 { return std::move(_M_base); }
2978 constexpr bool __use_const
2979 = (__detail::__simple_view<_Vp>
2980 && is_reference_v<range_reference_t<_Vp>>);
2981 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
2986 requires input_range<const _Vp>
2987 && is_reference_v<range_reference_t<const _Vp>>
2989 return _Iterator<true>{this, ranges::begin(_M_base)};
2995 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
2996 && forward_range<_InnerRange>
2997 && common_range<_Vp> && common_range<_InnerRange>)
2998 return _Iterator<__detail::__simple_view<_Vp>>{this,
2999 ranges::end(_M_base)};
3001 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3006 requires input_range<const _Vp>
3007 && is_reference_v<range_reference_t<const _Vp>>
3009 if constexpr (forward_range<const _Vp>
3010 && is_reference_v<range_reference_t<const _Vp>>
3011 && forward_range<range_reference_t<const _Vp>>
3012 && common_range<const _Vp>
3013 && common_range<range_reference_t<const _Vp>>)
3014 return _Iterator<true>{this, ranges::end(_M_base)};
3016 return _Sentinel<true>{this};
3020 template<typename _Range>
3021 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3027 template<typename _Range>
3028 concept __can_join_view
3029 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3030 } // namespace __detail
3032 struct _Join : __adaptor::_RangeAdaptorClosure
3034 template<viewable_range _Range>
3035 requires __detail::__can_join_view<_Range>
3037 operator() [[nodiscard]] (_Range&& __r) const
3039 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3040 // 3474. Nesting join_views is broken because of CTAD
3041 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3044 static constexpr bool _S_has_simple_call_op = true;
3047 inline constexpr _Join join;
3048 } // namespace views
3053 struct __require_constant;
3055 template<typename _Range>
3056 concept __tiny_range = sized_range<_Range>
3058 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3059 && (remove_reference_t<_Range>::size() <= 1);
3061 template<typename _Base>
3062 struct __lazy_split_view_outer_iter_cat
3065 template<forward_range _Base>
3066 struct __lazy_split_view_outer_iter_cat<_Base>
3067 { using iterator_category = input_iterator_tag; };
3069 template<typename _Base>
3070 struct __lazy_split_view_inner_iter_cat
3073 template<forward_range _Base>
3074 struct __lazy_split_view_inner_iter_cat<_Base>
3077 static constexpr auto
3080 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3081 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3082 return forward_iterator_tag{};
3087 using iterator_category = decltype(_S_iter_cat());
3091 template<input_range _Vp, forward_range _Pattern>
3092 requires view<_Vp> && view<_Pattern>
3093 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3095 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3096 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3099 template<bool _Const>
3100 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3102 template<bool _Const>
3105 template<bool _Const>
3107 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3110 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3111 using _Base = lazy_split_view::_Base<_Const>;
3115 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3117 // [range.lazy.split.outer] p1
3118 // Many of the following specifications refer to the notional member
3119 // current of outer-iterator. current is equivalent to current_ if
3120 // V models forward_range, and parent_->current_ otherwise.
3122 __current() noexcept
3124 if constexpr (forward_range<_Vp>)
3127 return *_M_parent->_M_current;
3131 __current() const noexcept
3133 if constexpr (forward_range<_Vp>)
3136 return *_M_parent->_M_current;
3139 _Parent* _M_parent = nullptr;
3141 [[no_unique_address]]
3142 __detail::__maybe_present_t<forward_range<_Vp>,
3143 iterator_t<_Base>> _M_current;
3144 bool _M_trailing_empty = false;
3147 using iterator_concept = __conditional_t<forward_range<_Base>,
3148 forward_iterator_tag,
3149 input_iterator_tag>;
3150 // iterator_category defined in __lazy_split_view_outer_iter_cat
3151 using difference_type = range_difference_t<_Base>;
3153 struct value_type : view_interface<value_type>
3156 _OuterIter _M_i = _OuterIter();
3159 value_type() = default;
3162 value_type(_OuterIter __i)
3163 : _M_i(std::move(__i))
3166 constexpr _InnerIter<_Const>
3168 { return _InnerIter<_Const>{_M_i}; }
3170 constexpr default_sentinel_t
3171 end() const noexcept
3172 { return default_sentinel; }
3175 _OuterIter() = default;
3178 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3179 : _M_parent(__parent)
3183 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3184 requires forward_range<_Base>
3185 : _M_parent(__parent),
3186 _M_current(std::move(__current))
3190 _OuterIter(_OuterIter<!_Const> __i)
3192 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3193 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
3196 constexpr value_type
3198 { return value_type{*this}; }
3200 constexpr _OuterIter&
3203 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3204 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3205 const auto __end = ranges::end(_M_parent->_M_base);
3206 if (__current() == __end)
3208 _M_trailing_empty = false;
3211 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3212 if (__pbegin == __pend)
3214 else if constexpr (__detail::__tiny_range<_Pattern>)
3216 __current() = ranges::find(std::move(__current()), __end,
3218 if (__current() != __end)
3221 if (__current() == __end)
3222 _M_trailing_empty = true;
3229 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3233 if (__current() == __end)
3234 _M_trailing_empty = true;
3237 } while (++__current() != __end);
3241 constexpr decltype(auto)
3244 if constexpr (forward_range<_Base>)
3254 friend constexpr bool
3255 operator==(const _OuterIter& __x, const _OuterIter& __y)
3256 requires forward_range<_Base>
3258 return __x._M_current == __y._M_current
3259 && __x._M_trailing_empty == __y._M_trailing_empty;
3262 friend constexpr bool
3263 operator==(const _OuterIter& __x, default_sentinel_t)
3264 { return __x.__at_end(); };
3266 friend _OuterIter<!_Const>;
3267 friend _InnerIter<_Const>;
3270 template<bool _Const>
3272 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3275 using _Base = lazy_split_view::_Base<_Const>;
3280 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3281 auto __end = ranges::end(_M_i._M_parent->_M_base);
3282 if constexpr (__detail::__tiny_range<_Pattern>)
3284 const auto& __cur = _M_i_current();
3287 if (__pcur == __pend)
3288 return _M_incremented;
3289 return *__cur == *__pcur;
3293 auto __cur = _M_i_current();
3296 if (__pcur == __pend)
3297 return _M_incremented;
3300 if (*__cur != *__pcur)
3302 if (++__pcur == __pend)
3304 } while (++__cur != __end);
3310 _M_i_current() noexcept
3311 { return _M_i.__current(); }
3314 _M_i_current() const noexcept
3315 { return _M_i.__current(); }
3317 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3318 bool _M_incremented = false;
3321 using iterator_concept
3322 = typename _OuterIter<_Const>::iterator_concept;
3323 // iterator_category defined in __lazy_split_view_inner_iter_cat
3324 using value_type = range_value_t<_Base>;
3325 using difference_type = range_difference_t<_Base>;
3327 _InnerIter() = default;
3330 _InnerIter(_OuterIter<_Const> __i)
3331 : _M_i(std::move(__i))
3334 constexpr const iterator_t<_Base>&
3335 base() const& noexcept
3336 { return _M_i_current(); }
3338 constexpr iterator_t<_Base>
3339 base() && requires forward_range<_Vp>
3340 { return std::move(_M_i_current()); }
3342 constexpr decltype(auto)
3344 { return *_M_i_current(); }
3346 constexpr _InnerIter&
3349 _M_incremented = true;
3350 if constexpr (!forward_range<_Base>)
3351 if constexpr (_Pattern::size() == 0)
3357 constexpr decltype(auto)
3360 if constexpr (forward_range<_Base>)
3370 friend constexpr bool
3371 operator==(const _InnerIter& __x, const _InnerIter& __y)
3372 requires forward_range<_Base>
3373 { return __x._M_i == __y._M_i; }
3375 friend constexpr bool
3376 operator==(const _InnerIter& __x, default_sentinel_t)
3377 { return __x.__at_end(); }
3379 friend constexpr decltype(auto)
3380 iter_move(const _InnerIter& __i)
3381 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3382 { return ranges::iter_move(__i._M_i_current()); }
3384 friend constexpr void
3385 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3386 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3387 __y._M_i_current())))
3388 requires indirectly_swappable<iterator_t<_Base>>
3389 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3392 _Vp _M_base = _Vp();
3393 _Pattern _M_pattern = _Pattern();
3394 [[no_unique_address]]
3395 __detail::__maybe_present_t<!forward_range<_Vp>,
3396 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3400 lazy_split_view() requires (default_initializable<_Vp>
3401 && default_initializable<_Pattern>)
3405 lazy_split_view(_Vp __base, _Pattern __pattern)
3406 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3409 template<input_range _Range>
3410 requires constructible_from<_Vp, views::all_t<_Range>>
3411 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3413 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3414 : _M_base(views::all(std::forward<_Range>(__r))),
3415 _M_pattern(views::single(std::move(__e)))
3419 base() const& requires copy_constructible<_Vp>
3424 { return std::move(_M_base); }
3429 if constexpr (forward_range<_Vp>)
3431 constexpr bool __simple
3432 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3433 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3437 _M_current = ranges::begin(_M_base);
3438 return _OuterIter<false>{this};
3443 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3445 return _OuterIter<true>{this, ranges::begin(_M_base)};
3449 end() requires forward_range<_Vp> && common_range<_Vp>
3451 constexpr bool __simple
3452 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3453 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3459 if constexpr (forward_range<_Vp>
3460 && forward_range<const _Vp>
3461 && common_range<const _Vp>)
3462 return _OuterIter<true>{this, ranges::end(_M_base)};
3464 return default_sentinel;
3468 template<typename _Range, typename _Pattern>
3469 lazy_split_view(_Range&&, _Pattern&&)
3470 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3472 template<input_range _Range>
3473 lazy_split_view(_Range&&, range_value_t<_Range>)
3474 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3480 template<typename _Range, typename _Pattern>
3481 concept __can_lazy_split_view
3482 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3483 } // namespace __detail
3485 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3487 template<viewable_range _Range, typename _Pattern>
3488 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3490 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3492 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3495 using _RangeAdaptor<_LazySplit>::operator();
3496 static constexpr int _S_arity = 2;
3497 // The pattern argument of views::lazy_split is not always simple -- it can be
3498 // a non-view range, the value category of which affects whether the call
3499 // is well-formed. But a scalar or a view pattern argument is surely
3501 template<typename _Pattern>
3502 static constexpr bool _S_has_simple_extra_args
3503 = is_scalar_v<_Pattern> || (view<_Pattern>
3504 && copy_constructible<_Pattern>);
3507 inline constexpr _LazySplit lazy_split;
3508 } // namespace views
3510 template<forward_range _Vp, forward_range _Pattern>
3511 requires view<_Vp> && view<_Pattern>
3512 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3514 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3517 _Vp _M_base = _Vp();
3518 _Pattern _M_pattern = _Pattern();
3519 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3525 split_view() requires (default_initializable<_Vp>
3526 && default_initializable<_Pattern>)
3530 split_view(_Vp __base, _Pattern __pattern)
3531 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3534 template<forward_range _Range>
3535 requires constructible_from<_Vp, views::all_t<_Range>>
3536 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3538 split_view(_Range&& __r, range_value_t<_Range> __e)
3539 : _M_base(views::all(std::forward<_Range>(__r))),
3540 _M_pattern(views::single(std::move(__e)))
3544 base() const& requires copy_constructible<_Vp>
3549 { return std::move(_M_base); }
3554 if (!_M_cached_begin)
3555 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3556 return {this, ranges::begin(_M_base), *_M_cached_begin};
3562 if constexpr (common_range<_Vp>)
3563 return _Iterator{this, ranges::end(_M_base), {}};
3565 return _Sentinel{this};
3568 constexpr subrange<iterator_t<_Vp>>
3569 _M_find_next(iterator_t<_Vp> __it)
3571 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3572 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3584 split_view* _M_parent = nullptr;
3585 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3586 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3587 bool _M_trailing_empty = false;
3589 friend struct _Sentinel;
3592 using iterator_concept = forward_iterator_tag;
3593 using iterator_category = input_iterator_tag;
3594 using value_type = subrange<iterator_t<_Vp>>;
3595 using difference_type = range_difference_t<_Vp>;
3597 _Iterator() = default;
3600 _Iterator(split_view* __parent,
3601 iterator_t<_Vp> __current,
3602 subrange<iterator_t<_Vp>> __next)
3603 : _M_parent(__parent),
3604 _M_cur(std::move(__current)),
3605 _M_next(std::move(__next))
3608 constexpr iterator_t<_Vp>
3612 constexpr value_type
3614 { return {_M_cur, _M_next.begin()}; }
3616 constexpr _Iterator&
3619 _M_cur = _M_next.begin();
3620 if (_M_cur != ranges::end(_M_parent->_M_base))
3622 _M_cur = _M_next.end();
3623 if (_M_cur == ranges::end(_M_parent->_M_base))
3625 _M_trailing_empty = true;
3626 _M_next = {_M_cur, _M_cur};
3629 _M_next = _M_parent->_M_find_next(_M_cur);
3632 _M_trailing_empty = false;
3644 friend constexpr bool
3645 operator==(const _Iterator& __x, const _Iterator& __y)
3647 return __x._M_cur == __y._M_cur
3648 && __x._M_trailing_empty == __y._M_trailing_empty;
3655 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3658 _M_equal(const _Iterator& __x) const
3659 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3662 _Sentinel() = default;
3665 _Sentinel(split_view* __parent)
3666 : _M_end(ranges::end(__parent->_M_base))
3669 friend constexpr bool
3670 operator==(const _Iterator& __x, const _Sentinel& __y)
3671 { return __y._M_equal(__x); }
3675 template<typename _Range, typename _Pattern>
3676 split_view(_Range&&, _Pattern&&)
3677 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3679 template<forward_range _Range>
3680 split_view(_Range&&, range_value_t<_Range>)
3681 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3687 template<typename _Range, typename _Pattern>
3688 concept __can_split_view
3689 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3690 } // namespace __detail
3692 struct _Split : __adaptor::_RangeAdaptor<_Split>
3694 template<viewable_range _Range, typename _Pattern>
3695 requires __detail::__can_split_view<_Range, _Pattern>
3697 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3699 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3702 using _RangeAdaptor<_Split>::operator();
3703 static constexpr int _S_arity = 2;
3704 template<typename _Pattern>
3705 static constexpr bool _S_has_simple_extra_args
3706 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3709 inline constexpr _Split split;
3710 } // namespace views
3716 template<input_or_output_iterator _Iter>
3718 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3720 if constexpr (contiguous_iterator<_Iter>)
3721 return span(std::__to_address(__i), __n);
3722 else if constexpr (random_access_iterator<_Iter>)
3723 return subrange(__i, __i + __n);
3725 return subrange(counted_iterator(std::move(__i), __n),
3730 inline constexpr _Counted counted{};
3731 } // namespace views
3734 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3735 class common_view : public view_interface<common_view<_Vp>>
3738 _Vp _M_base = _Vp();
3741 common_view() requires default_initializable<_Vp> = default;
3744 common_view(_Vp __r)
3745 : _M_base(std::move(__r))
3749 base() const& requires copy_constructible<_Vp>
3754 { return std::move(_M_base); }
3759 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3760 return ranges::begin(_M_base);
3762 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3763 (ranges::begin(_M_base));
3767 begin() const requires range<const _Vp>
3769 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3770 return ranges::begin(_M_base);
3772 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3773 (ranges::begin(_M_base));
3779 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3780 return ranges::begin(_M_base) + ranges::size(_M_base);
3782 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3783 (ranges::end(_M_base));
3787 end() const requires range<const _Vp>
3789 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3790 return ranges::begin(_M_base) + ranges::size(_M_base);
3792 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3793 (ranges::end(_M_base));
3797 size() requires sized_range<_Vp>
3798 { return ranges::size(_M_base); }
3801 size() const requires sized_range<const _Vp>
3802 { return ranges::size(_M_base); }
3805 template<typename _Range>
3806 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3808 template<typename _Tp>
3809 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3810 = enable_borrowed_range<_Tp>;
3816 template<typename _Range>
3817 concept __already_common = common_range<_Range>
3818 && requires { views::all(std::declval<_Range>()); };
3820 template<typename _Range>
3821 concept __can_common_view
3822 = requires { common_view{std::declval<_Range>()}; };
3823 } // namespace __detail
3825 struct _Common : __adaptor::_RangeAdaptorClosure
3827 template<viewable_range _Range>
3828 requires __detail::__already_common<_Range>
3829 || __detail::__can_common_view<_Range>
3831 operator() [[nodiscard]] (_Range&& __r) const
3833 if constexpr (__detail::__already_common<_Range>)
3834 return views::all(std::forward<_Range>(__r));
3836 return common_view{std::forward<_Range>(__r)};
3839 static constexpr bool _S_has_simple_call_op = true;
3842 inline constexpr _Common common;
3843 } // namespace views
3846 requires bidirectional_range<_Vp>
3847 class reverse_view : public view_interface<reverse_view<_Vp>>
3850 static constexpr bool _S_needs_cached_begin
3851 = !common_range<_Vp> && !(random_access_range<_Vp>
3852 && sized_sentinel_for<sentinel_t<_Vp>,
3855 _Vp _M_base = _Vp();
3856 [[no_unique_address]]
3857 __detail::__maybe_present_t<_S_needs_cached_begin,
3858 __detail::_CachedPosition<_Vp>>
3862 reverse_view() requires default_initializable<_Vp> = default;
3865 reverse_view(_Vp __r)
3866 : _M_base(std::move(__r))
3870 base() const& requires copy_constructible<_Vp>
3875 { return std::move(_M_base); }
3877 constexpr reverse_iterator<iterator_t<_Vp>>
3880 if constexpr (_S_needs_cached_begin)
3881 if (_M_cached_begin._M_has_value())
3882 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3884 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3885 if constexpr (_S_needs_cached_begin)
3886 _M_cached_begin._M_set(_M_base, __it);
3887 return std::make_reverse_iterator(std::move(__it));
3891 begin() requires common_range<_Vp>
3892 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3895 begin() const requires common_range<const _Vp>
3896 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3898 constexpr reverse_iterator<iterator_t<_Vp>>
3900 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3903 end() const requires common_range<const _Vp>
3904 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3907 size() requires sized_range<_Vp>
3908 { return ranges::size(_M_base); }
3911 size() const requires sized_range<const _Vp>
3912 { return ranges::size(_M_base); }
3915 template<typename _Range>
3916 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3918 template<typename _Tp>
3919 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3920 = enable_borrowed_range<_Tp>;
3927 inline constexpr bool __is_reversible_subrange = false;
3929 template<typename _Iter, subrange_kind _Kind>
3930 inline constexpr bool
3931 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3932 reverse_iterator<_Iter>,
3936 inline constexpr bool __is_reverse_view = false;
3938 template<typename _Vp>
3939 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3941 template<typename _Range>
3942 concept __can_reverse_view
3943 = requires { reverse_view{std::declval<_Range>()}; };
3944 } // namespace __detail
3946 struct _Reverse : __adaptor::_RangeAdaptorClosure
3948 template<viewable_range _Range>
3949 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3950 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3951 || __detail::__can_reverse_view<_Range>
3953 operator() [[nodiscard]] (_Range&& __r) const
3955 using _Tp = remove_cvref_t<_Range>;
3956 if constexpr (__detail::__is_reverse_view<_Tp>)
3957 return std::forward<_Range>(__r).base();
3958 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3960 using _Iter = decltype(ranges::begin(__r).base());
3961 if constexpr (sized_range<_Tp>)
3962 return subrange<_Iter, _Iter, subrange_kind::sized>
3963 {__r.end().base(), __r.begin().base(), __r.size()};
3965 return subrange<_Iter, _Iter, subrange_kind::unsized>
3966 {__r.end().base(), __r.begin().base()};
3969 return reverse_view{std::forward<_Range>(__r)};
3972 static constexpr bool _S_has_simple_call_op = true;
3975 inline constexpr _Reverse reverse;
3976 } // namespace views
3980 template<typename _Tp, size_t _Nm>
3981 concept __has_tuple_element = requires(_Tp __t)
3983 typename tuple_size<_Tp>::type;
3984 requires _Nm < tuple_size_v<_Tp>;
3985 typename tuple_element_t<_Nm, _Tp>;
3986 { std::get<_Nm>(__t) }
3987 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
3990 template<typename _Tp, size_t _Nm>
3991 concept __returnable_element
3992 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
3995 template<input_range _Vp, size_t _Nm>
3997 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
3998 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4000 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4001 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4004 elements_view() requires default_initializable<_Vp> = default;
4007 elements_view(_Vp __base)
4008 : _M_base(std::move(__base))
4012 base() const& requires copy_constructible<_Vp>
4017 { return std::move(_M_base); }
4020 begin() requires (!__detail::__simple_view<_Vp>)
4021 { return _Iterator<false>(ranges::begin(_M_base)); }
4024 begin() const requires range<const _Vp>
4025 { return _Iterator<true>(ranges::begin(_M_base)); }
4028 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4029 { return _Sentinel<false>{ranges::end(_M_base)}; }
4032 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4033 { return _Iterator<false>{ranges::end(_M_base)}; }
4036 end() const requires range<const _Vp>
4037 { return _Sentinel<true>{ranges::end(_M_base)}; }
4040 end() const requires common_range<const _Vp>
4041 { return _Iterator<true>{ranges::end(_M_base)}; }
4044 size() requires sized_range<_Vp>
4045 { return ranges::size(_M_base); }
4048 size() const requires sized_range<const _Vp>
4049 { return ranges::size(_M_base); }
4052 template<bool _Const>
4053 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4055 template<bool _Const>
4059 template<bool _Const>
4060 requires forward_range<_Base<_Const>>
4061 struct __iter_cat<_Const>
4064 static auto _S_iter_cat()
4066 using _Base = elements_view::_Base<_Const>;
4067 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4068 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4069 if constexpr (!is_lvalue_reference_v<_Res>)
4070 return input_iterator_tag{};
4071 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4072 return random_access_iterator_tag{};
4077 using iterator_category = decltype(_S_iter_cat());
4080 template<bool _Const>
4083 template<bool _Const>
4084 struct _Iterator : __iter_cat<_Const>
4087 using _Base = elements_view::_Base<_Const>;
4089 iterator_t<_Base> _M_current = iterator_t<_Base>();
4091 static constexpr decltype(auto)
4092 _S_get_element(const iterator_t<_Base>& __i)
4094 if constexpr (is_reference_v<range_reference_t<_Base>>)
4095 return std::get<_Nm>(*__i);
4098 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4099 return static_cast<_Et>(std::get<_Nm>(*__i));
4106 if constexpr (random_access_range<_Base>)
4107 return random_access_iterator_tag{};
4108 else if constexpr (bidirectional_range<_Base>)
4109 return bidirectional_iterator_tag{};
4110 else if constexpr (forward_range<_Base>)
4111 return forward_iterator_tag{};
4113 return input_iterator_tag{};
4116 friend _Iterator<!_Const>;
4119 using iterator_concept = decltype(_S_iter_concept());
4120 // iterator_category defined in elements_view::__iter_cat
4122 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4123 using difference_type = range_difference_t<_Base>;
4125 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4128 _Iterator(iterator_t<_Base> __current)
4129 : _M_current(std::move(__current))
4133 _Iterator(_Iterator<!_Const> __i)
4134 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4135 : _M_current(std::move(__i._M_current))
4138 constexpr const iterator_t<_Base>&
4139 base() const& noexcept
4140 { return _M_current; }
4142 constexpr iterator_t<_Base>
4144 { return std::move(_M_current); }
4146 constexpr decltype(auto)
4148 { return _S_get_element(_M_current); }
4150 constexpr _Iterator&
4162 operator++(int) requires forward_range<_Base>
4169 constexpr _Iterator&
4170 operator--() requires bidirectional_range<_Base>
4177 operator--(int) requires bidirectional_range<_Base>
4184 constexpr _Iterator&
4185 operator+=(difference_type __n)
4186 requires random_access_range<_Base>
4192 constexpr _Iterator&
4193 operator-=(difference_type __n)
4194 requires random_access_range<_Base>
4200 constexpr decltype(auto)
4201 operator[](difference_type __n) const
4202 requires random_access_range<_Base>
4203 { return _S_get_element(_M_current + __n); }
4205 friend constexpr bool
4206 operator==(const _Iterator& __x, const _Iterator& __y)
4207 requires equality_comparable<iterator_t<_Base>>
4208 { return __x._M_current == __y._M_current; }
4210 friend constexpr bool
4211 operator<(const _Iterator& __x, const _Iterator& __y)
4212 requires random_access_range<_Base>
4213 { return __x._M_current < __y._M_current; }
4215 friend constexpr bool
4216 operator>(const _Iterator& __x, const _Iterator& __y)
4217 requires random_access_range<_Base>
4218 { return __y._M_current < __x._M_current; }
4220 friend constexpr bool
4221 operator<=(const _Iterator& __x, const _Iterator& __y)
4222 requires random_access_range<_Base>
4223 { return !(__y._M_current > __x._M_current); }
4225 friend constexpr bool
4226 operator>=(const _Iterator& __x, const _Iterator& __y)
4227 requires random_access_range<_Base>
4228 { return !(__x._M_current > __y._M_current); }
4230 #ifdef __cpp_lib_three_way_comparison
4231 friend constexpr auto
4232 operator<=>(const _Iterator& __x, const _Iterator& __y)
4233 requires random_access_range<_Base>
4234 && three_way_comparable<iterator_t<_Base>>
4235 { return __x._M_current <=> __y._M_current; }
4238 friend constexpr _Iterator
4239 operator+(const _Iterator& __x, difference_type __y)
4240 requires random_access_range<_Base>
4241 { return _Iterator{__x} += __y; }
4243 friend constexpr _Iterator
4244 operator+(difference_type __x, const _Iterator& __y)
4245 requires random_access_range<_Base>
4246 { return __y + __x; }
4248 friend constexpr _Iterator
4249 operator-(const _Iterator& __x, difference_type __y)
4250 requires random_access_range<_Base>
4251 { return _Iterator{__x} -= __y; }
4253 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4254 // 3483. transform_view::iterator's difference is overconstrained
4255 friend constexpr difference_type
4256 operator-(const _Iterator& __x, const _Iterator& __y)
4257 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4258 { return __x._M_current - __y._M_current; }
4260 template <bool> friend struct _Sentinel;
4263 template<bool _Const>
4267 template<bool _Const2>
4269 _M_equal(const _Iterator<_Const2>& __x) const
4270 { return __x._M_current == _M_end; }
4272 template<bool _Const2>
4274 _M_distance_from(const _Iterator<_Const2>& __i) const
4275 { return _M_end - __i._M_current; }
4277 using _Base = elements_view::_Base<_Const>;
4278 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4281 _Sentinel() = default;
4284 _Sentinel(sentinel_t<_Base> __end)
4285 : _M_end(std::move(__end))
4289 _Sentinel(_Sentinel<!_Const> __other)
4291 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4292 : _M_end(std::move(__other._M_end))
4295 constexpr sentinel_t<_Base>
4299 template<bool _Const2>
4300 requires sentinel_for<sentinel_t<_Base>,
4301 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4302 friend constexpr bool
4303 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4304 { return __y._M_equal(__x); }
4306 template<bool _Const2,
4307 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4308 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4309 friend constexpr range_difference_t<_Base2>
4310 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4311 { return -__y._M_distance_from(__x); }
4313 template<bool _Const2,
4314 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4315 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4316 friend constexpr range_difference_t<_Base2>
4317 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4318 { return __x._M_distance_from(__y); }
4320 friend _Sentinel<!_Const>;
4323 _Vp _M_base = _Vp();
4326 template<typename _Tp, size_t _Nm>
4327 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4328 = enable_borrowed_range<_Tp>;
4330 template<typename _Range>
4331 using keys_view = elements_view<views::all_t<_Range>, 0>;
4333 template<typename _Range>
4334 using values_view = elements_view<views::all_t<_Range>, 1>;
4340 template<size_t _Nm, typename _Range>
4341 concept __can_elements_view
4342 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4343 } // namespace __detail
4345 template<size_t _Nm>
4346 struct _Elements : __adaptor::_RangeAdaptorClosure
4348 template<viewable_range _Range>
4349 requires __detail::__can_elements_view<_Nm, _Range>
4351 operator() [[nodiscard]] (_Range&& __r) const
4353 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4356 static constexpr bool _S_has_simple_call_op = true;
4359 template<size_t _Nm>
4360 inline constexpr _Elements<_Nm> elements;
4361 inline constexpr auto keys = elements<0>;
4362 inline constexpr auto values = elements<1>;
4363 } // namespace views
4365 #if __cplusplus > 202002L
4367 #define __cpp_lib_ranges_zip 202110L
4371 template<typename... _Rs>
4372 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4373 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4374 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4376 template<typename... _Ts>
4377 struct __tuple_or_pair
4378 { using type = std::tuple<_Ts...>; };
4380 template<typename _Tp, typename _Up>
4381 struct __tuple_or_pair<_Tp, _Up>
4382 { using type = pair<_Tp, _Up>; };
4384 template<typename... _Ts>
4385 using __tuple_or_pair_t = typename __tuple_or_pair<_Ts...>::type;
4387 template<typename _Fp, typename _Tuple>
4389 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4391 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4392 return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
4393 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4394 }, std::forward<_Tuple>(__tuple));
4397 template<typename _Fp, typename _Tuple>
4399 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4401 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4402 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4403 }, std::forward<_Tuple>(__tuple));
4405 } // namespace __detail
4407 template<input_range... _Vs>
4408 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4409 class zip_view : public view_interface<zip_view<_Vs...>>
4411 tuple<_Vs...> _M_views;
4413 template<bool> class _Iterator;
4414 template<bool> class _Sentinel;
4417 zip_view() = default;
4420 zip_view(_Vs... __views)
4421 : _M_views(std::move(__views)...)
4425 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4426 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4429 begin() const requires (range<const _Vs> && ...)
4430 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4433 end() requires (!(__detail::__simple_view<_Vs> && ...))
4435 if constexpr (!__detail::__zip_is_common<_Vs...>)
4436 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4437 else if constexpr ((random_access_range<_Vs> && ...))
4438 return begin() + iter_difference_t<_Iterator<false>>(size());
4440 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4444 end() const requires (range<const _Vs> && ...)
4446 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4447 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4448 else if constexpr ((random_access_range<const _Vs> && ...))
4449 return begin() + iter_difference_t<_Iterator<true>>(size());
4451 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4455 size() requires (sized_range<_Vs> && ...)
4457 return std::apply([](auto... sizes) {
4458 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4459 return ranges::min({_CT(sizes)...});
4460 }, __detail::__tuple_transform(ranges::size, _M_views));
4464 size() const requires (sized_range<const _Vs> && ...)
4466 return std::apply([](auto... sizes) {
4467 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4468 return ranges::min({_CT(sizes)...});
4469 }, __detail::__tuple_transform(ranges::size, _M_views));
4473 template<typename... _Rs>
4474 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4476 template<typename... _Views>
4477 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4478 = (enable_borrowed_range<_Views> && ...);
4482 template<bool _Const, typename... _Vs>
4483 concept __all_random_access
4484 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4486 template<bool _Const, typename... _Vs>
4487 concept __all_bidirectional
4488 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4490 template<bool _Const, typename... _Vs>
4491 concept __all_forward
4492 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4494 template<bool _Const, typename... _Views>
4495 struct __zip_view_iter_cat
4498 template<bool _Const, typename... _Views>
4499 requires __all_forward<_Const, _Views...>
4500 struct __zip_view_iter_cat<_Const, _Views...>
4501 { using iterator_category = input_iterator_tag; };
4502 } // namespace __detail
4504 template<input_range... _Vs>
4505 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4506 template<bool _Const>
4507 class zip_view<_Vs...>::_Iterator
4508 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4510 __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4513 _Iterator(decltype(_M_current) __current)
4514 : _M_current(std::move(__current))
4520 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4521 return random_access_iterator_tag{};
4522 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4523 return bidirectional_iterator_tag{};
4524 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4525 return forward_iterator_tag{};
4527 return input_iterator_tag{};
4530 template<copy_constructible _Fp, input_range... _Ws>
4531 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4532 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4533 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4534 friend class zip_transform_view;
4537 // iterator_category defined in __zip_view_iter_cat
4538 using iterator_concept = decltype(_S_iter_concept());
4540 = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4541 using difference_type
4542 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4544 _Iterator() = default;
4547 _Iterator(_Iterator<!_Const> __i)
4549 && (convertible_to<iterator_t<_Vs>,
4550 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4551 : _M_current(std::move(__i._M_current))
4557 auto __f = [](auto& __i) -> decltype(auto) {
4560 return __detail::__tuple_transform(__f, _M_current);
4563 constexpr _Iterator&
4566 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4576 requires __detail::__all_forward<_Const, _Vs...>
4583 constexpr _Iterator&
4585 requires __detail::__all_bidirectional<_Const, _Vs...>
4587 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4593 requires __detail::__all_bidirectional<_Const, _Vs...>
4600 constexpr _Iterator&
4601 operator+=(difference_type __x)
4602 requires __detail::__all_random_access<_Const, _Vs...>
4604 auto __f = [&]<typename _It>(_It& __i) {
4605 __i += iter_difference_t<_It>(__x);
4607 __detail::__tuple_for_each(__f, _M_current);
4611 constexpr _Iterator&
4612 operator-=(difference_type __x)
4613 requires __detail::__all_random_access<_Const, _Vs...>
4615 auto __f = [&]<typename _It>(_It& __i) {
4616 __i -= iter_difference_t<_It>(__x);
4618 __detail::__tuple_for_each(__f, _M_current);
4623 operator[](difference_type __n) const
4624 requires __detail::__all_random_access<_Const, _Vs...>
4626 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4627 return __i[iter_difference_t<_It>(__n)];
4629 return __detail::__tuple_transform(__f, _M_current);
4632 friend constexpr bool
4633 operator==(const _Iterator& __x, const _Iterator& __y)
4634 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4636 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4637 return __x._M_current == __y._M_current;
4639 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4640 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4641 }(make_index_sequence<sizeof...(_Vs)>{});
4644 friend constexpr auto
4645 operator<=>(const _Iterator& __x, const _Iterator& __y)
4646 requires __detail::__all_random_access<_Const, _Vs...>
4647 { return __x._M_current <=> __y._M_current; }
4649 friend constexpr _Iterator
4650 operator+(const _Iterator& __i, difference_type __n)
4651 requires __detail::__all_random_access<_Const, _Vs...>
4658 friend constexpr _Iterator
4659 operator+(difference_type __n, const _Iterator& __i)
4660 requires __detail::__all_random_access<_Const, _Vs...>
4667 friend constexpr _Iterator
4668 operator-(const _Iterator& __i, difference_type __n)
4669 requires __detail::__all_random_access<_Const, _Vs...>
4676 friend constexpr difference_type
4677 operator-(const _Iterator& __x, const _Iterator& __y)
4678 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4679 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4681 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4682 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4683 - std::get<_Is>(__y._M_current))...},
4685 [](difference_type __i) {
4686 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4688 }(make_index_sequence<sizeof...(_Vs)>{});
4691 friend constexpr auto
4692 iter_move(const _Iterator& __i)
4693 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4695 friend constexpr void
4696 iter_swap(const _Iterator& __l, const _Iterator& __r)
4697 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4699 [&]<size_t... _Is>(index_sequence<_Is...>) {
4700 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4701 }(make_index_sequence<sizeof...(_Vs)>{});
4704 friend class zip_view;
4707 template<input_range... _Vs>
4708 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4709 template<bool _Const>
4710 class zip_view<_Vs...>::_Sentinel
4712 __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4715 _Sentinel(decltype(_M_end) __end)
4719 friend class zip_view;
4722 _Sentinel() = default;
4725 _Sentinel(_Sentinel<!_Const> __i)
4727 && (convertible_to<sentinel_t<_Vs>,
4728 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4729 : _M_end(std::move(__i._M_end))
4732 template<bool _OtherConst>
4733 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4734 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4735 friend constexpr bool
4736 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4738 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4739 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4740 }(make_index_sequence<sizeof...(_Vs)>{});
4743 template<bool _OtherConst>
4744 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4745 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4746 friend constexpr auto
4747 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4750 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4751 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4752 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4755 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4757 }(make_index_sequence<sizeof...(_Vs)>{});
4760 template<bool _OtherConst>
4761 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4762 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4763 friend constexpr auto
4764 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4765 { return -(__x - __y); }
4772 template<typename... _Ts>
4773 concept __can_zip_view
4774 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4779 template<typename... _Ts>
4780 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4782 operator() [[nodiscard]] (_Ts&&... __ts) const
4784 if constexpr (sizeof...(_Ts) == 0)
4785 return views::empty<tuple<>>;
4787 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4791 inline constexpr _Zip zip;
4796 template<typename _Range, bool _Const>
4797 using __range_iter_cat
4798 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4801 template<copy_constructible _Fp, input_range... _Vs>
4802 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4803 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4804 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4805 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
4807 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4808 zip_view<_Vs...> _M_zip;
4810 using _InnerView = zip_view<_Vs...>;
4812 template<bool _Const>
4813 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4815 template<bool _Const>
4816 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4818 template<bool _Const>
4819 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
4821 template<bool _Const>
4825 template<bool _Const>
4826 requires forward_range<_Base<_Const>>
4827 struct __iter_cat<_Const>
4833 using __detail::__maybe_const_t;
4834 using __detail::__range_iter_cat;
4835 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
4836 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
4837 if constexpr (!is_lvalue_reference_v<_Res>)
4838 return input_iterator_tag{};
4839 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4840 random_access_iterator_tag> && ...))
4841 return random_access_iterator_tag{};
4842 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4843 bidirectional_iterator_tag> && ...))
4844 return bidirectional_iterator_tag{};
4845 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4846 forward_iterator_tag> && ...))
4847 return forward_iterator_tag{};
4849 return input_iterator_tag{};
4852 using iterator_category = decltype(_S_iter_cat());
4855 template<bool> class _Iterator;
4856 template<bool> class _Sentinel;
4859 zip_transform_view() = default;
4862 zip_transform_view(_Fp __fun, _Vs... __views)
4863 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
4868 { return _Iterator<false>(*this, _M_zip.begin()); }
4872 requires range<const _InnerView>
4873 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4874 { return _Iterator<true>(*this, _M_zip.begin()); }
4879 if constexpr (common_range<_InnerView>)
4880 return _Iterator<false>(*this, _M_zip.end());
4882 return _Sentinel<false>(_M_zip.end());
4887 requires range<const _InnerView>
4888 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4890 if constexpr (common_range<const _InnerView>)
4891 return _Iterator<true>(*this, _M_zip.end());
4893 return _Sentinel<true>(_M_zip.end());
4897 size() requires sized_range<_InnerView>
4898 { return _M_zip.size(); }
4901 size() const requires sized_range<const _InnerView>
4902 { return _M_zip.size(); }
4905 template<class _Fp, class... Rs>
4906 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
4908 template<copy_constructible _Fp, input_range... _Vs>
4909 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4910 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4911 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4912 template<bool _Const>
4913 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
4915 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
4917 _Parent* _M_parent = nullptr;
4918 __ziperator<_Const> _M_inner;
4921 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
4922 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
4925 friend class zip_transform_view;
4928 // iterator_category defined in zip_transform_view::__iter_cat
4929 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
4931 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
4932 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
4933 using difference_type = range_difference_t<_Base<_Const>>;
4935 _Iterator() = default;
4938 _Iterator(_Iterator<!_Const> __i)
4939 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
4940 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
4943 constexpr decltype(auto)
4946 return std::apply([&](const auto&... __iters) -> decltype(auto) {
4947 return std::__invoke(*_M_parent->_M_fun, *__iters...);
4948 }, _M_inner._M_current);
4951 constexpr _Iterator&
4963 operator++(int) requires forward_range<_Base<_Const>>
4970 constexpr _Iterator&
4971 operator--() requires bidirectional_range<_Base<_Const>>
4978 operator--(int) requires bidirectional_range<_Base<_Const>>
4985 constexpr _Iterator&
4986 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
4992 constexpr _Iterator&
4993 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
4999 constexpr decltype(auto)
5000 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5002 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5003 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5004 }, _M_inner._M_current);
5007 friend constexpr bool
5008 operator==(const _Iterator& __x, const _Iterator& __y)
5009 requires equality_comparable<__ziperator<_Const>>
5010 { return __x._M_inner == __y._M_inner; }
5012 friend constexpr auto
5013 operator<=>(const _Iterator& __x, const _Iterator& __y)
5014 requires random_access_range<_Base<_Const>>
5015 { return __x._M_inner <=> __y._M_inner; }
5017 friend constexpr _Iterator
5018 operator+(const _Iterator& __i, difference_type __n)
5019 requires random_access_range<_Base<_Const>>
5020 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5022 friend constexpr _Iterator
5023 operator+(difference_type __n, const _Iterator& __i)
5024 requires random_access_range<_Base<_Const>>
5025 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5027 friend constexpr _Iterator
5028 operator-(const _Iterator& __i, difference_type __n)
5029 requires random_access_range<_Base<_Const>>
5030 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5032 friend constexpr difference_type
5033 operator-(const _Iterator& __x, const _Iterator& __y)
5034 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5035 { return __x._M_inner - __y._M_inner; }
5038 template<copy_constructible _Fp, input_range... _Vs>
5039 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5040 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5041 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5042 template<bool _Const>
5043 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5045 __zentinel<_Const> _M_inner;
5048 _Sentinel(__zentinel<_Const> __inner)
5052 friend class zip_transform_view;
5055 _Sentinel() = default;
5058 _Sentinel(_Sentinel<!_Const> __i)
5059 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5060 : _M_inner(std::move(__i._M_inner))
5063 template<bool _OtherConst>
5064 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5065 friend constexpr bool
5066 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5067 { return __x._M_inner == __y._M_inner; }
5069 template<bool _OtherConst>
5070 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5071 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5072 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5073 { return __x._M_inner - __y._M_inner; }
5075 template<bool _OtherConst>
5076 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5077 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5078 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5079 { return __x._M_inner - __y._M_inner; }
5086 template<typename _Fp, typename... _Ts>
5087 concept __can_zip_transform_view
5088 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5091 struct _ZipTransform
5093 template<typename _Fp, typename... _Ts>
5094 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5096 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5098 if constexpr (sizeof...(_Ts) == 0)
5099 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5101 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5105 inline constexpr _ZipTransform zip_transform;
5108 template<forward_range _Vp, size_t _Nm>
5109 requires view<_Vp> && (_Nm > 0)
5110 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5112 _Vp _M_base = _Vp();
5114 template<bool> class _Iterator;
5115 template<bool> class _Sentinel;
5117 struct __as_sentinel
5121 adjacent_view() requires default_initializable<_Vp> = default;
5124 adjacent_view(_Vp __base)
5125 : _M_base(std::move(__base))
5129 begin() requires (!__detail::__simple_view<_Vp>)
5130 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5133 begin() const requires range<const _Vp>
5134 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5137 end() requires (!__detail::__simple_view<_Vp>)
5139 if constexpr (common_range<_Vp>)
5140 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5142 return _Sentinel<false>(ranges::end(_M_base));
5146 end() const requires range<const _Vp>
5148 if constexpr (common_range<const _Vp>)
5149 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5151 return _Sentinel<true>(ranges::end(_M_base));
5155 size() requires sized_range<_Vp>
5157 using _ST = decltype(ranges::size(_M_base));
5158 using _CT = common_type_t<_ST, size_t>;
5159 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5160 __sz -= std::min<_CT>(__sz, _Nm - 1);
5161 return static_cast<_ST>(__sz);
5165 size() const requires sized_range<const _Vp>
5167 using _ST = decltype(ranges::size(_M_base));
5168 using _CT = common_type_t<_ST, size_t>;
5169 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5170 __sz -= std::min<_CT>(__sz, _Nm - 1);
5171 return static_cast<_ST>(__sz);
5175 template<typename _Vp, size_t _Nm>
5176 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5177 = enable_borrowed_range<_Vp>;
5181 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5182 template<typename _Tp, size_t _Nm>
5183 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5185 // For a functor F that is callable with N arguments, the expression
5186 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5187 template<typename _Fp, size_t _Nm>
5190 template<typename... _Ts>
5191 static invoke_result_t<_Fp, _Ts...>
5192 __tuple_apply(const tuple<_Ts...>&); // not defined
5194 template<typename _Tp>
5195 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5196 operator()(_Tp&&); // not defined
5200 template<forward_range _Vp, size_t _Nm>
5201 requires view<_Vp> && (_Nm > 0)
5202 template<bool _Const>
5203 class adjacent_view<_Vp, _Nm>::_Iterator
5205 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5206 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5209 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5211 for (auto& __i : _M_current)
5214 ranges::advance(__first, 1, __last);
5219 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5221 if constexpr (!bidirectional_range<_Base>)
5222 for (auto& __it : _M_current)
5225 for (size_t __i = 0; __i < _Nm; ++__i)
5227 _M_current[_Nm - 1 - __i] = __last;
5228 ranges::advance(__last, -1, __first);
5235 if constexpr (random_access_range<_Base>)
5236 return random_access_iterator_tag{};
5237 else if constexpr (bidirectional_range<_Base>)
5238 return bidirectional_iterator_tag{};
5240 return forward_iterator_tag{};
5243 friend class adjacent_view;
5245 template<forward_range _Wp, copy_constructible _Fp, size_t _Mm>
5246 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5247 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5248 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5249 range_reference_t<_Wp>>>
5250 friend class adjacent_transform_view;
5253 using iterator_category = input_iterator_tag;
5254 using iterator_concept = decltype(_S_iter_concept());
5255 using value_type = conditional_t<_Nm == 2,
5256 pair<range_value_t<_Base>, range_value_t<_Base>>,
5257 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5258 using difference_type = range_difference_t<_Base>;
5260 _Iterator() = default;
5263 _Iterator(_Iterator<!_Const> __i)
5264 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5266 for (size_t __j = 0; __j < _Nm; ++__j)
5267 _M_current[__j] = std::move(__i._M_current[__j]);
5273 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5274 return __detail::__tuple_transform(__f, _M_current);
5277 constexpr _Iterator&
5280 for (auto& __i : _M_current)
5293 constexpr _Iterator&
5294 operator--() requires bidirectional_range<_Base>
5296 for (auto& __i : _M_current)
5302 operator--(int) requires bidirectional_range<_Base>
5309 constexpr _Iterator&
5310 operator+=(difference_type __x)
5311 requires random_access_range<_Base>
5313 for (auto& __i : _M_current)
5318 constexpr _Iterator&
5319 operator-=(difference_type __x)
5320 requires random_access_range<_Base>
5322 for (auto& __i : _M_current)
5328 operator[](difference_type __n) const
5329 requires random_access_range<_Base>
5331 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5332 return __detail::__tuple_transform(__f, _M_current);
5335 friend constexpr bool
5336 operator==(const _Iterator& __x, const _Iterator& __y)
5337 { return __x._M_current.back() == __y._M_current.back(); }
5339 friend constexpr bool
5340 operator<(const _Iterator& __x, const _Iterator& __y)
5341 requires random_access_range<_Base>
5342 { return __x._M_current.back() < __y._M_current.back(); }
5344 friend constexpr bool
5345 operator>(const _Iterator& __x, const _Iterator& __y)
5346 requires random_access_range<_Base>
5347 { return __y < __x; }
5349 friend constexpr bool
5350 operator<=(const _Iterator& __x, const _Iterator& __y)
5351 requires random_access_range<_Base>
5352 { return !(__y < __x); }
5354 friend constexpr bool
5355 operator>=(const _Iterator& __x, const _Iterator& __y)
5356 requires random_access_range<_Base>
5357 { return !(__x < __y); }
5359 friend constexpr auto
5360 operator<=>(const _Iterator& __x, const _Iterator& __y)
5361 requires random_access_range<_Base>
5362 && three_way_comparable<iterator_t<_Base>>
5363 { return __x._M_current.back() <=> __y._M_current.back(); }
5365 friend constexpr _Iterator
5366 operator+(const _Iterator& __i, difference_type __n)
5367 requires random_access_range<_Base>
5374 friend constexpr _Iterator
5375 operator+(difference_type __n, const _Iterator& __i)
5376 requires random_access_range<_Base>
5383 friend constexpr _Iterator
5384 operator-(const _Iterator& __i, difference_type __n)
5385 requires random_access_range<_Base>
5392 friend constexpr difference_type
5393 operator-(const _Iterator& __x, const _Iterator& __y)
5394 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5395 { return __x._M_current.back() - __y._M_current.back(); }
5397 friend constexpr auto
5398 iter_move(const _Iterator& __i)
5399 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5401 friend constexpr void
5402 iter_swap(const _Iterator& __l, const _Iterator& __r)
5403 requires indirectly_swappable<iterator_t<_Base>>
5405 for (size_t __i = 0; __i < _Nm; __i++)
5406 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5410 template<forward_range _Vp, size_t _Nm>
5411 requires view<_Vp> && (_Nm > 0)
5412 template<bool _Const>
5413 class adjacent_view<_Vp, _Nm>::_Sentinel
5415 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5417 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5420 _Sentinel(sentinel_t<_Base> __end)
5424 friend class adjacent_view;
5427 _Sentinel() = default;
5430 _Sentinel(_Sentinel<!_Const> __i)
5431 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5432 : _M_end(std::move(__i._M_end))
5435 template<bool _OtherConst>
5436 requires sentinel_for<sentinel_t<_Base>,
5437 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5438 friend constexpr bool
5439 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5440 { return __x._M_current.back() == __y._M_end; }
5442 template<bool _OtherConst>
5443 requires sized_sentinel_for<sentinel_t<_Base>,
5444 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5445 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5446 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5447 { return __x._M_current.back() - __y._M_end; }
5449 template<bool _OtherConst>
5450 requires sized_sentinel_for<sentinel_t<_Base>,
5451 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5452 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5453 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5454 { return __y._M_end - __x._M_current.back(); }
5461 template<size_t _Nm, typename _Range>
5462 concept __can_adjacent_view
5463 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5466 template<size_t _Nm>
5467 struct _Adjacent : __adaptor::_RangeAdaptorClosure
5469 template<viewable_range _Range>
5470 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5472 operator() [[nodiscard]] (_Range&& __r) const
5474 if constexpr (_Nm == 0)
5475 return views::empty<tuple<>>;
5477 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5481 template<size_t _Nm>
5482 inline constexpr _Adjacent<_Nm> adjacent;
5484 inline constexpr auto pairwise = adjacent<2>;
5487 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5488 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5489 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5490 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5491 range_reference_t<_Vp>>>
5492 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5494 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5495 adjacent_view<_Vp, _Nm> _M_inner;
5497 using _InnerView = adjacent_view<_Vp, _Nm>;
5499 template<bool _Const>
5500 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5502 template<bool _Const>
5503 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5505 template<bool> class _Iterator;
5506 template<bool> class _Sentinel;
5509 adjacent_transform_view() = default;
5512 adjacent_transform_view(_Vp __base, _Fp __fun)
5513 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5518 { return _Iterator<false>(*this, _M_inner.begin()); }
5522 requires range<const _InnerView>
5523 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5524 range_reference_t<const _Vp>>
5525 { return _Iterator<true>(*this, _M_inner.begin()); }
5530 if constexpr (common_range<_InnerView>)
5531 return _Iterator<false>(*this, _M_inner.end());
5533 return _Sentinel<false>(_M_inner.end());
5538 requires range<const _InnerView>
5539 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5540 range_reference_t<const _Vp>>
5542 if constexpr (common_range<const _InnerView>)
5543 return _Iterator<true>(*this, _M_inner.end());
5545 return _Sentinel<true>(_M_inner.end());
5549 size() requires sized_range<_InnerView>
5550 { return _M_inner.size(); }
5553 size() const requires sized_range<const _InnerView>
5554 { return _M_inner.size(); }
5557 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5558 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5559 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5560 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5561 range_reference_t<_Vp>>>
5562 template<bool _Const>
5563 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5565 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5566 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5568 _Parent* _M_parent = nullptr;
5569 _InnerIter<_Const> _M_inner;
5572 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5573 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5579 using __detail::__maybe_const_t;
5580 using __detail::__unarize;
5581 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5582 range_reference_t<_Base>>;
5583 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5584 if constexpr (!is_lvalue_reference_v<_Res>)
5585 return input_iterator_tag{};
5586 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5587 return random_access_iterator_tag{};
5588 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5589 return bidirectional_iterator_tag{};
5590 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5591 return forward_iterator_tag{};
5593 return input_iterator_tag{};
5596 friend class adjacent_transform_view;
5599 using iterator_category = decltype(_S_iter_cat());
5600 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5602 = remove_cvref_t<invoke_result_t
5603 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5604 range_reference_t<_Base>>>;
5605 using difference_type = range_difference_t<_Base>;
5607 _Iterator() = default;
5610 _Iterator(_Iterator<!_Const> __i)
5611 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5612 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5615 constexpr decltype(auto)
5618 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5619 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5620 }, _M_inner._M_current);
5623 constexpr _Iterator&
5638 constexpr _Iterator&
5639 operator--() requires bidirectional_range<_Base>
5646 operator--(int) requires bidirectional_range<_Base>
5653 constexpr _Iterator&
5654 operator+=(difference_type __x) requires random_access_range<_Base>
5660 constexpr _Iterator&
5661 operator-=(difference_type __x) requires random_access_range<_Base>
5667 constexpr decltype(auto)
5668 operator[](difference_type __n) const requires random_access_range<_Base>
5670 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5671 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5672 }, _M_inner._M_current);
5675 friend constexpr bool
5676 operator==(const _Iterator& __x, const _Iterator& __y)
5677 { return __x._M_inner == __y._M_inner; }
5679 friend constexpr bool
5680 operator<(const _Iterator& __x, const _Iterator& __y)
5681 requires random_access_range<_Base>
5682 { return __x._M_inner < __y._M_inner; }
5684 friend constexpr bool
5685 operator>(const _Iterator& __x, const _Iterator& __y)
5686 requires random_access_range<_Base>
5687 { return __x._M_inner > __y._M_inner; }
5689 friend constexpr bool
5690 operator<=(const _Iterator& __x, const _Iterator& __y)
5691 requires random_access_range<_Base>
5692 { return __x._M_inner <= __y._M_inner; }
5694 friend constexpr bool
5695 operator>=(const _Iterator& __x, const _Iterator& __y)
5696 requires random_access_range<_Base>
5697 { return __x._M_inner >= __y._M_inner; }
5699 friend constexpr auto
5700 operator<=>(const _Iterator& __x, const _Iterator& __y)
5701 requires random_access_range<_Base> &&
5702 three_way_comparable<_InnerIter<_Const>>
5703 { return __x._M_inner <=> __y._M_inner; }
5705 friend constexpr _Iterator
5706 operator+(const _Iterator& __i, difference_type __n)
5707 requires random_access_range<_Base>
5708 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5710 friend constexpr _Iterator
5711 operator+(difference_type __n, const _Iterator& __i)
5712 requires random_access_range<_Base>
5713 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5715 friend constexpr _Iterator
5716 operator-(const _Iterator& __i, difference_type __n)
5717 requires random_access_range<_Base>
5718 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5720 friend constexpr difference_type
5721 operator-(const _Iterator& __x, const _Iterator& __y)
5722 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5723 { return __x._M_inner - __y._M_inner; }
5726 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5727 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5728 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5729 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5730 range_reference_t<_Vp>>>
5731 template<bool _Const>
5732 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5734 _InnerSent<_Const> _M_inner;
5737 _Sentinel(_InnerSent<_Const> __inner)
5741 friend class adjacent_transform_view;
5744 _Sentinel() = default;
5747 _Sentinel(_Sentinel<!_Const> __i)
5748 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5749 : _M_inner(std::move(__i._M_inner))
5752 template<bool _OtherConst>
5753 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5754 friend constexpr bool
5755 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5756 { return __x._M_inner == __y._M_inner; }
5758 template<bool _OtherConst>
5759 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5760 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5761 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5762 { return __x._M_inner - __y._M_inner; }
5764 template<bool _OtherConst>
5765 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5766 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5767 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5768 { return __x._M_inner - __y._M_inner; }
5775 template<size_t _Nm, typename _Range, typename _Fp>
5776 concept __can_adjacent_transform_view
5777 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5778 (std::declval<_Range>(), std::declval<_Fp>()); };
5781 template<size_t _Nm>
5782 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5784 template<viewable_range _Range, typename _Fp>
5785 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5787 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
5789 if constexpr (_Nm == 0)
5790 return zip_transform(std::forward<_Fp>(__f));
5792 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5793 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5796 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5797 static constexpr int _S_arity = 2;
5798 static constexpr bool _S_has_simple_extra_args = true;
5801 template<size_t _Nm>
5802 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
5804 inline constexpr auto pairwise_transform = adjacent_transform<2>;
5807 #define __cpp_lib_ranges_chunk 202202L
5811 template<typename _Tp>
5812 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
5814 _Tp __r = __num / __denom;
5815 if (__num % __denom)
5822 requires input_range<_Vp>
5823 class chunk_view : public view_interface<chunk_view<_Vp>>
5826 range_difference_t<_Vp> _M_n;
5827 range_difference_t<_Vp> _M_remainder = 0;
5828 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
5835 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
5836 : _M_base(std::move(__base)), _M_n(__n)
5837 { __glibcxx_assert(__n >= 0); }
5840 base() const & requires copy_constructible<_Vp>
5845 { return std::move(_M_base); }
5847 constexpr _OuterIter
5850 _M_current = ranges::begin(_M_base);
5851 _M_remainder = _M_n;
5852 return _OuterIter(*this);
5855 constexpr default_sentinel_t
5856 end() const noexcept
5857 { return default_sentinel; }
5860 size() requires sized_range<_Vp>
5862 return __detail::__to_unsigned_like(__detail::__div_ceil
5863 (ranges::distance(_M_base), _M_n));
5867 size() const requires sized_range<const _Vp>
5869 return __detail::__to_unsigned_like(__detail::__div_ceil
5870 (ranges::distance(_M_base), _M_n));
5874 template<typename _Range>
5875 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
5878 requires input_range<_Vp>
5879 class chunk_view<_Vp>::_OuterIter
5881 chunk_view* _M_parent;
5884 _OuterIter(chunk_view& __parent) noexcept
5885 : _M_parent(std::__addressof(__parent))
5891 using iterator_concept = input_iterator_tag;
5892 using difference_type = range_difference_t<_Vp>;
5896 _OuterIter(_OuterIter&&) = default;
5897 _OuterIter& operator=(_OuterIter&&) = default;
5899 constexpr value_type
5902 __glibcxx_assert(*this != default_sentinel);
5903 return value_type(*_M_parent);
5906 constexpr _OuterIter&
5909 __glibcxx_assert(*this != default_sentinel);
5910 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
5911 ranges::end(_M_parent->_M_base));
5912 _M_parent->_M_remainder = _M_parent->_M_n;
5920 friend constexpr bool
5921 operator==(const _OuterIter& __x, default_sentinel_t)
5923 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
5924 && __x._M_parent->_M_remainder != 0;
5927 friend constexpr difference_type
5928 operator-(default_sentinel_t, const _OuterIter& __x)
5929 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5931 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
5933 if (__dist < __x._M_parent->_M_remainder)
5934 return __dist == 0 ? 0 : 1;
5936 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
5937 __x._M_parent->_M_n);
5940 friend constexpr difference_type
5941 operator-(const _OuterIter& __x, default_sentinel_t __y)
5942 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5943 { return -(__y - __x); }
5947 requires input_range<_Vp>
5948 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
5951 chunk_view* _M_parent;
5954 value_type(chunk_view& __parent) noexcept
5955 : _M_parent(std::__addressof(__parent))
5961 constexpr _InnerIter
5962 begin() const noexcept
5963 { return _InnerIter(*_M_parent); }
5965 constexpr default_sentinel_t
5966 end() const noexcept
5967 { return default_sentinel; }
5971 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5973 return __detail::__to_unsigned_like
5974 (ranges::min(_M_parent->_M_remainder,
5975 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
5980 requires input_range<_Vp>
5981 class chunk_view<_Vp>::_InnerIter
5983 chunk_view* _M_parent;
5986 _InnerIter(chunk_view& __parent) noexcept
5987 : _M_parent(std::__addressof(__parent))
5990 friend _OuterIter::value_type;
5993 using iterator_concept = input_iterator_tag;
5994 using difference_type = range_difference_t<_Vp>;
5995 using value_type = range_value_t<_Vp>;
5997 _InnerIter(_InnerIter&&) = default;
5998 _InnerIter& operator=(_InnerIter&&) = default;
6000 constexpr const iterator_t<_Vp>&
6002 { return *_M_parent->_M_current; }
6004 constexpr range_reference_t<_Vp>
6007 __glibcxx_assert(*this != default_sentinel);
6008 return **_M_parent->_M_current;
6011 constexpr _InnerIter&
6014 __glibcxx_assert(*this != default_sentinel);
6015 ++*_M_parent->_M_current;
6016 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6017 _M_parent->_M_remainder = 0;
6019 --_M_parent->_M_remainder;
6027 friend constexpr bool
6028 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6029 { return __x._M_parent->_M_remainder == 0; }
6031 friend constexpr difference_type
6032 operator-(default_sentinel_t, const _InnerIter& __x)
6033 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6035 return ranges::min(__x._M_parent->_M_remainder,
6036 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6039 friend constexpr difference_type
6040 operator-(const _InnerIter& __x, default_sentinel_t __y)
6041 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6042 { return -(__y - __x); }
6046 requires forward_range<_Vp>
6047 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6050 range_difference_t<_Vp> _M_n;
6051 template<bool> class _Iterator;
6055 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6056 : _M_base(std::move(__base)), _M_n(__n)
6057 { __glibcxx_assert(__n > 0); }
6060 base() const & requires copy_constructible<_Vp>
6065 { return std::move(_M_base); }
6068 begin() requires (!__detail::__simple_view<_Vp>)
6069 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6072 begin() const requires forward_range<const _Vp>
6073 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6076 end() requires (!__detail::__simple_view<_Vp>)
6078 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6080 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6081 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6083 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6084 return _Iterator<false>(this, ranges::end(_M_base));
6086 return default_sentinel;
6090 end() const requires forward_range<const _Vp>
6092 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6094 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6095 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6097 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6098 return _Iterator<true>(this, ranges::end(_M_base));
6100 return default_sentinel;
6104 size() requires sized_range<_Vp>
6106 return __detail::__to_unsigned_like(__detail::__div_ceil
6107 (ranges::distance(_M_base), _M_n));
6111 size() const requires sized_range<const _Vp>
6113 return __detail::__to_unsigned_like(__detail::__div_ceil
6114 (ranges::distance(_M_base), _M_n));
6118 template<typename _Vp>
6119 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6120 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6123 requires forward_range<_Vp>
6124 template<bool _Const>
6125 class chunk_view<_Vp>::_Iterator
6127 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6128 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6130 iterator_t<_Base> _M_current = iterator_t<_Base>();
6131 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6132 range_difference_t<_Base> _M_n = 0;
6133 range_difference_t<_Base> _M_missing = 0;
6136 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6137 range_difference_t<_Base> __missing = 0)
6138 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6139 _M_n(__parent->_M_n), _M_missing(__missing)
6145 if constexpr (random_access_range<_Base>)
6146 return random_access_iterator_tag{};
6147 else if constexpr (bidirectional_range<_Base>)
6148 return bidirectional_iterator_tag{};
6150 return forward_iterator_tag{};
6156 using iterator_category = input_iterator_tag;
6157 using iterator_concept = decltype(_S_iter_cat());
6158 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6159 using difference_type = range_difference_t<_Base>;
6161 _Iterator() = default;
6163 constexpr _Iterator(_Iterator<!_Const> __i)
6165 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6166 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6167 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6168 _M_n(__i._M_n), _M_missing(__i._M_missing)
6171 constexpr iterator_t<_Base>
6173 { return _M_current; }
6175 constexpr value_type
6178 __glibcxx_assert(_M_current != _M_end);
6179 return views::take(subrange(_M_current, _M_end), _M_n);
6182 constexpr _Iterator&
6185 __glibcxx_assert(_M_current != _M_end);
6186 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6198 constexpr _Iterator&
6199 operator--() requires bidirectional_range<_Base>
6201 ranges::advance(_M_current, _M_missing - _M_n);
6207 operator--(int) requires bidirectional_range<_Base>
6214 constexpr _Iterator&
6215 operator+=(difference_type __x)
6216 requires random_access_range<_Base>
6220 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6221 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6225 ranges::advance(_M_current, _M_n * __x + _M_missing);
6231 constexpr _Iterator&
6232 operator-=(difference_type __x)
6233 requires random_access_range<_Base>
6234 { return *this += -__x; }
6236 constexpr value_type
6237 operator[](difference_type __n) const
6238 requires random_access_range<_Base>
6239 { return *(*this + __n); }
6241 friend constexpr bool
6242 operator==(const _Iterator& __x, const _Iterator& __y)
6243 { return __x._M_current == __y._M_current; }
6245 friend constexpr bool
6246 operator==(const _Iterator& __x, default_sentinel_t)
6247 { return __x._M_current == __x._M_end; }
6249 friend constexpr bool
6250 operator<(const _Iterator& __x, const _Iterator& __y)
6251 requires random_access_range<_Base>
6252 { return __x._M_current > __y._M_current; }
6254 friend constexpr bool
6255 operator>(const _Iterator& __x, const _Iterator& __y)
6256 requires random_access_range<_Base>
6257 { return __y < __x; }
6259 friend constexpr bool
6260 operator<=(const _Iterator& __x, const _Iterator& __y)
6261 requires random_access_range<_Base>
6262 { return !(__y < __x); }
6264 friend constexpr bool
6265 operator>=(const _Iterator& __x, const _Iterator& __y)
6266 requires random_access_range<_Base>
6267 { return !(__x < __y); }
6269 friend constexpr auto
6270 operator<=>(const _Iterator& __x, const _Iterator& __y)
6271 requires random_access_range<_Base>
6272 && three_way_comparable<iterator_t<_Base>>
6273 { return __x._M_current <=> __y._M_current; }
6275 friend constexpr _Iterator
6276 operator+(const _Iterator& __i, difference_type __n)
6277 requires random_access_range<_Base>
6284 friend constexpr _Iterator
6285 operator+(difference_type __n, const _Iterator& __i)
6286 requires random_access_range<_Base>
6293 friend constexpr _Iterator
6294 operator-(const _Iterator& __i, difference_type __n)
6295 requires random_access_range<_Base>
6302 friend constexpr difference_type
6303 operator-(const _Iterator& __x, const _Iterator& __y)
6304 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6306 return (__x._M_current - __y._M_current
6307 + __x._M_missing - __y._M_missing) / __x._M_n;
6310 friend constexpr difference_type
6311 operator-(default_sentinel_t __y, const _Iterator& __x)
6312 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6313 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6315 friend constexpr difference_type
6316 operator-(const _Iterator& __x, default_sentinel_t __y)
6317 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6318 { return -(__y - __x); }
6325 template<typename _Range, typename _Dp>
6326 concept __can_chunk_view
6327 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6330 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6332 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6333 requires __detail::__can_chunk_view<_Range, _Dp>
6335 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6336 { return chunk_view(std::forward<_Range>(__r), __n); }
6338 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6339 static constexpr int _S_arity = 2;
6340 static constexpr bool _S_has_simple_extra_args = true;
6343 inline constexpr _Chunk chunk;
6346 #define __cpp_lib_ranges_slide 202202L
6350 template<typename _Vp>
6351 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6353 template<typename _Vp>
6354 concept __slide_caches_last
6355 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6357 template<typename _Vp>
6358 concept __slide_caches_first
6359 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6362 template<forward_range _Vp>
6364 class slide_view : public view_interface<slide_view<_Vp>>
6367 range_difference_t<_Vp> _M_n;
6368 [[no_unique_address]]
6369 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6370 __detail::_CachedPosition<_Vp>> _M_cached_begin;
6371 [[no_unique_address]]
6372 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6373 __detail::_CachedPosition<_Vp>> _M_cached_end;
6375 template<bool> class _Iterator;
6380 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6381 : _M_base(std::move(__base)), _M_n(__n)
6382 { __glibcxx_assert(__n > 0); }
6385 begin() requires (!(__detail::__simple_view<_Vp>
6386 && __detail::__slide_caches_nothing<const _Vp>))
6388 if constexpr (__detail::__slide_caches_first<_Vp>)
6390 iterator_t<_Vp> __it;
6391 if (_M_cached_begin._M_has_value())
6392 __it = _M_cached_begin._M_get(_M_base);
6395 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6396 _M_cached_begin._M_set(_M_base, __it);
6398 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6401 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6405 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6406 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6409 end() requires (!(__detail::__simple_view<_Vp>
6410 && __detail::__slide_caches_nothing<const _Vp>))
6412 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6413 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6415 else if constexpr (__detail::__slide_caches_last<_Vp>)
6417 iterator_t<_Vp> __it;
6418 if (_M_cached_end._M_has_value())
6419 __it = _M_cached_end._M_get(_M_base);
6422 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6423 _M_cached_end._M_set(_M_base, __it);
6425 return _Iterator<false>(std::move(__it), _M_n);
6427 else if constexpr (common_range<_Vp>)
6428 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6430 return _Sentinel(ranges::end(_M_base));
6434 end() const requires __detail::__slide_caches_nothing<const _Vp>
6435 { return begin() + range_difference_t<const _Vp>(size()); }
6438 size() requires sized_range<_Vp>
6440 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6443 return __detail::__to_unsigned_like(__sz);
6447 size() const requires sized_range<const _Vp>
6449 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6452 return __detail::__to_unsigned_like(__sz);
6456 template<typename _Range>
6457 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6459 template<typename _Vp>
6460 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6461 = enable_borrowed_range<_Vp>;
6463 template<forward_range _Vp>
6465 template<bool _Const>
6466 class slide_view<_Vp>::_Iterator
6468 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6469 static constexpr bool _S_last_elt_present
6470 = __detail::__slide_caches_first<_Base>;
6472 iterator_t<_Base> _M_current = iterator_t<_Base>();
6473 [[no_unique_address]]
6474 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6475 _M_last_elt = decltype(_M_last_elt)();
6476 range_difference_t<_Base> _M_n = 0;
6479 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6480 requires (!_S_last_elt_present)
6481 : _M_current(__current), _M_n(__n)
6485 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6486 range_difference_t<_Base> __n)
6487 requires _S_last_elt_present
6488 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6494 if constexpr (random_access_range<_Base>)
6495 return random_access_iterator_tag{};
6496 else if constexpr (bidirectional_range<_Base>)
6497 return bidirectional_iterator_tag{};
6499 return forward_iterator_tag{};
6503 friend slide_view::_Sentinel;
6506 using iterator_category = input_iterator_tag;
6507 using iterator_concept = decltype(_S_iter_concept());
6508 using value_type = decltype(views::counted(_M_current, _M_n));
6509 using difference_type = range_difference_t<_Base>;
6511 _Iterator() = default;
6514 _Iterator(_Iterator<!_Const> __i)
6515 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6516 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6521 { return views::counted(_M_current, _M_n); }
6523 constexpr _Iterator&
6527 if constexpr (_S_last_elt_present)
6540 constexpr _Iterator&
6541 operator--() requires bidirectional_range<_Base>
6544 if constexpr (_S_last_elt_present)
6550 operator--(int) requires bidirectional_range<_Base>
6557 constexpr _Iterator&
6558 operator+=(difference_type __x)
6559 requires random_access_range<_Base>
6562 if constexpr (_S_last_elt_present)
6567 constexpr _Iterator&
6568 operator-=(difference_type __x)
6569 requires random_access_range<_Base>
6572 if constexpr (_S_last_elt_present)
6578 operator[](difference_type __n) const
6579 requires random_access_range<_Base>
6580 { return views::counted(_M_current + __n, _M_n); }
6582 friend constexpr bool
6583 operator==(const _Iterator& __x, const _Iterator& __y)
6585 if constexpr (_S_last_elt_present)
6586 return __x._M_last_elt == __y._M_last_elt;
6588 return __x._M_current == __y._M_current;
6591 friend constexpr bool
6592 operator<(const _Iterator& __x, const _Iterator& __y)
6593 requires random_access_range<_Base>
6594 { return __x._M_current < __y._M_current; }
6596 friend constexpr bool
6597 operator>(const _Iterator& __x, const _Iterator& __y)
6598 requires random_access_range<_Base>
6599 { return __y < __x; }
6601 friend constexpr bool
6602 operator<=(const _Iterator& __x, const _Iterator& __y)
6603 requires random_access_range<_Base>
6604 { return !(__y < __x); }
6606 friend constexpr bool
6607 operator>=(const _Iterator& __x, const _Iterator& __y)
6608 requires random_access_range<_Base>
6609 { return !(__x < __y); }
6611 friend constexpr auto
6612 operator<=>(const _Iterator& __x, const _Iterator& __y)
6613 requires random_access_range<_Base>
6614 && three_way_comparable<iterator_t<_Base>>
6615 { return __x._M_current <=> __y._M_current; }
6617 friend constexpr _Iterator
6618 operator+(const _Iterator& __i, difference_type __n)
6619 requires random_access_range<_Base>
6626 friend constexpr _Iterator
6627 operator+(difference_type __n, const _Iterator& __i)
6628 requires random_access_range<_Base>
6635 friend constexpr _Iterator
6636 operator-(const _Iterator& __i, difference_type __n)
6637 requires random_access_range<_Base>
6644 friend constexpr difference_type
6645 operator-(const _Iterator& __x, const _Iterator& __y)
6646 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6648 if constexpr (_S_last_elt_present)
6649 return __x._M_last_elt - __y._M_last_elt;
6651 return __x._M_current - __y._M_current;
6655 template<forward_range _Vp>
6657 class slide_view<_Vp>::_Sentinel
6659 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6662 _Sentinel(sentinel_t<_Vp> __end)
6669 _Sentinel() = default;
6671 friend constexpr bool
6672 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6673 { return __x._M_last_elt == __y._M_end; }
6675 friend constexpr range_difference_t<_Vp>
6676 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6677 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6678 { return __x._M_last_elt - __y._M_end; }
6680 friend constexpr range_difference_t<_Vp>
6681 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6682 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6683 { return __y._M_end -__x._M_last_elt; }
6690 template<typename _Range, typename _Dp>
6691 concept __can_slide_view
6692 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6695 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6697 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6698 requires __detail::__can_slide_view<_Range, _Dp>
6700 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6701 { return slide_view(std::forward<_Range>(__r), __n); }
6703 using __adaptor::_RangeAdaptor<_Slide>::operator();
6704 static constexpr int _S_arity = 2;
6705 static constexpr bool _S_has_simple_extra_args = true;
6708 inline constexpr _Slide slide;
6711 #define __cpp_lib_ranges_chunk_by 202202L
6713 template<forward_range _Vp,
6714 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6715 requires view<_Vp> && is_object_v<_Pred>
6716 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6718 _Vp _M_base = _Vp();
6719 __detail::__box<_Pred> _M_pred = _Pred();
6720 __detail::_CachedPosition<_Vp> _M_cached_begin;
6722 constexpr iterator_t<_Vp>
6723 _M_find_next(iterator_t<_Vp> __current)
6725 __glibcxx_assert(_M_pred.has_value());
6726 auto __pred = [this]<typename _Tp>(_Tp&& __x, _Tp&& __y) {
6727 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Tp>(__y)));
6729 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6730 return ranges::next(__it, 1, ranges::end(_M_base));
6733 constexpr iterator_t<_Vp>
6734 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6736 __glibcxx_assert(_M_pred.has_value());
6737 auto __pred = [this]<typename _Tp>(_Tp&& __x, _Tp&& __y) {
6738 return !bool((*_M_pred)(std::forward<_Tp>(__y), std::forward<_Tp>(__x)));
6740 auto __rbegin = std::make_reverse_iterator(__current);
6741 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6742 __glibcxx_assert(__rbegin != __rend);
6743 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6744 return ranges::prev(__it, 1, ranges::begin(_M_base));
6750 chunk_by_view() requires (default_initializable<_Vp>
6751 && default_initializable<_Pred>)
6755 chunk_by_view(_Vp __base, _Pred __pred)
6756 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
6760 base() const & requires copy_constructible<_Vp>
6765 { return std::move(_M_base); }
6767 constexpr const _Pred&
6769 { return *_M_pred; }
6774 __glibcxx_assert(_M_pred.has_value());
6775 iterator_t<_Vp> __it;
6776 if (_M_cached_begin._M_has_value())
6777 __it = _M_cached_begin._M_get(_M_base);
6780 __it = _M_find_next(ranges::begin(_M_base));
6781 _M_cached_begin._M_set(_M_base, __it);
6783 return _Iterator(*this, ranges::begin(_M_base), __it);
6789 if constexpr (common_range<_Vp>)
6790 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
6792 return default_sentinel;
6796 template<typename _Range, typename _Pred>
6797 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6799 template<forward_range _Vp,
6800 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6801 requires view<_Vp> && is_object_v<_Pred>
6802 class chunk_by_view<_Vp, _Pred>::_Iterator
6804 chunk_by_view* _M_parent = nullptr;
6805 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
6806 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
6809 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
6810 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
6816 if constexpr (bidirectional_range<_Vp>)
6817 return bidirectional_iterator_tag{};
6819 return forward_iterator_tag{};
6822 friend chunk_by_view;
6825 using value_type = subrange<iterator_t<_Vp>>;
6826 using difference_type = range_difference_t<_Vp>;
6827 using iterator_category = input_iterator_tag;
6828 using iterator_concept = decltype(_S_iter_concept());
6830 _Iterator() = default;
6832 constexpr value_type
6835 __glibcxx_assert(_M_current != _M_next);
6836 return ranges::subrange(_M_current, _M_next);
6839 constexpr _Iterator&
6842 __glibcxx_assert(_M_current != _M_next);
6843 _M_current = _M_next;
6844 _M_next = _M_parent->_M_find_next(_M_current);
6856 constexpr _Iterator&
6857 operator--() requires bidirectional_range<_Vp>
6859 _M_next = _M_current;
6860 _M_current = _M_parent->_M_find_prev(_M_next);
6865 operator--(int) requires bidirectional_range<_Vp>
6872 friend constexpr bool
6873 operator==(const _Iterator& __x, const _Iterator& __y)
6874 { return __x._M_current == __y._M_current; }
6876 friend constexpr bool
6877 operator==(const _Iterator& __x, default_sentinel_t)
6878 { return __x._M_current == __x._M_next; }
6885 template<typename _Range, typename _Pred>
6886 concept __can_chunk_by_view
6887 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
6890 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
6892 template<viewable_range _Range, typename _Pred>
6893 requires __detail::__can_chunk_by_view<_Range, _Pred>
6895 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
6896 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
6898 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
6899 static constexpr int _S_arity = 2;
6900 static constexpr bool _S_has_simple_extra_args = true;
6903 inline constexpr _ChunkBy chunk_by;
6906 #define __cpp_lib_ranges_join_with 202202L
6910 template<typename _Range, typename _Pattern>
6911 concept __compatible_joinable_ranges
6912 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
6913 && common_reference_with<range_reference_t<_Range>,
6914 range_reference_t<_Pattern>>
6915 && common_reference_with<range_rvalue_reference_t<_Range>,
6916 range_rvalue_reference_t<_Pattern>>;
6918 template<typename _Range>
6919 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
6922 template<input_range _Vp, forward_range _Pattern>
6923 requires view<_Vp> && view<_Pattern>
6924 && input_range<range_reference_t<_Vp>>
6925 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
6926 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
6928 using _InnerRange = range_reference_t<_Vp>;
6930 _Vp _M_base = _Vp();
6931 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
6932 _Pattern _M_pattern = _Pattern();
6934 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6935 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
6936 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
6938 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
6939 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
6940 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
6942 template<bool _Const>
6943 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
6945 template<bool _Const>
6949 template<bool _Const>
6950 requires _S_ref_is_glvalue<_Const>
6951 && forward_range<_Base<_Const>>
6952 && forward_range<_InnerBase<_Const>>
6953 struct __iter_cat<_Const>
6959 using _OuterIter = join_with_view::_OuterIter<_Const>;
6960 using _InnerIter = join_with_view::_InnerIter<_Const>;
6961 using _PatternIter = join_with_view::_PatternIter<_Const>;
6962 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
6963 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
6964 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
6965 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
6966 iter_reference_t<_PatternIter>>>)
6967 return input_iterator_tag{};
6968 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
6969 && derived_from<_InnerCat, bidirectional_iterator_tag>
6970 && derived_from<_PatternCat, bidirectional_iterator_tag>
6971 && common_range<_InnerBase<_Const>>
6972 && common_range<_PatternBase<_Const>>)
6973 return bidirectional_iterator_tag{};
6974 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
6975 && derived_from<_InnerCat, forward_iterator_tag>
6976 && derived_from<_PatternCat, forward_iterator_tag>)
6977 return forward_iterator_tag{};
6979 return input_iterator_tag{};
6982 using iterator_category = decltype(_S_iter_cat());
6985 template<bool> struct _Iterator;
6986 template<bool> struct _Sentinel;
6989 join_with_view() requires (default_initializable<_Vp>
6990 && default_initializable<_Pattern>)
6994 join_with_view(_Vp __base, _Pattern __pattern)
6995 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
6998 template<input_range _Range>
6999 requires constructible_from<_Vp, views::all_t<_Range>>
7000 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7002 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7003 : _M_base(views::all(std::forward<_Range>(__r))),
7004 _M_pattern(views::single(std::move(__e)))
7008 base() const& requires copy_constructible<_Vp>
7013 { return std::move(_M_base); }
7018 constexpr bool __use_const = is_reference_v<_InnerRange>
7019 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7020 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7025 requires input_range<const _Vp>
7026 && forward_range<const _Pattern>
7027 && is_reference_v<range_reference_t<const _Vp>>
7028 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7033 constexpr bool __use_const
7034 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7035 if constexpr (is_reference_v<_InnerRange>
7036 && forward_range<_Vp> && common_range<_Vp>
7037 && forward_range<_InnerRange> && common_range<_InnerRange>)
7038 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7040 return _Sentinel<__use_const>{*this};
7045 requires input_range<const _Vp>
7046 && forward_range<const _Pattern>
7047 && is_reference_v<range_reference_t<const _Vp>>
7049 using _InnerConstRange = range_reference_t<const _Vp>;
7050 if constexpr (forward_range<const _Vp>
7051 && forward_range<_InnerConstRange>
7052 && common_range<const _Vp>
7053 && common_range<_InnerConstRange>)
7054 return _Iterator<true>{*this, ranges::end(_M_base)};
7056 return _Sentinel<true>{*this};
7060 template<typename _Range, typename _Pattern>
7061 join_with_view(_Range&&, _Pattern&&)
7062 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7064 template<input_range _Range>
7065 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7066 -> join_with_view<views::all_t<_Range>,
7067 single_view<range_value_t<range_reference_t<_Range>>>>;
7069 template<input_range _Vp, forward_range _Pattern>
7070 requires view<_Vp> && view<_Pattern>
7071 && input_range<range_reference_t<_Vp>>
7072 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7073 template<bool _Const>
7074 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7076 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7077 using _Base = join_with_view::_Base<_Const>;
7078 using _InnerBase = join_with_view::_InnerBase<_Const>;
7079 using _PatternBase = join_with_view::_PatternBase<_Const>;
7081 using _OuterIter = join_with_view::_OuterIter<_Const>;
7082 using _InnerIter = join_with_view::_InnerIter<_Const>;
7083 using _PatternIter = join_with_view::_PatternIter<_Const>;
7085 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7087 _Parent* _M_parent = nullptr;
7088 _OuterIter _M_outer_it = _OuterIter();
7089 variant<_PatternIter, _InnerIter> _M_inner_it;
7092 _Iterator(_Parent& __parent, iterator_t<_Base> __outer)
7093 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7095 if (_M_outer_it != ranges::end(_M_parent->_M_base))
7097 auto&& __inner = _M_update_inner(_M_outer_it);
7098 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7104 _M_update_inner(const _OuterIter& __x)
7106 if constexpr (_S_ref_is_glvalue)
7109 return _M_parent->_M_inner._M_emplace_deref(__x);
7113 _M_get_inner(const _OuterIter& __x)
7115 if constexpr (_S_ref_is_glvalue)
7118 return *_M_parent->_M_inner;
7126 if (_M_inner_it.index() == 0)
7128 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7131 auto&& __inner = _M_update_inner(_M_outer_it);
7132 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7136 auto&& __inner = _M_get_inner(_M_outer_it);
7137 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7140 if (++_M_outer_it == ranges::end(_M_parent->_M_base))
7142 if constexpr (_S_ref_is_glvalue)
7143 _M_inner_it.template emplace<0>();
7147 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7155 if constexpr (_S_ref_is_glvalue
7156 && bidirectional_range<_Base>
7157 && __detail::__bidirectional_common<_InnerBase>
7158 && __detail::__bidirectional_common<_PatternBase>)
7159 return bidirectional_iterator_tag{};
7160 else if constexpr (_S_ref_is_glvalue
7161 && forward_range<_Base>
7162 && forward_range<_InnerBase>)
7163 return forward_iterator_tag{};
7165 return input_iterator_tag{};
7168 friend join_with_view;
7171 using iterator_concept = decltype(_S_iter_concept());
7172 // iterator_category defined in join_with_view::__iter_cat
7173 using value_type = common_type_t<iter_value_t<_InnerIter>,
7174 iter_value_t<_PatternIter>>;
7175 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7176 iter_difference_t<_InnerIter>,
7177 iter_difference_t<_PatternIter>>;
7179 _Iterator() requires default_initializable<_OuterIter> = default;
7182 _Iterator(_Iterator<!_Const> __i)
7184 && convertible_to<iterator_t<_Vp>, _OuterIter>
7185 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7186 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7187 : _M_parent(__i._M_parent),
7188 _M_outer_it(std::move(__i._M_outer_it))
7190 if (__i._M_inner_it.index() == 0)
7191 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7193 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7196 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7197 iter_reference_t<_PatternIter>>
7200 if (_M_inner_it.index() == 0)
7201 return *std::get<0>(_M_inner_it);
7203 return *std::get<1>(_M_inner_it);
7206 constexpr _Iterator&
7209 if (_M_inner_it.index() == 0)
7210 ++std::get<0>(_M_inner_it);
7212 ++std::get<1>(_M_inner_it);
7223 requires _S_ref_is_glvalue
7224 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7226 _Iterator __tmp = *this;
7231 constexpr _Iterator&
7233 requires _S_ref_is_glvalue
7234 && bidirectional_range<_Base>
7235 && __detail::__bidirectional_common<_InnerBase>
7236 && __detail::__bidirectional_common<_PatternBase>
7238 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7240 auto&& __inner = *--_M_outer_it;
7241 _M_inner_it.template emplace<1>(ranges::end(__inner));
7246 if (_M_inner_it.index() == 0)
7248 auto& __it = std::get<0>(_M_inner_it);
7249 if (__it == ranges::begin(_M_parent->_M_pattern))
7251 auto&& __inner = *--_M_outer_it;
7252 _M_inner_it.template emplace<1>(ranges::end(__inner));
7259 auto& __it = std::get<1>(_M_inner_it);
7260 auto&& __inner = *_M_outer_it;
7261 if (__it == ranges::begin(__inner))
7262 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7268 if (_M_inner_it.index() == 0)
7269 --std::get<0>(_M_inner_it);
7271 --std::get<1>(_M_inner_it);
7277 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7278 && __detail::__bidirectional_common<_InnerBase>
7279 && __detail::__bidirectional_common<_PatternBase>
7281 _Iterator __tmp = *this;
7286 friend constexpr bool
7287 operator==(const _Iterator& __x, const _Iterator& __y)
7288 requires _S_ref_is_glvalue
7289 && equality_comparable<_OuterIter> && equality_comparable<_InnerIter>
7290 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7292 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7293 iter_rvalue_reference_t<_PatternIter>>
7294 iter_move(const _Iterator& __x)
7296 if (__x._M_inner_it.index() == 0)
7297 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7299 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7302 friend constexpr void
7303 iter_swap(const _Iterator& __x, const _Iterator& __y)
7304 requires indirectly_swappable<_InnerIter, _PatternIter>
7306 if (__x._M_inner_it.index() == 0)
7308 if (__y._M_inner_it.index() == 0)
7309 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7311 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7315 if (__y._M_inner_it.index() == 0)
7316 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7318 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7323 template<input_range _Vp, forward_range _Pattern>
7324 requires view<_Vp> && view<_Pattern>
7325 && input_range<range_reference_t<_Vp>>
7326 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7327 template<bool _Const>
7328 class join_with_view<_Vp, _Pattern>::_Sentinel
7330 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7331 using _Base = join_with_view::_Base<_Const>;
7333 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7336 _Sentinel(_Parent& __parent)
7337 : _M_end(ranges::end(__parent._M_base))
7340 friend join_with_view;
7343 _Sentinel() = default;
7346 _Sentinel(_Sentinel<!_Const> __s)
7347 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7348 : _M_end(std::move(__s._M_end))
7351 template<bool _OtherConst>
7352 requires sentinel_for<sentinel_t<_Base>,
7353 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7354 friend constexpr bool
7355 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7356 { return __x._M_outer_it == __y._M_end; }
7363 template<typename _Range, typename _Pattern>
7364 concept __can_join_with_view
7365 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7366 } // namespace __detail
7368 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7370 template<viewable_range _Range, typename _Pattern>
7371 requires __detail::__can_join_with_view<_Range, _Pattern>
7373 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7375 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7378 using _RangeAdaptor<_JoinWith>::operator();
7379 static constexpr int _S_arity = 2;
7380 template<typename _Pattern>
7381 static constexpr bool _S_has_simple_extra_args
7382 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7385 inline constexpr _JoinWith join_with;
7386 } // namespace views
7388 #define __cpp_lib_ranges_repeat 202207L
7390 template<copy_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7391 requires (is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7392 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
7393 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7395 __detail::__box<_Tp> _M_value = _Tp();
7396 [[no_unique_address]] _Bound _M_bound = _Bound();
7400 template<typename _Range>
7401 friend constexpr auto
7402 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7404 template<typename _Range>
7405 friend constexpr auto
7406 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7409 repeat_view() requires default_initializable<_Tp> = default;
7412 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7413 : _M_value(__value), _M_bound(__bound)
7415 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7416 __glibcxx_assert(__bound >= 0);
7420 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7421 : _M_value(std::move(__value)), _M_bound(__bound)
7424 template<typename... _Args, typename... _BoundArgs>
7425 requires constructible_from<_Tp, _Args...>
7426 && constructible_from<_Bound, _BoundArgs...>
7428 repeat_view(piecewise_construct_t,
7429 tuple<_Args...> __args,
7430 tuple<_BoundArgs...> __bound_args = tuple<>{})
7431 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7432 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7437 { return _Iterator(std::__addressof(*_M_value)); }
7440 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7441 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7443 constexpr unreachable_sentinel_t
7444 end() const noexcept
7445 { return unreachable_sentinel; }
7448 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7449 { return __detail::__to_unsigned_like(_M_bound); }
7452 template<typename _Tp, typename _Bound>
7453 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7455 template<copy_constructible _Tp, semiregular _Bound>
7456 requires __detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>
7457 class repeat_view<_Tp, _Bound>::_Iterator
7460 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7462 const _Tp* _M_value = nullptr;
7463 __index_type _M_current = __index_type();
7466 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7467 : _M_value(__value), _M_current(__bound)
7469 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7470 __glibcxx_assert(__bound >= 0);
7476 using iterator_concept = random_access_iterator_tag;
7477 using iterator_category = random_access_iterator_tag;
7478 using value_type = _Tp;
7479 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7481 __detail::__iota_diff_t<__index_type>>;
7483 _Iterator() = default;
7485 constexpr const _Tp&
7486 operator*() const noexcept
7487 { return *_M_value; }
7489 constexpr _Iterator&
7504 constexpr _Iterator&
7507 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7508 __glibcxx_assert(_M_current > 0);
7521 constexpr _Iterator&
7522 operator+=(difference_type __n)
7524 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7525 __glibcxx_assert(_M_current + __n >= 0);
7530 constexpr _Iterator&
7531 operator-=(difference_type __n)
7533 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7534 __glibcxx_assert(_M_current - __n >= 0);
7539 constexpr const _Tp&
7540 operator[](difference_type __n) const noexcept
7541 { return *(*this + __n); }
7543 friend constexpr bool
7544 operator==(const _Iterator& __x, const _Iterator& __y)
7545 { return __x._M_current == __y._M_current; }
7547 friend constexpr auto
7548 operator<=>(const _Iterator& __x, const _Iterator& __y)
7549 { return __x._M_current <=> __y._M_current; }
7551 friend constexpr _Iterator
7552 operator+(_Iterator __i, difference_type __n)
7558 friend constexpr _Iterator
7559 operator+(difference_type __n, _Iterator __i)
7560 { return __i + __n; }
7562 friend constexpr _Iterator
7563 operator-(_Iterator __i, difference_type __n)
7569 friend constexpr difference_type
7570 operator-(const _Iterator& __x, const _Iterator& __y)
7572 return (static_cast<difference_type>(__x._M_current)
7573 - static_cast<difference_type>(__y._M_current));
7581 template<typename _Tp, typename _Bound>
7582 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7584 template<typename _Tp>
7585 concept __can_repeat_view
7586 = requires { repeat_view(std::declval<_Tp>()); };
7588 template<typename _Tp, typename _Bound>
7589 concept __can_bounded_repeat_view
7590 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7595 template<typename _Tp>
7596 requires __detail::__can_repeat_view<_Tp>
7598 operator() [[nodiscard]] (_Tp&& __value) const
7599 { return repeat_view(std::forward<_Tp>(__value)); }
7601 template<typename _Tp, typename _Bound>
7602 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7604 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7605 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7608 inline constexpr _Repeat repeat;
7612 template<typename _Range>
7614 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7616 using _Tp = remove_cvref_t<_Range>;
7617 static_assert(__is_repeat_view<_Tp>);
7618 if constexpr (sized_range<_Tp>)
7619 return views::repeat(*__r._M_value, std::min(ranges::distance(__r), __n));
7621 return views::repeat(*__r._M_value, __n);
7624 template<typename _Range>
7626 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7628 using _Tp = remove_cvref_t<_Range>;
7629 static_assert(__is_repeat_view<_Tp>);
7630 if constexpr (sized_range<_Tp>)
7632 auto __sz = ranges::distance(__r);
7633 return views::repeat(*__r._M_value, __sz - std::min(__sz, __n));
7641 #define __cpp_lib_ranges_stride 202207L
7643 template<input_range _Vp>
7645 class stride_view : public view_interface<stride_view<_Vp>>
7648 range_difference_t<_Vp> _M_stride;
7650 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7652 template<bool _Const>
7656 template<bool _Const>
7657 requires forward_range<_Base<_Const>>
7658 struct __iter_cat<_Const>
7664 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7665 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7666 return random_access_iterator_tag{};
7671 using iterator_category = decltype(_S_iter_cat());
7674 template<bool> class _Iterator;
7678 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7679 : _M_base(std::move(__base)), _M_stride(__stride)
7680 { __glibcxx_assert(__stride > 0); }
7683 base() const& requires copy_constructible<_Vp>
7688 { return std::move(_M_base); }
7690 constexpr range_difference_t<_Vp>
7691 stride() const noexcept
7692 { return _M_stride; }
7695 begin() requires (!__detail::__simple_view<_Vp>)
7696 { return _Iterator<false>(this, ranges::begin(_M_base)); }
7699 begin() const requires range<const _Vp>
7700 { return _Iterator<true>(this, ranges::begin(_M_base)); }
7703 end() requires (!__detail::__simple_view<_Vp>)
7705 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7707 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7708 return _Iterator<false>(this, ranges::end(_M_base), __missing);
7710 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7711 return _Iterator<false>(this, ranges::end(_M_base));
7713 return default_sentinel;
7717 end() const requires range<const _Vp>
7719 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7720 && forward_range<const _Vp>)
7722 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7723 return _Iterator<true>(this, ranges::end(_M_base), __missing);
7725 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7726 return _Iterator<true>(this, ranges::end(_M_base));
7728 return default_sentinel;
7732 size() requires sized_range<_Vp>
7734 return __detail::__to_unsigned_like
7735 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7739 size() const requires sized_range<const _Vp>
7741 return __detail::__to_unsigned_like
7742 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7746 template<typename _Range>
7747 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7749 template<typename _Vp>
7750 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7751 = enable_borrowed_range<_Vp>;
7753 template<input_range _Vp>
7755 template<bool _Const>
7756 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
7758 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
7759 using _Base = stride_view::_Base<_Const>;
7761 iterator_t<_Base> _M_current = iterator_t<_Base>();
7762 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7763 range_difference_t<_Base> _M_stride = 0;
7764 range_difference_t<_Base> _M_missing = 0;
7767 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
7768 range_difference_t<_Base> __missing = 0)
7769 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
7770 _M_stride(__parent->_M_stride), _M_missing(__missing)
7776 if constexpr (random_access_range<_Base>)
7777 return random_access_iterator_tag{};
7778 else if constexpr (bidirectional_range<_Base>)
7779 return bidirectional_iterator_tag{};
7780 else if constexpr (forward_range<_Base>)
7781 return forward_iterator_tag{};
7783 return input_iterator_tag{};
7789 using difference_type = range_difference_t<_Base>;
7790 using value_type = range_value_t<_Base>;
7791 using iterator_concept = decltype(_S_iter_concept());
7792 // iterator_category defined in stride_view::__iter_cat
7794 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
7797 _Iterator(_Iterator<!_Const> __other)
7799 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7800 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7801 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
7802 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
7805 constexpr iterator_t<_Base>
7807 { return std::move(_M_current); }
7809 constexpr const iterator_t<_Base>&
7810 base() const & noexcept
7811 { return _M_current; }
7813 constexpr decltype(auto)
7815 { return *_M_current; }
7817 constexpr _Iterator&
7820 __glibcxx_assert(_M_current != _M_end);
7821 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
7830 operator++(int) requires forward_range<_Base>
7837 constexpr _Iterator&
7838 operator--() requires bidirectional_range<_Base>
7840 ranges::advance(_M_current, _M_missing - _M_stride);
7846 operator--(int) requires bidirectional_range<_Base>
7853 constexpr _Iterator&
7854 operator+=(difference_type __n) requires random_access_range<_Base>
7858 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
7859 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
7863 ranges::advance(_M_current, _M_stride * __n + _M_missing);
7869 constexpr _Iterator&
7870 operator-=(difference_type __n) requires random_access_range<_Base>
7871 { return *this += -__n; }
7873 constexpr decltype(auto) operator[](difference_type __n) const
7874 requires random_access_range<_Base>
7875 { return *(*this + __n); }
7877 friend constexpr bool
7878 operator==(const _Iterator& __x, default_sentinel_t)
7879 { return __x._M_current == __x._M_end; }
7881 friend constexpr bool
7882 operator==(const _Iterator& __x, const _Iterator& __y)
7883 requires equality_comparable<iterator_t<_Base>>
7884 { return __x._M_current == __y._M_current; }
7886 friend constexpr bool
7887 operator<(const _Iterator& __x, const _Iterator& __y)
7888 requires random_access_range<_Base>
7889 { return __x._M_current < __y._M_current; }
7891 friend constexpr bool
7892 operator>(const _Iterator& __x, const _Iterator& __y)
7893 requires random_access_range<_Base>
7894 { return __y._M_current < __x._M_current; }
7896 friend constexpr bool
7897 operator<=(const _Iterator& __x, const _Iterator& __y)
7898 requires random_access_range<_Base>
7899 { return !(__y._M_current < __x._M_current); }
7901 friend constexpr bool
7902 operator>=(const _Iterator& __x, const _Iterator& __y)
7903 requires random_access_range<_Base>
7904 { return !(__x._M_current < __y._M_current); }
7906 friend constexpr auto
7907 operator<=>(const _Iterator& __x, const _Iterator& __y)
7908 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
7909 { return __x._M_current <=> __y._M_current; }
7911 friend constexpr _Iterator
7912 operator+(const _Iterator& __i, difference_type __n)
7913 requires random_access_range<_Base>
7920 friend constexpr _Iterator
7921 operator+(difference_type __n, const _Iterator& __i)
7922 requires random_access_range<_Base>
7923 { return __i + __n; }
7925 friend constexpr _Iterator
7926 operator-(const _Iterator& __i, difference_type __n)
7927 requires random_access_range<_Base>
7934 friend constexpr difference_type
7935 operator-(const _Iterator& __x, const _Iterator& __y)
7936 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7938 auto __n = __x._M_current - __y._M_current;
7939 if constexpr (forward_range<_Base>)
7940 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
7942 return -__detail::__div_ceil(-__n, __x._M_stride);
7944 return __detail::__div_ceil(__n, __x._M_stride);
7947 friend constexpr difference_type
7948 operator-(default_sentinel_t __y, const _Iterator& __x)
7949 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7950 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
7952 friend constexpr difference_type
7953 operator-(const _Iterator& __x, default_sentinel_t __y)
7954 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7955 { return -(__y - __x); }
7957 friend constexpr range_rvalue_reference_t<_Base>
7958 iter_move(const _Iterator& __i)
7959 noexcept(noexcept(ranges::iter_move(__i._M_current)))
7960 { return ranges::iter_move(__i._M_current); }
7962 friend constexpr void
7963 iter_swap(const _Iterator& __x, const _Iterator& __y)
7964 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
7965 requires indirectly_swappable<iterator_t<_Base>>
7966 { ranges::iter_swap(__x._M_current, __y._M_current); }
7973 template<typename _Range, typename _Dp>
7974 concept __can_stride_view
7975 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
7978 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
7980 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
7981 requires __detail::__can_stride_view<_Range, _Dp>
7983 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
7984 { return stride_view(std::forward<_Range>(__r), __n); }
7986 using __adaptor::_RangeAdaptor<_Stride>::operator();
7987 static constexpr int _S_arity = 2;
7988 static constexpr bool _S_has_simple_extra_args = true;
7991 inline constexpr _Stride stride;
7994 #define __cpp_lib_ranges_cartesian_product 202207L
7998 template<bool _Const, typename _First, typename... _Vs>
7999 concept __cartesian_product_is_random_access
8000 = (random_access_range<__maybe_const_t<_Const, _First>>
8002 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8003 && sized_range<__maybe_const_t<_Const, _Vs>>));
8005 template<typename _Range>
8006 concept __cartesian_product_common_arg
8007 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8009 template<bool _Const, typename _First, typename... _Vs>
8010 concept __cartesian_product_is_bidirectional
8011 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8013 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8014 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8016 template<typename _First, typename... _Vs>
8017 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8019 template<typename... _Vs>
8020 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8022 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8023 concept __cartesian_is_sized_sentinel
8024 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8025 iterator_t<__maybe_const_t<_Const, _First>>>
8027 && (sized_range<__maybe_const_t<_Const, _Vs>>
8028 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8029 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8031 template<__cartesian_product_common_arg _Range>
8033 __cartesian_common_arg_end(_Range& __r)
8035 if constexpr (common_range<_Range>)
8036 return ranges::end(__r);
8038 return ranges::begin(__r) + ranges::distance(__r);
8040 } // namespace __detail
8042 template<input_range _First, forward_range... _Vs>
8043 requires (view<_First> && ... && view<_Vs>)
8044 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8046 tuple<_First, _Vs...> _M_bases;
8048 template<bool> class _Iterator;
8051 _S_difference_type()
8053 // TODO: Implement the recommended practice of using the smallest
8054 // sufficiently wide type according to the maximum sizes of the
8055 // underlying ranges?
8056 return common_type_t<ptrdiff_t,
8057 range_difference_t<_First>,
8058 range_difference_t<_Vs>...>{};
8062 cartesian_product_view() = default;
8065 cartesian_product_view(_First __first, _Vs... __rest)
8066 : _M_bases(std::move(__first), std::move(__rest)...)
8069 constexpr _Iterator<false>
8070 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8071 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8073 constexpr _Iterator<true>
8074 begin() const requires (range<const _First> && ... && range<const _Vs>)
8075 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8077 constexpr _Iterator<false>
8078 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8079 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8081 bool __empty_tail = [this]<size_t... _Is>(index_sequence<_Is...>) {
8082 return (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8083 }(make_index_sequence<sizeof...(_Vs)>{});
8085 auto __it = __detail::__tuple_transform(ranges::begin, _M_bases);
8087 std::get<0>(__it) = __detail::__cartesian_common_arg_end(std::get<0>(_M_bases));
8088 return _Iterator<false>{*this, std::move(__it)};
8091 constexpr _Iterator<true>
8092 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8094 bool __empty_tail = [this]<size_t... _Is>(index_sequence<_Is...>) {
8095 return (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8096 }(make_index_sequence<sizeof...(_Vs)>{});
8098 auto __it = __detail::__tuple_transform(ranges::begin, _M_bases);
8100 std::get<0>(__it) = __detail::__cartesian_common_arg_end(std::get<0>(_M_bases));
8101 return _Iterator<true>{*this, std::move(__it)};
8104 constexpr default_sentinel_t
8105 end() const noexcept
8106 { return default_sentinel; }
8109 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8111 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8112 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8113 auto __size = static_cast<_ST>(1);
8114 #ifdef _GLIBCXX_ASSERTIONS
8115 if constexpr (integral<_ST>)
8118 = (__builtin_mul_overflow(__size,
8119 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8122 __glibcxx_assert(!__overflow);
8126 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8128 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8132 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8134 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8135 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8136 auto __size = static_cast<_ST>(1);
8137 #ifdef _GLIBCXX_ASSERTIONS
8138 if constexpr (integral<_ST>)
8141 = (__builtin_mul_overflow(__size,
8142 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8145 __glibcxx_assert(!__overflow);
8149 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8151 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8155 template<typename... _Vs>
8156 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8158 template<input_range _First, forward_range... _Vs>
8159 requires (view<_First> && ... && view<_Vs>)
8160 template<bool _Const>
8161 class cartesian_product_view<_First, _Vs...>::_Iterator
8163 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8164 _Parent* _M_parent = nullptr;
8165 __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
8166 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8169 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8170 : _M_parent(std::__addressof(__parent)),
8171 _M_current(std::move(__current))
8177 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8178 return random_access_iterator_tag{};
8179 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8180 return bidirectional_iterator_tag{};
8181 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8182 return forward_iterator_tag{};
8184 return input_iterator_tag{};
8187 friend cartesian_product_view;
8190 using iterator_category = input_iterator_tag;
8191 using iterator_concept = decltype(_S_iter_concept());
8193 = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
8194 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8196 = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
8197 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8198 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8200 _Iterator() requires forward_range<__maybe_const_t<_Const, _First>> = default;
8203 _Iterator(_Iterator<!_Const> __i)
8205 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8206 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8207 : _M_parent(std::__addressof(__i._M_parent)),
8208 _M_current(std::move(__i._M_current))
8214 auto __f = [](auto& __i) -> decltype(auto) {
8217 return __detail::__tuple_transform(__f, _M_current);
8220 constexpr _Iterator&
8232 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8239 constexpr _Iterator&
8241 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8249 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8256 constexpr _Iterator&
8257 operator+=(difference_type __x)
8258 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8264 constexpr _Iterator&
8265 operator-=(difference_type __x)
8266 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8267 { return *this += -__x; }
8270 operator[](difference_type __n) const
8271 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8272 { return *((*this) + __n); }
8274 friend constexpr bool
8275 operator==(const _Iterator& __x, const _Iterator& __y)
8276 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8277 { return __x._M_current == __y._M_current; }
8279 friend constexpr bool
8280 operator==(const _Iterator& __x, default_sentinel_t)
8282 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8283 return ((std::get<_Is>(__x._M_current)
8284 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8286 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8289 friend constexpr auto
8290 operator<=>(const _Iterator& __x, const _Iterator& __y)
8291 requires __detail::__all_random_access<_Const, _First, _Vs...>
8292 { return __x._M_current <=> __y._M_current; }
8294 friend constexpr _Iterator
8295 operator+(_Iterator __x, difference_type __y)
8296 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8297 { return __x += __y; }
8299 friend constexpr _Iterator
8300 operator+(difference_type __x, _Iterator __y)
8301 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8302 { return __y += __x; }
8304 friend constexpr _Iterator
8305 operator-(_Iterator __x, difference_type __y)
8306 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8307 { return __x -= __y; }
8309 friend constexpr difference_type
8310 operator-(const _Iterator& __x, const _Iterator& __y)
8311 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8312 { return __x._M_distance_from(__y._M_current); }
8314 friend constexpr difference_type
8315 operator-(const _Iterator& __i, default_sentinel_t)
8316 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8318 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8319 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8320 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8321 }(make_index_sequence<sizeof...(_Vs)>{});
8322 return __i._M_distance_from(__end_tuple);
8325 friend constexpr difference_type
8326 operator-(default_sentinel_t, const _Iterator& __i)
8327 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8328 { return -(__i - default_sentinel); }
8330 friend constexpr auto
8331 iter_move(const _Iterator& __i)
8332 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8334 friend constexpr void
8335 iter_swap(const _Iterator& __l, const _Iterator& __r)
8336 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8338 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8340 [&]<size_t... _Is>(index_sequence<_Is...>) {
8341 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8342 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8346 template<size_t _Nm = sizeof...(_Vs)>
8350 auto& __it = std::get<_Nm>(_M_current);
8352 if constexpr (_Nm > 0)
8353 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8355 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8360 template<size_t _Nm = sizeof...(_Vs)>
8364 auto& __it = std::get<_Nm>(_M_current);
8365 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8367 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8368 if constexpr (_Nm > 0)
8374 template<size_t _Nm = sizeof...(_Vs)>
8376 _M_advance(difference_type __x)
8377 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8385 // Constant time iterator advancement.
8386 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8387 auto& __it = std::get<_Nm>(_M_current);
8388 if constexpr (_Nm == 0)
8390 #ifdef _GLIBCXX_ASSERTIONS
8391 auto __size = ranges::ssize(__r);
8392 auto __begin = ranges::begin(__r);
8393 auto __offset = __it - __begin;
8394 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8400 auto __size = ranges::ssize(__r);
8401 auto __begin = ranges::begin(__r);
8402 auto __offset = __it - __begin;
8404 __x = __offset / __size;
8408 __offset = __size + __offset;
8411 __it = __begin + __offset;
8412 _M_advance<_Nm - 1>(__x);
8417 template<typename _Tuple>
8418 constexpr difference_type
8419 _M_distance_from(const _Tuple& __t) const
8421 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8422 auto __sum = static_cast<difference_type>(0);
8423 #ifdef _GLIBCXX_ASSERTIONS
8424 if constexpr (integral<difference_type>)
8427 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8429 __glibcxx_assert(!__overflow);
8433 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8435 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8438 template<size_t _Nm, typename _Tuple>
8439 constexpr difference_type
8440 _M_scaled_distance(const _Tuple& __t) const
8442 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8443 - std::get<_Nm>(__t));
8444 #ifdef _GLIBCXX_ASSERTIONS
8445 if constexpr (integral<difference_type>)
8447 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8448 __glibcxx_assert(!__overflow);
8452 __dist *= _M_scaled_size<_Nm+1>();
8456 template<size_t _Nm>
8457 constexpr difference_type
8458 _M_scaled_size() const
8460 if constexpr (_Nm <= sizeof...(_Vs))
8462 auto __size = static_cast<difference_type>(ranges::size
8463 (std::get<_Nm>(_M_parent->_M_bases)));
8464 #ifdef _GLIBCXX_ASSERTIONS
8465 if constexpr (integral<difference_type>)
8467 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8468 __glibcxx_assert(!__overflow);
8472 __size *= _M_scaled_size<_Nm+1>();
8476 return static_cast<difference_type>(1);
8484 template<typename... _Ts>
8485 concept __can_cartesian_product_view
8486 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8489 struct _CartesianProduct
8491 template<typename... _Ts>
8492 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8494 operator() [[nodiscard]] (_Ts&&... __ts) const
8496 if constexpr (sizeof...(_Ts) == 0)
8497 return views::empty<tuple<>>;
8499 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8503 inline constexpr _CartesianProduct cartesian_product;
8506 #define __cpp_lib_ranges_as_rvalue 202207L
8508 template<input_range _Vp>
8510 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8512 _Vp _M_base = _Vp();
8515 as_rvalue_view() requires default_initializable<_Vp> = default;
8518 as_rvalue_view(_Vp __base)
8519 : _M_base(std::move(__base))
8523 base() const& requires copy_constructible<_Vp>
8528 { return std::move(_M_base); }
8531 begin() requires (!__detail::__simple_view<_Vp>)
8532 { return move_iterator(ranges::begin(_M_base)); }
8535 begin() const requires range<const _Vp>
8536 { return move_iterator(ranges::begin(_M_base)); }
8539 end() requires (!__detail::__simple_view<_Vp>)
8541 if constexpr (common_range<_Vp>)
8542 return move_iterator(ranges::end(_M_base));
8544 return move_sentinel(ranges::end(_M_base));
8548 end() const requires range<const _Vp>
8550 if constexpr (common_range<const _Vp>)
8551 return move_iterator(ranges::end(_M_base));
8553 return move_sentinel(ranges::end(_M_base));
8557 size() requires sized_range<_Vp>
8558 { return ranges::size(_M_base); }
8561 size() const requires sized_range<const _Vp>
8562 { return ranges::size(_M_base); }
8565 template<typename _Range>
8566 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8568 template<typename _Tp>
8569 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8570 = enable_borrowed_range<_Tp>;
8576 template<typename _Tp>
8577 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8580 struct _AsRvalue : __adaptor::_RangeAdaptorClosure
8582 template<viewable_range _Range>
8583 requires __detail::__can_as_rvalue_view<_Range>
8585 operator() [[nodiscard]] (_Range&& __r) const
8587 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8588 range_reference_t<_Range>>)
8589 return views::all(std::forward<_Range>(__r));
8591 return as_rvalue_view(std::forward<_Range>(__r));
8595 inline constexpr _AsRvalue as_rvalue;
8598 } // namespace ranges
8600 namespace views = ranges::views;
8602 _GLIBCXX_END_NAMESPACE_VERSION
8604 #endif // library concepts
8606 #endif /* _GLIBCXX_RANGES */