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
42#include <initializer_list>
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.
60namespace 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>
681 concept __can_single_view
682 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
683 } // namespace __detail
687 template<__detail::__can_single_view _Tp>
689 operator() [[nodiscard]] (_Tp&& __e) const
690 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
691 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
694 inline constexpr _Single single{};
698 template<typename... _Args>
699 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
700 } // namespace __detail
704 template<__detail::__can_iota_view _Tp>
706 operator() [[nodiscard]] (_Tp&& __e) const
707 { return iota_view(std::forward<_Tp>(__e)); }
709 template<typename _Tp, typename _Up>
710 requires __detail::__can_iota_view<_Tp, _Up>
712 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
713 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
716 inline constexpr _Iota iota{};
722 template<typename _Val, typename _CharT, typename _Traits>
723 concept __stream_extractable
724 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
725 } // namespace __detail
727 template<movable _Val, typename _CharT,
728 typename _Traits = char_traits<_CharT>>
729 requires default_initializable<_Val>
730 && __detail::__stream_extractable<_Val, _CharT, _Traits>
731 class basic_istream_view
732 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
736 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
737 : _M_stream(std::__addressof(__stream))
743 *_M_stream >> _M_object;
744 return _Iterator{this};
747 constexpr default_sentinel_t
749 { return default_sentinel; }
752 basic_istream<_CharT, _Traits>* _M_stream;
753 _Val _M_object = _Val();
758 using iterator_concept = input_iterator_tag;
759 using difference_type = ptrdiff_t;
760 using value_type = _Val;
763 _Iterator(basic_istream_view* __parent) noexcept
764 : _M_parent(__parent)
767 _Iterator(const _Iterator&) = delete;
768 _Iterator(_Iterator&&) = default;
769 _Iterator& operator=(const _Iterator&) = delete;
770 _Iterator& operator=(_Iterator&&) = default;
775 *_M_parent->_M_stream >> _M_parent->_M_object;
785 { return _M_parent->_M_object; }
788 operator==(const _Iterator& __x, default_sentinel_t)
789 { return __x._M_at_end(); }
792 basic_istream_view* _M_parent;
796 { return !*_M_parent->_M_stream; }
802 template<typename _Val>
803 using istream_view = basic_istream_view<_Val, char>;
805 template<typename _Val>
806 using wistream_view = basic_istream_view<_Val, wchar_t>;
812 template<typename _Tp, typename _Up>
813 concept __can_istream_view = requires (_Up __e) {
814 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
816 } // namespace __detail
818 template<typename _Tp>
821 template<typename _CharT, typename _Traits>
823 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
824 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
825 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
828 template<typename _Tp>
829 inline constexpr _Istream<_Tp> istream;
833 // C++20 24.7 [range.adaptors] Range adaptors
839 // Alias for a type that is conditionally present
840 // (and is an empty type otherwise).
841 // Data members using this alias should use [[no_unique_address]] so that
842 // they take no space when not needed.
843 template<bool _Present, typename _Tp>
844 using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;
846 // Alias for a type that is conditionally const.
847 template<bool _Const, typename _Tp>
848 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
850} // namespace __detail
852// Shorthand for __detail::__maybe_const_t.
853using __detail::__maybe_const_t;
855namespace views::__adaptor
857 // True if the range adaptor _Adaptor can be applied with _Args.
858 template<typename _Adaptor, typename... _Args>
859 concept __adaptor_invocable
860 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
862 // True if the range adaptor non-closure _Adaptor can be partially applied
864 template<typename _Adaptor, typename... _Args>
865 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
866 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
867 && (constructible_from<decay_t<_Args>, _Args> && ...);
869 template<typename _Adaptor, typename... _Args>
872 template<typename _Lhs, typename _Rhs>
875 // The base class of every range adaptor closure.
877 // The derived class should define the optional static data member
878 // _S_has_simple_call_op to true if the behavior of this adaptor is
879 // independent of the constness/value category of the adaptor object.
880 struct _RangeAdaptorClosure
882 // range | adaptor is equivalent to adaptor(range).
883 template<typename _Self, typename _Range>
884 requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
885 && __adaptor_invocable<_Self, _Range>
886 friend constexpr auto
887 operator|(_Range&& __r, _Self&& __self)
888 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
890 // Compose the adaptors __lhs and __rhs into a pipeline, returning
891 // another range adaptor closure object.
892 template<typename _Lhs, typename _Rhs>
893 requires derived_from<_Lhs, _RangeAdaptorClosure>
894 && derived_from<_Rhs, _RangeAdaptorClosure>
895 friend constexpr auto
896 operator|(_Lhs __lhs, _Rhs __rhs)
897 { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; }
900 // The base class of every range adaptor non-closure.
902 // The static data member _Derived::_S_arity must contain the total number of
903 // arguments that the adaptor takes, and the class _Derived must introduce
904 // _RangeAdaptor::operator() into the class scope via a using-declaration.
906 // The optional static data member _Derived::_S_has_simple_extra_args should
907 // be defined to true if the behavior of this adaptor is independent of the
908 // constness/value category of the extra arguments. This data member could
909 // also be defined as a variable template parameterized by the types of the
911 template<typename _Derived>
914 // Partially apply the arguments __args to the range adaptor _Derived,
915 // returning a range adaptor closure object.
916 template<typename... _Args>
917 requires __adaptor_partial_app_viable<_Derived, _Args...>
919 operator()(_Args&&... __args) const
921 return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
925 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
926 // one that's not overloaded according to constness or value category of the
928 template<typename _Adaptor>
929 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
931 // True if the behavior of the range adaptor non-closure _Adaptor is
932 // independent of the value category of its extra arguments _Args.
933 template<typename _Adaptor, typename... _Args>
934 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
935 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
937 // A range adaptor closure that represents partial application of
938 // the range adaptor _Adaptor with arguments _Args.
939 template<typename _Adaptor, typename... _Args>
940 struct _Partial : _RangeAdaptorClosure
942 tuple<_Args...> _M_args;
945 _Partial(_Args... __args)
946 : _M_args(std::move(__args)...)
949 // Invoke _Adaptor with arguments __r, _M_args... according to the
950 // value category of this _Partial object.
951 template<typename _Range>
952 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
954 operator()(_Range&& __r) const &
956 auto __forwarder = [&__r] (const auto&... __args) {
957 return _Adaptor{}(std::forward<_Range>(__r), __args...);
959 return std::apply(__forwarder, _M_args);
962 template<typename _Range>
963 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
965 operator()(_Range&& __r) &&
967 auto __forwarder = [&__r] (auto&... __args) {
968 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
970 return std::apply(__forwarder, _M_args);
973 template<typename _Range>
975 operator()(_Range&& __r) const && = delete;
978 // A lightweight specialization of the above primary template for
979 // the common case where _Adaptor accepts a single extra argument.
980 template<typename _Adaptor, typename _Arg>
981 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
987 : _M_arg(std::move(__arg))
990 template<typename _Range>
991 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
993 operator()(_Range&& __r) const &
994 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
996 template<typename _Range>
997 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
999 operator()(_Range&& __r) &&
1000 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
1002 template<typename _Range>
1004 operator()(_Range&& __r) const && = delete;
1007 // Partial specialization of the primary template for the case where the extra
1008 // arguments of the adaptor can always be safely and efficiently forwarded by
1009 // const reference. This lets us get away with a single operator() overload,
1010 // which makes overload resolution failure diagnostics more concise.
1011 template<typename _Adaptor, typename... _Args>
1012 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1013 && (is_trivially_copyable_v<_Args> && ...)
1014 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
1016 tuple<_Args...> _M_args;
1019 _Partial(_Args... __args)
1020 : _M_args(std::move(__args)...)
1023 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1024 // of the value category of this _Partial object.
1025 template<typename _Range>
1026 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1028 operator()(_Range&& __r) const
1030 auto __forwarder = [&__r] (const auto&... __args) {
1031 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1033 return std::apply(__forwarder, _M_args);
1036 static constexpr bool _S_has_simple_call_op = true;
1039 // A lightweight specialization of the above template for the common case
1040 // where _Adaptor accepts a single extra argument.
1041 template<typename _Adaptor, typename _Arg>
1042 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1043 && is_trivially_copyable_v<_Arg>
1044 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
1049 _Partial(_Arg __arg)
1050 : _M_arg(std::move(__arg))
1053 template<typename _Range>
1054 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1056 operator()(_Range&& __r) const
1057 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1059 static constexpr bool _S_has_simple_call_op = true;
1062 template<typename _Lhs, typename _Rhs, typename _Range>
1063 concept __pipe_invocable
1064 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1066 // A range adaptor closure that represents composition of the range
1067 // adaptor closures _Lhs and _Rhs.
1068 template<typename _Lhs, typename _Rhs>
1069 struct _Pipe : _RangeAdaptorClosure
1071 [[no_unique_address]] _Lhs _M_lhs;
1072 [[no_unique_address]] _Rhs _M_rhs;
1075 _Pipe(_Lhs __lhs, _Rhs __rhs)
1076 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1079 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1080 // range adaptor closure object.
1081 template<typename _Range>
1082 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1084 operator()(_Range&& __r) const &
1085 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1087 template<typename _Range>
1088 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1090 operator()(_Range&& __r) &&
1091 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1093 template<typename _Range>
1095 operator()(_Range&& __r) const && = delete;
1098 // A partial specialization of the above primary template for the case where
1099 // both adaptor operands have a simple operator(). This in turn lets us
1100 // implement composition using a single simple operator(), which makes
1101 // overload resolution failure diagnostics more concise.
1102 template<typename _Lhs, typename _Rhs>
1103 requires __closure_has_simple_call_op<_Lhs>
1104 && __closure_has_simple_call_op<_Rhs>
1105 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
1107 [[no_unique_address]] _Lhs _M_lhs;
1108 [[no_unique_address]] _Rhs _M_rhs;
1111 _Pipe(_Lhs __lhs, _Rhs __rhs)
1112 : _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
1115 template<typename _Range>
1116 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1118 operator()(_Range&& __r) const
1119 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1121 static constexpr bool _S_has_simple_call_op = true;
1123} // namespace views::__adaptor
1125#if __cplusplus > 202002L
1126 template<typename _Derived>
1127 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1128 class range_adaptor_closure
1129 : public views::__adaptor::_RangeAdaptorClosure
1133 template<range _Range> requires is_object_v<_Range>
1134 class ref_view : public view_interface<ref_view<_Range>>
1139 static void _S_fun(_Range&); // not defined
1140 static void _S_fun(_Range&&) = delete;
1143 template<__detail::__different_from<ref_view> _Tp>
1144 requires convertible_to<_Tp, _Range&>
1145 && requires { _S_fun(declval<_Tp>()); }
1148 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1149 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1156 constexpr iterator_t<_Range>
1158 { return ranges::begin(*_M_r); }
1160 constexpr sentinel_t<_Range>
1162 { return ranges::end(*_M_r); }
1165 empty() const requires requires { ranges::empty(*_M_r); }
1166 { return ranges::empty(*_M_r); }
1169 size() const requires sized_range<_Range>
1170 { return ranges::size(*_M_r); }
1173 data() const requires contiguous_range<_Range>
1174 { return ranges::data(*_M_r); }
1177 template<typename _Range>
1178 ref_view(_Range&) -> ref_view<_Range>;
1180 template<typename _Tp>
1181 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1183 template<range _Range>
1184 requires movable<_Range>
1185 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1186 class owning_view : public view_interface<owning_view<_Range>>
1189 _Range _M_r = _Range();
1192 owning_view() requires default_initializable<_Range> = default;
1195 owning_view(_Range&& __t)
1196 noexcept(is_nothrow_move_constructible_v<_Range>)
1197 : _M_r(std::move(__t))
1200 owning_view(owning_view&&) = default;
1201 owning_view& operator=(owning_view&&) = default;
1207 constexpr const _Range&
1208 base() const& noexcept
1213 { return std::move(_M_r); }
1215 constexpr const _Range&&
1216 base() const&& noexcept
1217 { return std::move(_M_r); }
1219 constexpr iterator_t<_Range>
1221 { return ranges::begin(_M_r); }
1223 constexpr sentinel_t<_Range>
1225 { return ranges::end(_M_r); }
1228 begin() const requires range<const _Range>
1229 { return ranges::begin(_M_r); }
1232 end() const requires range<const _Range>
1233 { return ranges::end(_M_r); }
1236 empty() requires requires { ranges::empty(_M_r); }
1237 { return ranges::empty(_M_r); }
1240 empty() const requires requires { ranges::empty(_M_r); }
1241 { return ranges::empty(_M_r); }
1244 size() requires sized_range<_Range>
1245 { return ranges::size(_M_r); }
1248 size() const requires sized_range<const _Range>
1249 { return ranges::size(_M_r); }
1252 data() requires contiguous_range<_Range>
1253 { return ranges::data(_M_r); }
1256 data() const requires contiguous_range<const _Range>
1257 { return ranges::data(_M_r); }
1260 template<typename _Tp>
1261 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1262 = enable_borrowed_range<_Tp>;
1268 template<typename _Range>
1269 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1271 template<typename _Range>
1272 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1273 } // namespace __detail
1275 struct _All : __adaptor::_RangeAdaptorClosure
1277 template<typename _Range>
1278 static constexpr bool
1281 if constexpr (view<decay_t<_Range>>)
1282 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1283 else if constexpr (__detail::__can_ref_view<_Range>)
1286 return noexcept(owning_view{std::declval<_Range>()});
1289 template<viewable_range _Range>
1290 requires view<decay_t<_Range>>
1291 || __detail::__can_ref_view<_Range>
1292 || __detail::__can_owning_view<_Range>
1294 operator() [[nodiscard]] (_Range&& __r) const
1295 noexcept(_S_noexcept<_Range>())
1297 if constexpr (view<decay_t<_Range>>)
1298 return std::forward<_Range>(__r);
1299 else if constexpr (__detail::__can_ref_view<_Range>)
1300 return ref_view{std::forward<_Range>(__r)};
1302 return owning_view{std::forward<_Range>(__r)};
1305 static constexpr bool _S_has_simple_call_op = true;
1308 inline constexpr _All all;
1310 template<viewable_range _Range>
1311 using all_t = decltype(all(std::declval<_Range>()));
1312 } // namespace views
1316 template<typename _Tp>
1317 struct __non_propagating_cache
1319 // When _Tp is not an object type (e.g. is a reference type), we make
1320 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1321 // users can easily conditionally declare data members with this type
1322 // (such as join_view::_M_inner).
1325 template<typename _Tp>
1326 requires is_object_v<_Tp>
1327 struct __non_propagating_cache<_Tp>
1328 : protected _Optional_base<_Tp>
1330 __non_propagating_cache() = default;
1333 __non_propagating_cache(const __non_propagating_cache&) noexcept
1337 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1338 { __other._M_reset(); }
1340 constexpr __non_propagating_cache&
1341 operator=(const __non_propagating_cache& __other) noexcept
1343 if (std::__addressof(__other) != this)
1348 constexpr __non_propagating_cache&
1349 operator=(__non_propagating_cache&& __other) noexcept
1356 constexpr __non_propagating_cache&
1357 operator=(_Tp __val)
1360 this->_M_payload._M_construct(std::move(__val));
1365 operator bool() const noexcept
1366 { return this->_M_is_engaged(); }
1369 operator*() noexcept
1370 { return this->_M_get(); }
1372 constexpr const _Tp&
1373 operator*() const noexcept
1374 { return this->_M_get(); }
1376 template<typename _Iter>
1378 _M_emplace_deref(const _Iter& __i)
1381 auto __f = [] (auto& __x) { return *__x; };
1382 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1383 return this->_M_get();
1387 template<range _Range>
1388 struct _CachedPosition
1391 _M_has_value() const
1394 constexpr iterator_t<_Range>
1395 _M_get(const _Range&) const
1397 __glibcxx_assert(false);
1398 __builtin_unreachable();
1402 _M_set(const _Range&, const iterator_t<_Range>&) const
1406 template<forward_range _Range>
1407 struct _CachedPosition<_Range>
1408 : protected __non_propagating_cache<iterator_t<_Range>>
1411 _M_has_value() const
1412 { return this->_M_is_engaged(); }
1414 constexpr iterator_t<_Range>
1415 _M_get(const _Range&) const
1417 __glibcxx_assert(_M_has_value());
1422 _M_set(const _Range&, const iterator_t<_Range>& __it)
1424 __glibcxx_assert(!_M_has_value());
1425 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1427 this->_M_payload._M_engaged = true;
1431 template<random_access_range _Range>
1432 requires (sizeof(range_difference_t<_Range>)
1433 <= sizeof(iterator_t<_Range>))
1434 struct _CachedPosition<_Range>
1437 range_difference_t<_Range> _M_offset = -1;
1440 _CachedPosition() = default;
1443 _CachedPosition(const _CachedPosition&) = default;
1446 _CachedPosition(_CachedPosition&& __other) noexcept
1447 { *this = std::move(__other); }
1449 constexpr _CachedPosition&
1450 operator=(const _CachedPosition&) = default;
1452 constexpr _CachedPosition&
1453 operator=(_CachedPosition&& __other) noexcept
1455 // Propagate the cached offset, but invalidate the source.
1456 _M_offset = __other._M_offset;
1457 __other._M_offset = -1;
1462 _M_has_value() const
1463 { return _M_offset >= 0; }
1465 constexpr iterator_t<_Range>
1466 _M_get(_Range& __r) const
1468 __glibcxx_assert(_M_has_value());
1469 return ranges::begin(__r) + _M_offset;
1473 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1475 __glibcxx_assert(!_M_has_value());
1476 _M_offset = __it - ranges::begin(__r);
1479 } // namespace __detail
1483 template<typename _Base>
1484 struct __filter_view_iter_cat
1487 template<forward_range _Base>
1488 struct __filter_view_iter_cat<_Base>
1494 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1495 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1496 return bidirectional_iterator_tag{};
1497 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1498 return forward_iterator_tag{};
1503 using iterator_category = decltype(_S_iter_cat());
1505 } // namespace __detail
1507 template<input_range _Vp,
1508 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1509 requires view<_Vp> && is_object_v<_Pred>
1510 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1515 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1518 static constexpr auto
1521 if constexpr (bidirectional_range<_Vp>)
1522 return bidirectional_iterator_tag{};
1523 else if constexpr (forward_range<_Vp>)
1524 return forward_iterator_tag{};
1526 return input_iterator_tag{};
1531 using _Vp_iter = iterator_t<_Vp>;
1533 _Vp_iter _M_current = _Vp_iter();
1534 filter_view* _M_parent = nullptr;
1537 using iterator_concept = decltype(_S_iter_concept());
1538 // iterator_category defined in __filter_view_iter_cat
1539 using value_type = range_value_t<_Vp>;
1540 using difference_type = range_difference_t<_Vp>;
1542 _Iterator() requires default_initializable<_Vp_iter> = default;
1545 _Iterator(filter_view* __parent, _Vp_iter __current)
1546 : _M_current(std::move(__current)),
1550 constexpr const _Vp_iter&
1551 base() const & noexcept
1552 { return _M_current; }
1556 { return std::move(_M_current); }
1558 constexpr range_reference_t<_Vp>
1560 { return *_M_current; }
1564 requires __detail::__has_arrow<_Vp_iter>
1565 && copyable<_Vp_iter>
1566 { return _M_current; }
1568 constexpr _Iterator&
1571 _M_current = ranges::find_if(std::move(++_M_current),
1572 ranges::end(_M_parent->_M_base),
1573 std::ref(*_M_parent->_M_pred));
1582 operator++(int) requires forward_range<_Vp>
1589 constexpr _Iterator&
1590 operator--() requires bidirectional_range<_Vp>
1594 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1599 operator--(int) requires bidirectional_range<_Vp>
1606 friend constexpr bool
1607 operator==(const _Iterator& __x, const _Iterator& __y)
1608 requires equality_comparable<_Vp_iter>
1609 { return __x._M_current == __y._M_current; }
1611 friend constexpr range_rvalue_reference_t<_Vp>
1612 iter_move(const _Iterator& __i)
1613 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1614 { return ranges::iter_move(__i._M_current); }
1616 friend constexpr void
1617 iter_swap(const _Iterator& __x, const _Iterator& __y)
1618 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1619 requires indirectly_swappable<_Vp_iter>
1620 { ranges::iter_swap(__x._M_current, __y._M_current); }
1626 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1629 __equal(const _Iterator& __i) const
1630 { return __i._M_current == _M_end; }
1633 _Sentinel() = default;
1636 _Sentinel(filter_view* __parent)
1637 : _M_end(ranges::end(__parent->_M_base))
1640 constexpr sentinel_t<_Vp>
1644 friend constexpr bool
1645 operator==(const _Iterator& __x, const _Sentinel& __y)
1646 { return __y.__equal(__x); }
1649 _Vp _M_base = _Vp();
1650 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1651 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1654 filter_view() requires (default_initializable<_Vp>
1655 && default_initializable<_Pred>)
1659 filter_view(_Vp __base, _Pred __pred)
1660 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1664 base() const& requires copy_constructible<_Vp>
1669 { return std::move(_M_base); }
1671 constexpr const _Pred&
1673 { return *_M_pred; }
1678 if (_M_cached_begin._M_has_value())
1679 return {this, _M_cached_begin._M_get(_M_base)};
1681 __glibcxx_assert(_M_pred.has_value());
1682 auto __it = ranges::find_if(ranges::begin(_M_base),
1683 ranges::end(_M_base),
1684 std::ref(*_M_pred));
1685 _M_cached_begin._M_set(_M_base, __it);
1686 return {this, std::move(__it)};
1692 if constexpr (common_range<_Vp>)
1693 return _Iterator{this, ranges::end(_M_base)};
1695 return _Sentinel{this};
1699 template<typename _Range, typename _Pred>
1700 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1706 template<typename _Range, typename _Pred>
1707 concept __can_filter_view
1708 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1709 } // namespace __detail
1711 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1713 template<viewable_range _Range, typename _Pred>
1714 requires __detail::__can_filter_view<_Range, _Pred>
1716 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1718 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1721 using _RangeAdaptor<_Filter>::operator();
1722 static constexpr int _S_arity = 2;
1723 static constexpr bool _S_has_simple_extra_args = true;
1726 inline constexpr _Filter filter;
1727 } // namespace views
1729 template<input_range _Vp, copy_constructible _Fp>
1730 requires view<_Vp> && is_object_v<_Fp>
1731 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1732 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1733 range_reference_t<_Vp>>>
1734 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1737 template<bool _Const>
1738 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1740 template<bool _Const>
1744 template<bool _Const>
1745 requires forward_range<_Base<_Const>>
1746 struct __iter_cat<_Const>
1752 using _Base = transform_view::_Base<_Const>;
1753 using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
1754 if constexpr (is_lvalue_reference_v<_Res>)
1757 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1758 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1759 return random_access_iterator_tag{};
1764 return input_iterator_tag{};
1767 using iterator_category = decltype(_S_iter_cat());
1770 template<bool _Const>
1773 template<bool _Const>
1774 struct _Iterator : __iter_cat<_Const>
1777 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1778 using _Base = transform_view::_Base<_Const>;
1783 if constexpr (random_access_range<_Base>)
1784 return random_access_iterator_tag{};
1785 else if constexpr (bidirectional_range<_Base>)
1786 return bidirectional_iterator_tag{};
1787 else if constexpr (forward_range<_Base>)
1788 return forward_iterator_tag{};
1790 return input_iterator_tag{};
1793 using _Base_iter = iterator_t<_Base>;
1795 _Base_iter _M_current = _Base_iter();
1796 _Parent* _M_parent = nullptr;
1799 using iterator_concept = decltype(_S_iter_concept());
1800 // iterator_category defined in __transform_view_iter_cat
1802 = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
1803 using difference_type = range_difference_t<_Base>;
1805 _Iterator() requires default_initializable<_Base_iter> = default;
1808 _Iterator(_Parent* __parent, _Base_iter __current)
1809 : _M_current(std::move(__current)),
1814 _Iterator(_Iterator<!_Const> __i)
1816 && convertible_to<iterator_t<_Vp>, _Base_iter>
1817 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1820 constexpr const _Base_iter&
1821 base() const & noexcept
1822 { return _M_current; }
1824 constexpr _Base_iter
1826 { return std::move(_M_current); }
1828 constexpr decltype(auto)
1830 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1831 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1833 constexpr _Iterator&
1845 operator++(int) requires forward_range<_Base>
1852 constexpr _Iterator&
1853 operator--() requires bidirectional_range<_Base>
1860 operator--(int) requires bidirectional_range<_Base>
1867 constexpr _Iterator&
1868 operator+=(difference_type __n) requires random_access_range<_Base>
1874 constexpr _Iterator&
1875 operator-=(difference_type __n) requires random_access_range<_Base>
1881 constexpr decltype(auto)
1882 operator[](difference_type __n) const
1883 requires random_access_range<_Base>
1884 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1886 friend constexpr bool
1887 operator==(const _Iterator& __x, const _Iterator& __y)
1888 requires equality_comparable<_Base_iter>
1889 { return __x._M_current == __y._M_current; }
1891 friend constexpr bool
1892 operator<(const _Iterator& __x, const _Iterator& __y)
1893 requires random_access_range<_Base>
1894 { return __x._M_current < __y._M_current; }
1896 friend constexpr bool
1897 operator>(const _Iterator& __x, const _Iterator& __y)
1898 requires random_access_range<_Base>
1899 { return __y < __x; }
1901 friend constexpr bool
1902 operator<=(const _Iterator& __x, const _Iterator& __y)
1903 requires random_access_range<_Base>
1904 { return !(__y < __x); }
1906 friend constexpr bool
1907 operator>=(const _Iterator& __x, const _Iterator& __y)
1908 requires random_access_range<_Base>
1909 { return !(__x < __y); }
1911#ifdef __cpp_lib_three_way_comparison
1912 friend constexpr auto
1913 operator<=>(const _Iterator& __x, const _Iterator& __y)
1914 requires random_access_range<_Base>
1915 && three_way_comparable<_Base_iter>
1916 { return __x._M_current <=> __y._M_current; }
1919 friend constexpr _Iterator
1920 operator+(_Iterator __i, difference_type __n)
1921 requires random_access_range<_Base>
1922 { return {__i._M_parent, __i._M_current + __n}; }
1924 friend constexpr _Iterator
1925 operator+(difference_type __n, _Iterator __i)
1926 requires random_access_range<_Base>
1927 { return {__i._M_parent, __i._M_current + __n}; }
1929 friend constexpr _Iterator
1930 operator-(_Iterator __i, difference_type __n)
1931 requires random_access_range<_Base>
1932 { return {__i._M_parent, __i._M_current - __n}; }
1934 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1935 // 3483. transform_view::iterator's difference is overconstrained
1936 friend constexpr difference_type
1937 operator-(const _Iterator& __x, const _Iterator& __y)
1938 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1939 { return __x._M_current - __y._M_current; }
1941 friend constexpr decltype(auto)
1942 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1944 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1945 return std::move(*__i);
1950 friend _Iterator<!_Const>;
1951 template<bool> friend struct _Sentinel;
1954 template<bool _Const>
1958 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1959 using _Base = transform_view::_Base<_Const>;
1961 template<bool _Const2>
1963 __distance_from(const _Iterator<_Const2>& __i) const
1964 { return _M_end - __i._M_current; }
1966 template<bool _Const2>
1968 __equal(const _Iterator<_Const2>& __i) const
1969 { return __i._M_current == _M_end; }
1971 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1974 _Sentinel() = default;
1977 _Sentinel(sentinel_t<_Base> __end)
1982 _Sentinel(_Sentinel<!_Const> __i)
1984 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1985 : _M_end(std::move(__i._M_end))
1988 constexpr sentinel_t<_Base>
1992 template<bool _Const2>
1993 requires sentinel_for<sentinel_t<_Base>,
1994 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
1995 friend constexpr bool
1996 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
1997 { return __y.__equal(__x); }
1999 template<bool _Const2,
2000 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2001 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2002 friend constexpr range_difference_t<_Base2>
2003 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2004 { return -__y.__distance_from(__x); }
2006 template<bool _Const2,
2007 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2008 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2009 friend constexpr range_difference_t<_Base2>
2010 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2011 { return __y.__distance_from(__x); }
2013 friend _Sentinel<!_Const>;
2016 _Vp _M_base = _Vp();
2017 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2020 transform_view() requires (default_initializable<_Vp>
2021 && default_initializable<_Fp>)
2025 transform_view(_Vp __base, _Fp __fun)
2026 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2030 base() const& requires copy_constructible<_Vp>
2031 { return _M_base ; }
2035 { return std::move(_M_base); }
2037 constexpr _Iterator<false>
2039 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2041 constexpr _Iterator<true>
2043 requires range<const _Vp>
2044 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2045 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2047 constexpr _Sentinel<false>
2049 { return _Sentinel<false>{ranges::end(_M_base)}; }
2051 constexpr _Iterator<false>
2052 end() requires common_range<_Vp>
2053 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2055 constexpr _Sentinel<true>
2057 requires range<const _Vp>
2058 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2059 { return _Sentinel<true>{ranges::end(_M_base)}; }
2061 constexpr _Iterator<true>
2063 requires common_range<const _Vp>
2064 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2065 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2068 size() requires sized_range<_Vp>
2069 { return ranges::size(_M_base); }
2072 size() const requires sized_range<const _Vp>
2073 { return ranges::size(_M_base); }
2076 template<typename _Range, typename _Fp>
2077 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2083 template<typename _Range, typename _Fp>
2084 concept __can_transform_view
2085 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2086 } // namespace __detail
2088 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2090 template<viewable_range _Range, typename _Fp>
2091 requires __detail::__can_transform_view<_Range, _Fp>
2093 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2095 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2098 using _RangeAdaptor<_Transform>::operator();
2099 static constexpr int _S_arity = 2;
2100 static constexpr bool _S_has_simple_extra_args = true;
2103 inline constexpr _Transform transform;
2104 } // namespace views
2107 class take_view : public view_interface<take_view<_Vp>>
2110 template<bool _Const>
2111 using _CI = counted_iterator<
2112 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2114 template<bool _Const>
2118 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2119 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2122 _Sentinel() = default;
2125 _Sentinel(sentinel_t<_Base> __end)
2130 _Sentinel(_Sentinel<!_Const> __s)
2131 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2132 : _M_end(std::move(__s._M_end))
2135 constexpr sentinel_t<_Base>
2139 friend constexpr bool
2140 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2141 { return __y.count() == 0 || __y.base() == __x._M_end; }
2143 template<bool _OtherConst = !_Const,
2144 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2145 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2146 friend constexpr bool
2147 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2148 { return __y.count() == 0 || __y.base() == __x._M_end; }
2150 friend _Sentinel<!_Const>;
2153 _Vp _M_base = _Vp();
2154 range_difference_t<_Vp> _M_count = 0;
2157 take_view() requires default_initializable<_Vp> = default;
2160 take_view(_Vp __base, range_difference_t<_Vp> __count)
2161 : _M_base(std::move(__base)), _M_count(std::move(__count))
2165 base() const& requires copy_constructible<_Vp>
2170 { return std::move(_M_base); }
2173 begin() requires (!__detail::__simple_view<_Vp>)
2175 if constexpr (sized_range<_Vp>)
2177 if constexpr (random_access_range<_Vp>)
2178 return ranges::begin(_M_base);
2182 return counted_iterator(ranges::begin(_M_base), __sz);
2186 return counted_iterator(ranges::begin(_M_base), _M_count);
2190 begin() const requires range<const _Vp>
2192 if constexpr (sized_range<const _Vp>)
2194 if constexpr (random_access_range<const _Vp>)
2195 return ranges::begin(_M_base);
2199 return counted_iterator(ranges::begin(_M_base), __sz);
2203 return counted_iterator(ranges::begin(_M_base), _M_count);
2207 end() requires (!__detail::__simple_view<_Vp>)
2209 if constexpr (sized_range<_Vp>)
2211 if constexpr (random_access_range<_Vp>)
2212 return ranges::begin(_M_base) + size();
2214 return default_sentinel;
2217 return _Sentinel<false>{ranges::end(_M_base)};
2221 end() const requires range<const _Vp>
2223 if constexpr (sized_range<const _Vp>)
2225 if constexpr (random_access_range<const _Vp>)
2226 return ranges::begin(_M_base) + size();
2228 return default_sentinel;
2231 return _Sentinel<true>{ranges::end(_M_base)};
2235 size() requires sized_range<_Vp>
2237 auto __n = ranges::size(_M_base);
2238 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2242 size() const requires sized_range<const _Vp>
2244 auto __n = ranges::size(_M_base);
2245 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2249 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2250 // 3447. Deduction guides for take_view and drop_view have different
2252 template<typename _Range>
2253 take_view(_Range&&, range_difference_t<_Range>)
2254 -> take_view<views::all_t<_Range>>;
2256 template<typename _Tp>
2257 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2258 = enable_borrowed_range<_Tp>;
2264 template<typename _Range>
2265 inline constexpr bool __is_empty_view = false;
2267 template<typename _Tp>
2268 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2270 template<typename _Range>
2271 inline constexpr bool __is_basic_string_view = false;
2273 template<typename _CharT, typename _Traits>
2274 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2277 template<typename _Range>
2278 inline constexpr bool __is_subrange = false;
2280 template<typename _Iter, typename _Sent, subrange_kind _Kind>
2281 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
2283 template<typename _Range>
2284 inline constexpr bool __is_iota_view = false;
2286 template<typename _Winc, typename _Bound>
2287 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2289 template<typename _Range>
2290 inline constexpr bool __is_repeat_view = false;
2292 template<typename _Range>
2294 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2296 template<typename _Range, typename _Dp>
2297 concept __can_take_view
2298 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2299 } // namespace __detail
2301 struct _Take : __adaptor::_RangeAdaptor<_Take>
2303 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2304 requires __detail::__can_take_view<_Range, _Dp>
2306 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2308 using _Tp = remove_cvref_t<_Range>;
2309 if constexpr (__detail::__is_empty_view<_Tp>)
2311 else if constexpr (random_access_range<_Tp>
2313 && (std::__detail::__is_span<_Tp>
2314 || __detail::__is_basic_string_view<_Tp>
2315 || __detail::__is_subrange<_Tp>
2316 || __detail::__is_iota_view<_Tp>))
2318 __n = std::min<_Dp>(ranges::distance(__r), __n);
2319 auto __begin = ranges::begin(__r);
2320 auto __end = __begin + __n;
2321 if constexpr (std::__detail::__is_span<_Tp>)
2322 return span<typename _Tp::element_type>(__begin, __end);
2323 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2324 return _Tp(__begin, __end);
2325 else if constexpr (__detail::__is_subrange<_Tp>)
2326 return subrange<iterator_t<_Tp>>(__begin, __end);
2328 return iota_view(*__begin, *__end);
2330 else if constexpr (__detail::__is_repeat_view<_Tp>)
2331 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2333 return take_view(std::forward<_Range>(__r), __n);
2336 using _RangeAdaptor<_Take>::operator();
2337 static constexpr int _S_arity = 2;
2338 // The count argument of views::take is not always simple -- it can be
2339 // e.g. a move-only class that's implicitly convertible to the difference
2340 // type. But an integer-like count argument is surely simple.
2341 template<typename _Tp>
2342 static constexpr bool _S_has_simple_extra_args
2343 = ranges::__detail::__is_integer_like<_Tp>;
2346 inline constexpr _Take take;
2347 } // namespace views
2349 template<view _Vp, typename _Pred>
2350 requires input_range<_Vp> && is_object_v<_Pred>
2351 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2352 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2354 template<bool _Const>
2358 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2360 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2361 const _Pred* _M_pred = nullptr;
2364 _Sentinel() = default;
2367 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2368 : _M_end(__end), _M_pred(__pred)
2372 _Sentinel(_Sentinel<!_Const> __s)
2373 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2374 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2377 constexpr sentinel_t<_Base>
2378 base() const { return _M_end; }
2380 friend constexpr bool
2381 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2382 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2384 template<bool _OtherConst = !_Const,
2385 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2386 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2387 friend constexpr bool
2388 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2389 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2391 friend _Sentinel<!_Const>;
2394 _Vp _M_base = _Vp();
2395 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2398 take_while_view() requires (default_initializable<_Vp>
2399 && default_initializable<_Pred>)
2403 take_while_view(_Vp __base, _Pred __pred)
2404 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2408 base() const& requires copy_constructible<_Vp>
2413 { return std::move(_M_base); }
2415 constexpr const _Pred&
2417 { return *_M_pred; }
2420 begin() requires (!__detail::__simple_view<_Vp>)
2421 { return ranges::begin(_M_base); }
2424 begin() const requires range<const _Vp>
2425 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2426 { return ranges::begin(_M_base); }
2429 end() requires (!__detail::__simple_view<_Vp>)
2430 { return _Sentinel<false>(ranges::end(_M_base),
2431 std::__addressof(*_M_pred)); }
2434 end() const requires range<const _Vp>
2435 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2436 { return _Sentinel<true>(ranges::end(_M_base),
2437 std::__addressof(*_M_pred)); }
2440 template<typename _Range, typename _Pred>
2441 take_while_view(_Range&&, _Pred)
2442 -> take_while_view<views::all_t<_Range>, _Pred>;
2448 template<typename _Range, typename _Pred>
2449 concept __can_take_while_view
2450 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2451 } // namespace __detail
2453 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2455 template<viewable_range _Range, typename _Pred>
2456 requires __detail::__can_take_while_view<_Range, _Pred>
2458 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2460 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2463 using _RangeAdaptor<_TakeWhile>::operator();
2464 static constexpr int _S_arity = 2;
2465 static constexpr bool _S_has_simple_extra_args = true;
2468 inline constexpr _TakeWhile take_while;
2469 } // namespace views
2472 class drop_view : public view_interface<drop_view<_Vp>>
2475 _Vp _M_base = _Vp();
2476 range_difference_t<_Vp> _M_count = 0;
2478 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2479 // both random_access_range and sized_range. Otherwise, cache its result.
2480 static constexpr bool _S_needs_cached_begin
2481 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2482 [[no_unique_address]]
2483 __detail::__maybe_present_t<_S_needs_cached_begin,
2484 __detail::_CachedPosition<_Vp>>
2488 drop_view() requires default_initializable<_Vp> = default;
2491 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2492 : _M_base(std::move(__base)), _M_count(__count)
2493 { __glibcxx_assert(__count >= 0); }
2496 base() const& requires copy_constructible<_Vp>
2501 { return std::move(_M_base); }
2503 // This overload is disabled for simple views with constant-time begin().
2506 requires (!(__detail::__simple_view<_Vp>
2507 && random_access_range<const _Vp>
2508 && sized_range<const _Vp>))
2510 if constexpr (_S_needs_cached_begin)
2511 if (_M_cached_begin._M_has_value())
2512 return _M_cached_begin._M_get(_M_base);
2514 auto __it = ranges::next(ranges::begin(_M_base),
2515 _M_count, ranges::end(_M_base));
2516 if constexpr (_S_needs_cached_begin)
2517 _M_cached_begin._M_set(_M_base, __it);
2521 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2522 // 3482. drop_view's const begin should additionally require sized_range
2525 requires random_access_range<const _Vp> && sized_range<const _Vp>
2527 return ranges::next(ranges::begin(_M_base), _M_count,
2528 ranges::end(_M_base));
2532 end() requires (!__detail::__simple_view<_Vp>)
2533 { return ranges::end(_M_base); }
2536 end() const requires range<const _Vp>
2537 { return ranges::end(_M_base); }
2540 size() requires sized_range<_Vp>
2542 const auto __s = ranges::size(_M_base);
2543 const auto __c = static_cast<decltype(__s)>(_M_count);
2544 return __s < __c ? 0 : __s - __c;
2548 size() const requires sized_range<const _Vp>
2550 const auto __s = ranges::size(_M_base);
2551 const auto __c = static_cast<decltype(__s)>(_M_count);
2552 return __s < __c ? 0 : __s - __c;
2556 template<typename _Range>
2557 drop_view(_Range&&, range_difference_t<_Range>)
2558 -> drop_view<views::all_t<_Range>>;
2560 template<typename _Tp>
2561 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2562 = enable_borrowed_range<_Tp>;
2568 template<typename _Range>
2570 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2572 template<typename _Range, typename _Dp>
2573 concept __can_drop_view
2574 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2575 } // namespace __detail
2577 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2579 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2580 requires __detail::__can_drop_view<_Range, _Dp>
2582 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2584 using _Tp = remove_cvref_t<_Range>;
2585 if constexpr (__detail::__is_empty_view<_Tp>)
2587 else if constexpr (random_access_range<_Tp>
2589 && (std::__detail::__is_span<_Tp>
2590 || __detail::__is_basic_string_view<_Tp>
2591 || __detail::__is_iota_view<_Tp>
2592 || __detail::__is_subrange<_Tp>))
2594 __n = std::min<_Dp>(ranges::distance(__r), __n);
2595 auto __begin = ranges::begin(__r) + __n;
2596 auto __end = ranges::end(__r);
2597 if constexpr (std::__detail::__is_span<_Tp>)
2598 return span<typename _Tp::element_type>(__begin, __end);
2599 else if constexpr (__detail::__is_subrange<_Tp>)
2601 if constexpr (_Tp::_S_store_size)
2603 using ranges::__detail::__to_unsigned_like;
2604 auto __m = ranges::distance(__r) - __n;
2605 return _Tp(__begin, __end, __to_unsigned_like(__m));
2608 return _Tp(__begin, __end);
2611 return _Tp(__begin, __end);
2613 else if constexpr (__detail::__is_repeat_view<_Tp>)
2614 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2616 return drop_view(std::forward<_Range>(__r), __n);
2619 using _RangeAdaptor<_Drop>::operator();
2620 static constexpr int _S_arity = 2;
2621 template<typename _Tp>
2622 static constexpr bool _S_has_simple_extra_args
2623 = _Take::_S_has_simple_extra_args<_Tp>;
2626 inline constexpr _Drop drop;
2627 } // namespace views
2629 template<view _Vp, typename _Pred>
2630 requires input_range<_Vp> && is_object_v<_Pred>
2631 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2632 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2635 _Vp _M_base = _Vp();
2636 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2637 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2640 drop_while_view() requires (default_initializable<_Vp>
2641 && default_initializable<_Pred>)
2645 drop_while_view(_Vp __base, _Pred __pred)
2646 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2650 base() const& requires copy_constructible<_Vp>
2655 { return std::move(_M_base); }
2657 constexpr const _Pred&
2659 { return *_M_pred; }
2664 if (_M_cached_begin._M_has_value())
2665 return _M_cached_begin._M_get(_M_base);
2667 __glibcxx_assert(_M_pred.has_value());
2668 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2669 ranges::end(_M_base),
2670 std::cref(*_M_pred));
2671 _M_cached_begin._M_set(_M_base, __it);
2677 { return ranges::end(_M_base); }
2680 template<typename _Range, typename _Pred>
2681 drop_while_view(_Range&&, _Pred)
2682 -> drop_while_view<views::all_t<_Range>, _Pred>;
2684 template<typename _Tp, typename _Pred>
2685 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2686 = enable_borrowed_range<_Tp>;
2692 template<typename _Range, typename _Pred>
2693 concept __can_drop_while_view
2694 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2695 } // namespace __detail
2697 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2699 template<viewable_range _Range, typename _Pred>
2700 requires __detail::__can_drop_while_view<_Range, _Pred>
2702 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2704 return drop_while_view(std::forward<_Range>(__r),
2705 std::forward<_Pred>(__p));
2708 using _RangeAdaptor<_DropWhile>::operator();
2709 static constexpr int _S_arity = 2;
2710 static constexpr bool _S_has_simple_extra_args = true;
2713 inline constexpr _DropWhile drop_while;
2714 } // namespace views
2716 template<input_range _Vp>
2717 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2718 class join_view : public view_interface<join_view<_Vp>>
2721 using _InnerRange = range_reference_t<_Vp>;
2723 template<bool _Const>
2724 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2726 template<bool _Const>
2727 using _Outer_iter = iterator_t<_Base<_Const>>;
2729 template<bool _Const>
2730 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2732 template<bool _Const>
2733 static constexpr bool _S_ref_is_glvalue
2734 = is_reference_v<range_reference_t<_Base<_Const>>>;
2736 template<bool _Const>
2740 template<bool _Const>
2741 requires _S_ref_is_glvalue<_Const>
2742 && forward_range<_Base<_Const>>
2743 && forward_range<range_reference_t<_Base<_Const>>>
2744 struct __iter_cat<_Const>
2747 static constexpr auto
2750 using _Outer_iter = join_view::_Outer_iter<_Const>;
2751 using _Inner_iter = join_view::_Inner_iter<_Const>;
2752 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2753 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2754 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2755 && derived_from<_InnerCat, bidirectional_iterator_tag>
2756 && common_range<range_reference_t<_Base<_Const>>>)
2757 return bidirectional_iterator_tag{};
2758 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2759 && derived_from<_InnerCat, forward_iterator_tag>)
2760 return forward_iterator_tag{};
2762 return input_iterator_tag{};
2765 using iterator_category = decltype(_S_iter_cat());
2768 template<bool _Const>
2771 template<bool _Const>
2772 struct _Iterator : __iter_cat<_Const>
2775 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2776 using _Base = join_view::_Base<_Const>;
2778 static constexpr bool _S_ref_is_glvalue
2779 = join_view::_S_ref_is_glvalue<_Const>;
2784 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2785 if constexpr (_S_ref_is_glvalue)
2788 return _M_parent->_M_inner._M_emplace_deref(__x);
2791 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2793 auto&& __inner = __update_inner(_M_outer);
2794 _M_inner = ranges::begin(__inner);
2795 if (_M_inner != ranges::end(__inner))
2799 if constexpr (_S_ref_is_glvalue)
2803 static constexpr auto
2806 if constexpr (_S_ref_is_glvalue
2807 && bidirectional_range<_Base>
2808 && bidirectional_range<range_reference_t<_Base>>
2809 && common_range<range_reference_t<_Base>>)
2810 return bidirectional_iterator_tag{};
2811 else if constexpr (_S_ref_is_glvalue
2812 && forward_range<_Base>
2813 && forward_range<range_reference_t<_Base>>)
2814 return forward_iterator_tag{};
2816 return input_iterator_tag{};
2819 using _Outer_iter = join_view::_Outer_iter<_Const>;
2820 using _Inner_iter = join_view::_Inner_iter<_Const>;
2822 _Outer_iter _M_outer = _Outer_iter();
2823 optional<_Inner_iter> _M_inner;
2824 _Parent* _M_parent = nullptr;
2827 using iterator_concept = decltype(_S_iter_concept());
2828 // iterator_category defined in __join_view_iter_cat
2829 using value_type = range_value_t<range_reference_t<_Base>>;
2830 using difference_type
2831 = common_type_t<range_difference_t<_Base>,
2832 range_difference_t<range_reference_t<_Base>>>;
2834 _Iterator() requires default_initializable<_Outer_iter> = default;
2837 _Iterator(_Parent* __parent, _Outer_iter __outer)
2838 : _M_outer(std::move(__outer)),
2843 _Iterator(_Iterator<!_Const> __i)
2845 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2846 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2847 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2848 _M_parent(__i._M_parent)
2851 constexpr decltype(auto)
2853 { return **_M_inner; }
2855 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2856 // 3500. join_view::iterator::operator->() is bogus
2857 constexpr _Inner_iter
2859 requires __detail::__has_arrow<_Inner_iter>
2860 && copyable<_Inner_iter>
2861 { return *_M_inner; }
2863 constexpr _Iterator&
2866 auto&& __inner_range = [this] () -> auto&& {
2867 if constexpr (_S_ref_is_glvalue)
2870 return *_M_parent->_M_inner;
2872 if (++*_M_inner == ranges::end(__inner_range))
2886 requires _S_ref_is_glvalue && forward_range<_Base>
2887 && forward_range<range_reference_t<_Base>>
2894 constexpr _Iterator&
2896 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2897 && bidirectional_range<range_reference_t<_Base>>
2898 && common_range<range_reference_t<_Base>>
2900 if (_M_outer == ranges::end(_M_parent->_M_base))
2901 _M_inner = ranges::end(*--_M_outer);
2902 while (*_M_inner == ranges::begin(*_M_outer))
2903 *_M_inner = ranges::end(*--_M_outer);
2910 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2911 && bidirectional_range<range_reference_t<_Base>>
2912 && common_range<range_reference_t<_Base>>
2919 friend constexpr bool
2920 operator==(const _Iterator& __x, const _Iterator& __y)
2921 requires _S_ref_is_glvalue
2922 && equality_comparable<_Outer_iter>
2923 && equality_comparable<_Inner_iter>
2925 return (__x._M_outer == __y._M_outer
2926 && __x._M_inner == __y._M_inner);
2929 friend constexpr decltype(auto)
2930 iter_move(const _Iterator& __i)
2931 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
2932 { return ranges::iter_move(*__i._M_inner); }
2934 friend constexpr void
2935 iter_swap(const _Iterator& __x, const _Iterator& __y)
2936 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
2937 requires indirectly_swappable<_Inner_iter>
2938 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
2940 friend _Iterator<!_Const>;
2941 template<bool> friend struct _Sentinel;
2944 template<bool _Const>
2948 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2949 using _Base = join_view::_Base<_Const>;
2951 template<bool _Const2>
2953 __equal(const _Iterator<_Const2>& __i) const
2954 { return __i._M_outer == _M_end; }
2956 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2959 _Sentinel() = default;
2962 _Sentinel(_Parent* __parent)
2963 : _M_end(ranges::end(__parent->_M_base))
2967 _Sentinel(_Sentinel<!_Const> __s)
2968 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2969 : _M_end(std::move(__s._M_end))
2972 template<bool _Const2>
2973 requires sentinel_for<sentinel_t<_Base>,
2974 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2975 friend constexpr bool
2976 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2977 { return __y.__equal(__x); }
2979 friend _Sentinel<!_Const>;
2982 _Vp _M_base = _Vp();
2983 [[no_unique_address]]
2984 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2987 join_view() requires default_initializable<_Vp> = default;
2990 join_view(_Vp __base)
2991 : _M_base(std::move(__base))
2995 base() const& requires copy_constructible<_Vp>
3000 { return std::move(_M_base); }
3005 constexpr bool __use_const
3006 = (__detail::__simple_view<_Vp>
3007 && is_reference_v<range_reference_t<_Vp>>);
3008 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3013 requires input_range<const _Vp>
3014 && is_reference_v<range_reference_t<const _Vp>>
3016 return _Iterator<true>{this, ranges::begin(_M_base)};
3022 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3023 && forward_range<_InnerRange>
3024 && common_range<_Vp> && common_range<_InnerRange>)
3025 return _Iterator<__detail::__simple_view<_Vp>>{this,
3026 ranges::end(_M_base)};
3028 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3033 requires input_range<const _Vp>
3034 && is_reference_v<range_reference_t<const _Vp>>
3036 if constexpr (forward_range<const _Vp>
3037 && is_reference_v<range_reference_t<const _Vp>>
3038 && forward_range<range_reference_t<const _Vp>>
3039 && common_range<const _Vp>
3040 && common_range<range_reference_t<const _Vp>>)
3041 return _Iterator<true>{this, ranges::end(_M_base)};
3043 return _Sentinel<true>{this};
3047 template<typename _Range>
3048 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3054 template<typename _Range>
3055 concept __can_join_view
3056 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3057 } // namespace __detail
3059 struct _Join : __adaptor::_RangeAdaptorClosure
3061 template<viewable_range _Range>
3062 requires __detail::__can_join_view<_Range>
3064 operator() [[nodiscard]] (_Range&& __r) const
3066 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3067 // 3474. Nesting join_views is broken because of CTAD
3068 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3071 static constexpr bool _S_has_simple_call_op = true;
3074 inline constexpr _Join join;
3075 } // namespace views
3080 struct __require_constant;
3082 template<typename _Range>
3083 concept __tiny_range = sized_range<_Range>
3085 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3086 && (remove_reference_t<_Range>::size() <= 1);
3088 template<typename _Base>
3089 struct __lazy_split_view_outer_iter_cat
3092 template<forward_range _Base>
3093 struct __lazy_split_view_outer_iter_cat<_Base>
3094 { using iterator_category = input_iterator_tag; };
3096 template<typename _Base>
3097 struct __lazy_split_view_inner_iter_cat
3100 template<forward_range _Base>
3101 struct __lazy_split_view_inner_iter_cat<_Base>
3104 static constexpr auto
3107 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3108 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3109 return forward_iterator_tag{};
3114 using iterator_category = decltype(_S_iter_cat());
3118 template<input_range _Vp, forward_range _Pattern>
3119 requires view<_Vp> && view<_Pattern>
3120 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3122 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3123 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3126 template<bool _Const>
3127 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3129 template<bool _Const>
3132 template<bool _Const>
3134 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3137 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3138 using _Base = lazy_split_view::_Base<_Const>;
3142 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3144 // [range.lazy.split.outer] p1
3145 // Many of the following specifications refer to the notional member
3146 // current of outer-iterator. current is equivalent to current_ if
3147 // V models forward_range, and parent_->current_ otherwise.
3149 __current() noexcept
3151 if constexpr (forward_range<_Vp>)
3154 return *_M_parent->_M_current;
3158 __current() const noexcept
3160 if constexpr (forward_range<_Vp>)
3163 return *_M_parent->_M_current;
3166 _Parent* _M_parent = nullptr;
3168 [[no_unique_address]]
3169 __detail::__maybe_present_t<forward_range<_Vp>,
3170 iterator_t<_Base>> _M_current;
3171 bool _M_trailing_empty = false;
3174 using iterator_concept = __conditional_t<forward_range<_Base>,
3175 forward_iterator_tag,
3176 input_iterator_tag>;
3177 // iterator_category defined in __lazy_split_view_outer_iter_cat
3178 using difference_type = range_difference_t<_Base>;
3180 struct value_type : view_interface<value_type>
3183 _OuterIter _M_i = _OuterIter();
3186 value_type() = default;
3189 value_type(_OuterIter __i)
3190 : _M_i(std::move(__i))
3193 constexpr _InnerIter<_Const>
3195 { return _InnerIter<_Const>{_M_i}; }
3197 constexpr default_sentinel_t
3198 end() const noexcept
3199 { return default_sentinel; }
3202 _OuterIter() = default;
3205 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3206 : _M_parent(__parent)
3210 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3211 requires forward_range<_Base>
3212 : _M_parent(__parent),
3213 _M_current(std::move(__current))
3217 _OuterIter(_OuterIter<!_Const> __i)
3219 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3220 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3221 _M_trailing_empty(__i._M_trailing_empty)
3224 constexpr value_type
3226 { return value_type{*this}; }
3228 constexpr _OuterIter&
3231 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3232 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3233 const auto __end = ranges::end(_M_parent->_M_base);
3234 if (__current() == __end)
3236 _M_trailing_empty = false;
3239 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3240 if (__pbegin == __pend)
3242 else if constexpr (__detail::__tiny_range<_Pattern>)
3244 __current() = ranges::find(std::move(__current()), __end,
3246 if (__current() != __end)
3249 if (__current() == __end)
3250 _M_trailing_empty = true;
3257 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3261 if (__current() == __end)
3262 _M_trailing_empty = true;
3265 } while (++__current() != __end);
3269 constexpr decltype(auto)
3272 if constexpr (forward_range<_Base>)
3282 friend constexpr bool
3283 operator==(const _OuterIter& __x, const _OuterIter& __y)
3284 requires forward_range<_Base>
3286 return __x._M_current == __y._M_current
3287 && __x._M_trailing_empty == __y._M_trailing_empty;
3290 friend constexpr bool
3291 operator==(const _OuterIter& __x, default_sentinel_t)
3292 { return __x.__at_end(); };
3294 friend _OuterIter<!_Const>;
3295 friend _InnerIter<_Const>;
3298 template<bool _Const>
3300 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3303 using _Base = lazy_split_view::_Base<_Const>;
3308 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3309 auto __end = ranges::end(_M_i._M_parent->_M_base);
3310 if constexpr (__detail::__tiny_range<_Pattern>)
3312 const auto& __cur = _M_i_current();
3315 if (__pcur == __pend)
3316 return _M_incremented;
3317 return *__cur == *__pcur;
3321 auto __cur = _M_i_current();
3324 if (__pcur == __pend)
3325 return _M_incremented;
3328 if (*__cur != *__pcur)
3330 if (++__pcur == __pend)
3332 } while (++__cur != __end);
3338 _M_i_current() noexcept
3339 { return _M_i.__current(); }
3342 _M_i_current() const noexcept
3343 { return _M_i.__current(); }
3345 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3346 bool _M_incremented = false;
3349 using iterator_concept
3350 = typename _OuterIter<_Const>::iterator_concept;
3351 // iterator_category defined in __lazy_split_view_inner_iter_cat
3352 using value_type = range_value_t<_Base>;
3353 using difference_type = range_difference_t<_Base>;
3355 _InnerIter() = default;
3358 _InnerIter(_OuterIter<_Const> __i)
3359 : _M_i(std::move(__i))
3362 constexpr const iterator_t<_Base>&
3363 base() const& noexcept
3364 { return _M_i_current(); }
3366 constexpr iterator_t<_Base>
3367 base() && requires forward_range<_Vp>
3368 { return std::move(_M_i_current()); }
3370 constexpr decltype(auto)
3372 { return *_M_i_current(); }
3374 constexpr _InnerIter&
3377 _M_incremented = true;
3378 if constexpr (!forward_range<_Base>)
3379 if constexpr (_Pattern::size() == 0)
3385 constexpr decltype(auto)
3388 if constexpr (forward_range<_Base>)
3398 friend constexpr bool
3399 operator==(const _InnerIter& __x, const _InnerIter& __y)
3400 requires forward_range<_Base>
3401 { return __x._M_i == __y._M_i; }
3403 friend constexpr bool
3404 operator==(const _InnerIter& __x, default_sentinel_t)
3405 { return __x.__at_end(); }
3407 friend constexpr decltype(auto)
3408 iter_move(const _InnerIter& __i)
3409 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3410 { return ranges::iter_move(__i._M_i_current()); }
3412 friend constexpr void
3413 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3414 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3415 __y._M_i_current())))
3416 requires indirectly_swappable<iterator_t<_Base>>
3417 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3420 _Vp _M_base = _Vp();
3421 _Pattern _M_pattern = _Pattern();
3422 [[no_unique_address]]
3423 __detail::__maybe_present_t<!forward_range<_Vp>,
3424 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3428 lazy_split_view() requires (default_initializable<_Vp>
3429 && default_initializable<_Pattern>)
3433 lazy_split_view(_Vp __base, _Pattern __pattern)
3434 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3437 template<input_range _Range>
3438 requires constructible_from<_Vp, views::all_t<_Range>>
3439 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3441 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3442 : _M_base(views::all(std::forward<_Range>(__r))),
3443 _M_pattern(views::single(std::move(__e)))
3447 base() const& requires copy_constructible<_Vp>
3452 { return std::move(_M_base); }
3457 if constexpr (forward_range<_Vp>)
3459 constexpr bool __simple
3460 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3461 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3465 _M_current = ranges::begin(_M_base);
3466 return _OuterIter<false>{this};
3471 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3473 return _OuterIter<true>{this, ranges::begin(_M_base)};
3477 end() requires forward_range<_Vp> && common_range<_Vp>
3479 constexpr bool __simple
3480 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3481 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3487 if constexpr (forward_range<_Vp>
3488 && forward_range<const _Vp>
3489 && common_range<const _Vp>)
3490 return _OuterIter<true>{this, ranges::end(_M_base)};
3492 return default_sentinel;
3496 template<typename _Range, typename _Pattern>
3497 lazy_split_view(_Range&&, _Pattern&&)
3498 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3500 template<input_range _Range>
3501 lazy_split_view(_Range&&, range_value_t<_Range>)
3502 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3508 template<typename _Range, typename _Pattern>
3509 concept __can_lazy_split_view
3510 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3511 } // namespace __detail
3513 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3515 template<viewable_range _Range, typename _Pattern>
3516 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3518 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3520 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3523 using _RangeAdaptor<_LazySplit>::operator();
3524 static constexpr int _S_arity = 2;
3525 // The pattern argument of views::lazy_split is not always simple -- it can be
3526 // a non-view range, the value category of which affects whether the call
3527 // is well-formed. But a scalar or a view pattern argument is surely
3529 template<typename _Pattern>
3530 static constexpr bool _S_has_simple_extra_args
3531 = is_scalar_v<_Pattern> || (view<_Pattern>
3532 && copy_constructible<_Pattern>);
3535 inline constexpr _LazySplit lazy_split;
3536 } // namespace views
3538 template<forward_range _Vp, forward_range _Pattern>
3539 requires view<_Vp> && view<_Pattern>
3540 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3542 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3545 _Vp _M_base = _Vp();
3546 _Pattern _M_pattern = _Pattern();
3547 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3553 split_view() requires (default_initializable<_Vp>
3554 && default_initializable<_Pattern>)
3558 split_view(_Vp __base, _Pattern __pattern)
3559 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3562 template<forward_range _Range>
3563 requires constructible_from<_Vp, views::all_t<_Range>>
3564 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3566 split_view(_Range&& __r, range_value_t<_Range> __e)
3567 : _M_base(views::all(std::forward<_Range>(__r))),
3568 _M_pattern(views::single(std::move(__e)))
3572 base() const& requires copy_constructible<_Vp>
3577 { return std::move(_M_base); }
3582 if (!_M_cached_begin)
3583 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3584 return {this, ranges::begin(_M_base), *_M_cached_begin};
3590 if constexpr (common_range<_Vp>)
3591 return _Iterator{this, ranges::end(_M_base), {}};
3593 return _Sentinel{this};
3596 constexpr subrange<iterator_t<_Vp>>
3597 _M_find_next(iterator_t<_Vp> __it)
3599 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3600 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3612 split_view* _M_parent = nullptr;
3613 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3614 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3615 bool _M_trailing_empty = false;
3617 friend struct _Sentinel;
3620 using iterator_concept = forward_iterator_tag;
3621 using iterator_category = input_iterator_tag;
3622 using value_type = subrange<iterator_t<_Vp>>;
3623 using difference_type = range_difference_t<_Vp>;
3625 _Iterator() = default;
3628 _Iterator(split_view* __parent,
3629 iterator_t<_Vp> __current,
3630 subrange<iterator_t<_Vp>> __next)
3631 : _M_parent(__parent),
3632 _M_cur(std::move(__current)),
3633 _M_next(std::move(__next))
3636 constexpr iterator_t<_Vp>
3640 constexpr value_type
3642 { return {_M_cur, _M_next.begin()}; }
3644 constexpr _Iterator&
3647 _M_cur = _M_next.begin();
3648 if (_M_cur != ranges::end(_M_parent->_M_base))
3650 _M_cur = _M_next.end();
3651 if (_M_cur == ranges::end(_M_parent->_M_base))
3653 _M_trailing_empty = true;
3654 _M_next = {_M_cur, _M_cur};
3657 _M_next = _M_parent->_M_find_next(_M_cur);
3660 _M_trailing_empty = false;
3672 friend constexpr bool
3673 operator==(const _Iterator& __x, const _Iterator& __y)
3675 return __x._M_cur == __y._M_cur
3676 && __x._M_trailing_empty == __y._M_trailing_empty;
3683 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3686 _M_equal(const _Iterator& __x) const
3687 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3690 _Sentinel() = default;
3693 _Sentinel(split_view* __parent)
3694 : _M_end(ranges::end(__parent->_M_base))
3697 friend constexpr bool
3698 operator==(const _Iterator& __x, const _Sentinel& __y)
3699 { return __y._M_equal(__x); }
3703 template<typename _Range, typename _Pattern>
3704 split_view(_Range&&, _Pattern&&)
3705 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3707 template<forward_range _Range>
3708 split_view(_Range&&, range_value_t<_Range>)
3709 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3715 template<typename _Range, typename _Pattern>
3716 concept __can_split_view
3717 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3718 } // namespace __detail
3720 struct _Split : __adaptor::_RangeAdaptor<_Split>
3722 template<viewable_range _Range, typename _Pattern>
3723 requires __detail::__can_split_view<_Range, _Pattern>
3725 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3727 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3730 using _RangeAdaptor<_Split>::operator();
3731 static constexpr int _S_arity = 2;
3732 template<typename _Pattern>
3733 static constexpr bool _S_has_simple_extra_args
3734 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3737 inline constexpr _Split split;
3738 } // namespace views
3744 template<input_or_output_iterator _Iter>
3746 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3748 if constexpr (contiguous_iterator<_Iter>)
3749 return span(std::__to_address(__i), __n);
3750 else if constexpr (random_access_iterator<_Iter>)
3751 return subrange(__i, __i + __n);
3753 return subrange(counted_iterator(std::move(__i), __n),
3758 inline constexpr _Counted counted{};
3759 } // namespace views
3762 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3763 class common_view : public view_interface<common_view<_Vp>>
3766 _Vp _M_base = _Vp();
3769 common_view() requires default_initializable<_Vp> = default;
3772 common_view(_Vp __r)
3773 : _M_base(std::move(__r))
3777 base() const& requires copy_constructible<_Vp>
3782 { return std::move(_M_base); }
3787 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3788 return ranges::begin(_M_base);
3790 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3791 (ranges::begin(_M_base));
3795 begin() const requires range<const _Vp>
3797 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3798 return ranges::begin(_M_base);
3800 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3801 (ranges::begin(_M_base));
3807 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3808 return ranges::begin(_M_base) + ranges::size(_M_base);
3810 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3811 (ranges::end(_M_base));
3815 end() const requires range<const _Vp>
3817 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3818 return ranges::begin(_M_base) + ranges::size(_M_base);
3820 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3821 (ranges::end(_M_base));
3825 size() requires sized_range<_Vp>
3826 { return ranges::size(_M_base); }
3829 size() const requires sized_range<const _Vp>
3830 { return ranges::size(_M_base); }
3833 template<typename _Range>
3834 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3836 template<typename _Tp>
3837 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3838 = enable_borrowed_range<_Tp>;
3844 template<typename _Range>
3845 concept __already_common = common_range<_Range>
3846 && requires { views::all(std::declval<_Range>()); };
3848 template<typename _Range>
3849 concept __can_common_view
3850 = requires { common_view{std::declval<_Range>()}; };
3851 } // namespace __detail
3853 struct _Common : __adaptor::_RangeAdaptorClosure
3855 template<viewable_range _Range>
3856 requires __detail::__already_common<_Range>
3857 || __detail::__can_common_view<_Range>
3859 operator() [[nodiscard]] (_Range&& __r) const
3861 if constexpr (__detail::__already_common<_Range>)
3862 return views::all(std::forward<_Range>(__r));
3864 return common_view{std::forward<_Range>(__r)};
3867 static constexpr bool _S_has_simple_call_op = true;
3870 inline constexpr _Common common;
3871 } // namespace views
3874 requires bidirectional_range<_Vp>
3875 class reverse_view : public view_interface<reverse_view<_Vp>>
3878 static constexpr bool _S_needs_cached_begin
3879 = !common_range<_Vp> && !(random_access_range<_Vp>
3880 && sized_sentinel_for<sentinel_t<_Vp>,
3883 _Vp _M_base = _Vp();
3884 [[no_unique_address]]
3885 __detail::__maybe_present_t<_S_needs_cached_begin,
3886 __detail::_CachedPosition<_Vp>>
3890 reverse_view() requires default_initializable<_Vp> = default;
3893 reverse_view(_Vp __r)
3894 : _M_base(std::move(__r))
3898 base() const& requires copy_constructible<_Vp>
3903 { return std::move(_M_base); }
3905 constexpr reverse_iterator<iterator_t<_Vp>>
3908 if constexpr (_S_needs_cached_begin)
3909 if (_M_cached_begin._M_has_value())
3910 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3912 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3913 if constexpr (_S_needs_cached_begin)
3914 _M_cached_begin._M_set(_M_base, __it);
3915 return std::make_reverse_iterator(std::move(__it));
3919 begin() requires common_range<_Vp>
3920 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3923 begin() const requires common_range<const _Vp>
3924 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3926 constexpr reverse_iterator<iterator_t<_Vp>>
3928 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3931 end() const requires common_range<const _Vp>
3932 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3935 size() requires sized_range<_Vp>
3936 { return ranges::size(_M_base); }
3939 size() const requires sized_range<const _Vp>
3940 { return ranges::size(_M_base); }
3943 template<typename _Range>
3944 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3946 template<typename _Tp>
3947 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3948 = enable_borrowed_range<_Tp>;
3955 inline constexpr bool __is_reversible_subrange = false;
3957 template<typename _Iter, subrange_kind _Kind>
3958 inline constexpr bool
3959 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3960 reverse_iterator<_Iter>,
3964 inline constexpr bool __is_reverse_view = false;
3966 template<typename _Vp>
3967 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3969 template<typename _Range>
3970 concept __can_reverse_view
3971 = requires { reverse_view{std::declval<_Range>()}; };
3972 } // namespace __detail
3974 struct _Reverse : __adaptor::_RangeAdaptorClosure
3976 template<viewable_range _Range>
3977 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3978 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3979 || __detail::__can_reverse_view<_Range>
3981 operator() [[nodiscard]] (_Range&& __r) const
3983 using _Tp = remove_cvref_t<_Range>;
3984 if constexpr (__detail::__is_reverse_view<_Tp>)
3985 return std::forward<_Range>(__r).base();
3986 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3988 using _Iter = decltype(ranges::begin(__r).base());
3989 if constexpr (sized_range<_Tp>)
3990 return subrange<_Iter, _Iter, subrange_kind::sized>
3991 {__r.end().base(), __r.begin().base(), __r.size()};
3993 return subrange<_Iter, _Iter, subrange_kind::unsized>
3994 {__r.end().base(), __r.begin().base()};
3997 return reverse_view{std::forward<_Range>(__r)};
4000 static constexpr bool _S_has_simple_call_op = true;
4003 inline constexpr _Reverse reverse;
4004 } // namespace views
4008 template<typename _Tp, size_t _Nm>
4009 concept __has_tuple_element = requires(_Tp __t)
4011 typename tuple_size<_Tp>::type;
4012 requires _Nm < tuple_size_v<_Tp>;
4013 typename tuple_element_t<_Nm, _Tp>;
4014 { std::get<_Nm>(__t) }
4015 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4018 template<typename _Tp, size_t _Nm>
4019 concept __returnable_element
4020 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4023 template<input_range _Vp, size_t _Nm>
4025 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4026 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4028 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4029 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4032 elements_view() requires default_initializable<_Vp> = default;
4035 elements_view(_Vp __base)
4036 : _M_base(std::move(__base))
4040 base() const& requires copy_constructible<_Vp>
4045 { return std::move(_M_base); }
4048 begin() requires (!__detail::__simple_view<_Vp>)
4049 { return _Iterator<false>(ranges::begin(_M_base)); }
4052 begin() const requires range<const _Vp>
4053 { return _Iterator<true>(ranges::begin(_M_base)); }
4056 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4057 { return _Sentinel<false>{ranges::end(_M_base)}; }
4060 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4061 { return _Iterator<false>{ranges::end(_M_base)}; }
4064 end() const requires range<const _Vp>
4065 { return _Sentinel<true>{ranges::end(_M_base)}; }
4068 end() const requires common_range<const _Vp>
4069 { return _Iterator<true>{ranges::end(_M_base)}; }
4072 size() requires sized_range<_Vp>
4073 { return ranges::size(_M_base); }
4076 size() const requires sized_range<const _Vp>
4077 { return ranges::size(_M_base); }
4080 template<bool _Const>
4081 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4083 template<bool _Const>
4087 template<bool _Const>
4088 requires forward_range<_Base<_Const>>
4089 struct __iter_cat<_Const>
4092 static auto _S_iter_cat()
4094 using _Base = elements_view::_Base<_Const>;
4095 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4096 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4097 if constexpr (!is_lvalue_reference_v<_Res>)
4098 return input_iterator_tag{};
4099 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4100 return random_access_iterator_tag{};
4105 using iterator_category = decltype(_S_iter_cat());
4108 template<bool _Const>
4111 template<bool _Const>
4112 struct _Iterator : __iter_cat<_Const>
4115 using _Base = elements_view::_Base<_Const>;
4117 iterator_t<_Base> _M_current = iterator_t<_Base>();
4119 static constexpr decltype(auto)
4120 _S_get_element(const iterator_t<_Base>& __i)
4122 if constexpr (is_reference_v<range_reference_t<_Base>>)
4123 return std::get<_Nm>(*__i);
4126 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4127 return static_cast<_Et>(std::get<_Nm>(*__i));
4134 if constexpr (random_access_range<_Base>)
4135 return random_access_iterator_tag{};
4136 else if constexpr (bidirectional_range<_Base>)
4137 return bidirectional_iterator_tag{};
4138 else if constexpr (forward_range<_Base>)
4139 return forward_iterator_tag{};
4141 return input_iterator_tag{};
4144 friend _Iterator<!_Const>;
4147 using iterator_concept = decltype(_S_iter_concept());
4148 // iterator_category defined in elements_view::__iter_cat
4150 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4151 using difference_type = range_difference_t<_Base>;
4153 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4156 _Iterator(iterator_t<_Base> __current)
4157 : _M_current(std::move(__current))
4161 _Iterator(_Iterator<!_Const> __i)
4162 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4163 : _M_current(std::move(__i._M_current))
4166 constexpr const iterator_t<_Base>&
4167 base() const& noexcept
4168 { return _M_current; }
4170 constexpr iterator_t<_Base>
4172 { return std::move(_M_current); }
4174 constexpr decltype(auto)
4176 { return _S_get_element(_M_current); }
4178 constexpr _Iterator&
4190 operator++(int) requires forward_range<_Base>
4197 constexpr _Iterator&
4198 operator--() requires bidirectional_range<_Base>
4205 operator--(int) requires bidirectional_range<_Base>
4212 constexpr _Iterator&
4213 operator+=(difference_type __n)
4214 requires random_access_range<_Base>
4220 constexpr _Iterator&
4221 operator-=(difference_type __n)
4222 requires random_access_range<_Base>
4228 constexpr decltype(auto)
4229 operator[](difference_type __n) const
4230 requires random_access_range<_Base>
4231 { return _S_get_element(_M_current + __n); }
4233 friend constexpr bool
4234 operator==(const _Iterator& __x, const _Iterator& __y)
4235 requires equality_comparable<iterator_t<_Base>>
4236 { return __x._M_current == __y._M_current; }
4238 friend constexpr bool
4239 operator<(const _Iterator& __x, const _Iterator& __y)
4240 requires random_access_range<_Base>
4241 { return __x._M_current < __y._M_current; }
4243 friend constexpr bool
4244 operator>(const _Iterator& __x, const _Iterator& __y)
4245 requires random_access_range<_Base>
4246 { return __y._M_current < __x._M_current; }
4248 friend constexpr bool
4249 operator<=(const _Iterator& __x, const _Iterator& __y)
4250 requires random_access_range<_Base>
4251 { return !(__y._M_current > __x._M_current); }
4253 friend constexpr bool
4254 operator>=(const _Iterator& __x, const _Iterator& __y)
4255 requires random_access_range<_Base>
4256 { return !(__x._M_current > __y._M_current); }
4258#ifdef __cpp_lib_three_way_comparison
4259 friend constexpr auto
4260 operator<=>(const _Iterator& __x, const _Iterator& __y)
4261 requires random_access_range<_Base>
4262 && three_way_comparable<iterator_t<_Base>>
4263 { return __x._M_current <=> __y._M_current; }
4266 friend constexpr _Iterator
4267 operator+(const _Iterator& __x, difference_type __y)
4268 requires random_access_range<_Base>
4269 { return _Iterator{__x} += __y; }
4271 friend constexpr _Iterator
4272 operator+(difference_type __x, const _Iterator& __y)
4273 requires random_access_range<_Base>
4274 { return __y + __x; }
4276 friend constexpr _Iterator
4277 operator-(const _Iterator& __x, difference_type __y)
4278 requires random_access_range<_Base>
4279 { return _Iterator{__x} -= __y; }
4281 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4282 // 3483. transform_view::iterator's difference is overconstrained
4283 friend constexpr difference_type
4284 operator-(const _Iterator& __x, const _Iterator& __y)
4285 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4286 { return __x._M_current - __y._M_current; }
4288 template <bool> friend struct _Sentinel;
4291 template<bool _Const>
4295 template<bool _Const2>
4297 _M_equal(const _Iterator<_Const2>& __x) const
4298 { return __x._M_current == _M_end; }
4300 template<bool _Const2>
4302 _M_distance_from(const _Iterator<_Const2>& __i) const
4303 { return _M_end - __i._M_current; }
4305 using _Base = elements_view::_Base<_Const>;
4306 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4309 _Sentinel() = default;
4312 _Sentinel(sentinel_t<_Base> __end)
4313 : _M_end(std::move(__end))
4317 _Sentinel(_Sentinel<!_Const> __other)
4319 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4320 : _M_end(std::move(__other._M_end))
4323 constexpr sentinel_t<_Base>
4327 template<bool _Const2>
4328 requires sentinel_for<sentinel_t<_Base>,
4329 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4330 friend constexpr bool
4331 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4332 { return __y._M_equal(__x); }
4334 template<bool _Const2,
4335 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4336 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4337 friend constexpr range_difference_t<_Base2>
4338 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4339 { return -__y._M_distance_from(__x); }
4341 template<bool _Const2,
4342 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4343 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4344 friend constexpr range_difference_t<_Base2>
4345 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4346 { return __x._M_distance_from(__y); }
4348 friend _Sentinel<!_Const>;
4351 _Vp _M_base = _Vp();
4354 template<typename _Tp, size_t _Nm>
4355 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4356 = enable_borrowed_range<_Tp>;
4358 template<typename _Range>
4359 using keys_view = elements_view<views::all_t<_Range>, 0>;
4361 template<typename _Range>
4362 using values_view = elements_view<views::all_t<_Range>, 1>;
4368 template<size_t _Nm, typename _Range>
4369 concept __can_elements_view
4370 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4371 } // namespace __detail
4373 template<size_t _Nm>
4374 struct _Elements : __adaptor::_RangeAdaptorClosure
4376 template<viewable_range _Range>
4377 requires __detail::__can_elements_view<_Nm, _Range>
4379 operator() [[nodiscard]] (_Range&& __r) const
4381 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4384 static constexpr bool _S_has_simple_call_op = true;
4387 template<size_t _Nm>
4388 inline constexpr _Elements<_Nm> elements;
4389 inline constexpr auto keys = elements<0>;
4390 inline constexpr auto values = elements<1>;
4391 } // namespace views
4393#if __cplusplus > 202002L
4395#define __cpp_lib_ranges_zip 202110L
4399 template<typename... _Rs>
4400 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4401 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4402 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4404 template<typename... _Ts>
4405 struct __tuple_or_pair
4406 { using type = std::tuple<_Ts...>; };
4408 template<typename _Tp, typename _Up>
4409 struct __tuple_or_pair<_Tp, _Up>
4410 { using type = pair<_Tp, _Up>; };
4412 template<typename... _Ts>
4413 using __tuple_or_pair_t = typename __tuple_or_pair<_Ts...>::type;
4415 template<typename _Fp, typename _Tuple>
4417 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4419 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4420 return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
4421 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4422 }, std::forward<_Tuple>(__tuple));
4425 template<typename _Fp, typename _Tuple>
4427 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4429 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4430 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4431 }, std::forward<_Tuple>(__tuple));
4433 } // namespace __detail
4435 template<input_range... _Vs>
4436 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4437 class zip_view : public view_interface<zip_view<_Vs...>>
4439 tuple<_Vs...> _M_views;
4441 template<bool> class _Iterator;
4442 template<bool> class _Sentinel;
4445 zip_view() = default;
4448 zip_view(_Vs... __views)
4449 : _M_views(std::move(__views)...)
4453 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4454 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4457 begin() const requires (range<const _Vs> && ...)
4458 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4461 end() requires (!(__detail::__simple_view<_Vs> && ...))
4463 if constexpr (!__detail::__zip_is_common<_Vs...>)
4464 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4465 else if constexpr ((random_access_range<_Vs> && ...))
4466 return begin() + iter_difference_t<_Iterator<false>>(size());
4468 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4472 end() const requires (range<const _Vs> && ...)
4474 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4475 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4476 else if constexpr ((random_access_range<const _Vs> && ...))
4477 return begin() + iter_difference_t<_Iterator<true>>(size());
4479 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4483 size() requires (sized_range<_Vs> && ...)
4485 return std::apply([](auto... sizes) {
4486 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4487 return ranges::min({_CT(sizes)...});
4488 }, __detail::__tuple_transform(ranges::size, _M_views));
4492 size() const requires (sized_range<const _Vs> && ...)
4494 return std::apply([](auto... sizes) {
4495 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4496 return ranges::min({_CT(sizes)...});
4497 }, __detail::__tuple_transform(ranges::size, _M_views));
4501 template<typename... _Rs>
4502 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4504 template<typename... _Views>
4505 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4506 = (enable_borrowed_range<_Views> && ...);
4510 template<bool _Const, typename... _Vs>
4511 concept __all_random_access
4512 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4514 template<bool _Const, typename... _Vs>
4515 concept __all_bidirectional
4516 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4518 template<bool _Const, typename... _Vs>
4519 concept __all_forward
4520 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4522 template<bool _Const, typename... _Views>
4523 struct __zip_view_iter_cat
4526 template<bool _Const, typename... _Views>
4527 requires __all_forward<_Const, _Views...>
4528 struct __zip_view_iter_cat<_Const, _Views...>
4529 { using iterator_category = input_iterator_tag; };
4530 } // namespace __detail
4532 template<input_range... _Vs>
4533 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4534 template<bool _Const>
4535 class zip_view<_Vs...>::_Iterator
4536 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4538 __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4541 _Iterator(decltype(_M_current) __current)
4542 : _M_current(std::move(__current))
4548 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4549 return random_access_iterator_tag{};
4550 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4551 return bidirectional_iterator_tag{};
4552 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4553 return forward_iterator_tag{};
4555 return input_iterator_tag{};
4558 template<copy_constructible _Fp, input_range... _Ws>
4559 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4560 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4561 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4562 friend class zip_transform_view;
4565 // iterator_category defined in __zip_view_iter_cat
4566 using iterator_concept = decltype(_S_iter_concept());
4568 = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4569 using difference_type
4570 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4572 _Iterator() = default;
4575 _Iterator(_Iterator<!_Const> __i)
4577 && (convertible_to<iterator_t<_Vs>,
4578 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4579 : _M_current(std::move(__i._M_current))
4585 auto __f = [](auto& __i) -> decltype(auto) {
4588 return __detail::__tuple_transform(__f, _M_current);
4591 constexpr _Iterator&
4594 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4604 requires __detail::__all_forward<_Const, _Vs...>
4611 constexpr _Iterator&
4613 requires __detail::__all_bidirectional<_Const, _Vs...>
4615 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4621 requires __detail::__all_bidirectional<_Const, _Vs...>
4628 constexpr _Iterator&
4629 operator+=(difference_type __x)
4630 requires __detail::__all_random_access<_Const, _Vs...>
4632 auto __f = [&]<typename _It>(_It& __i) {
4633 __i += iter_difference_t<_It>(__x);
4635 __detail::__tuple_for_each(__f, _M_current);
4639 constexpr _Iterator&
4640 operator-=(difference_type __x)
4641 requires __detail::__all_random_access<_Const, _Vs...>
4643 auto __f = [&]<typename _It>(_It& __i) {
4644 __i -= iter_difference_t<_It>(__x);
4646 __detail::__tuple_for_each(__f, _M_current);
4651 operator[](difference_type __n) const
4652 requires __detail::__all_random_access<_Const, _Vs...>
4654 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4655 return __i[iter_difference_t<_It>(__n)];
4657 return __detail::__tuple_transform(__f, _M_current);
4660 friend constexpr bool
4661 operator==(const _Iterator& __x, const _Iterator& __y)
4662 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4664 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4665 return __x._M_current == __y._M_current;
4667 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4668 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4669 }(make_index_sequence<sizeof...(_Vs)>{});
4672 friend constexpr auto
4673 operator<=>(const _Iterator& __x, const _Iterator& __y)
4674 requires __detail::__all_random_access<_Const, _Vs...>
4675 { return __x._M_current <=> __y._M_current; }
4677 friend constexpr _Iterator
4678 operator+(const _Iterator& __i, difference_type __n)
4679 requires __detail::__all_random_access<_Const, _Vs...>
4686 friend constexpr _Iterator
4687 operator+(difference_type __n, const _Iterator& __i)
4688 requires __detail::__all_random_access<_Const, _Vs...>
4695 friend constexpr _Iterator
4696 operator-(const _Iterator& __i, difference_type __n)
4697 requires __detail::__all_random_access<_Const, _Vs...>
4704 friend constexpr difference_type
4705 operator-(const _Iterator& __x, const _Iterator& __y)
4706 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4707 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4709 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4710 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4711 - std::get<_Is>(__y._M_current))...},
4713 [](difference_type __i) {
4714 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4716 }(make_index_sequence<sizeof...(_Vs)>{});
4719 friend constexpr auto
4720 iter_move(const _Iterator& __i)
4721 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4723 friend constexpr void
4724 iter_swap(const _Iterator& __l, const _Iterator& __r)
4725 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4727 [&]<size_t... _Is>(index_sequence<_Is...>) {
4728 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4729 }(make_index_sequence<sizeof...(_Vs)>{});
4732 friend class zip_view;
4735 template<input_range... _Vs>
4736 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4737 template<bool _Const>
4738 class zip_view<_Vs...>::_Sentinel
4740 __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4743 _Sentinel(decltype(_M_end) __end)
4747 friend class zip_view;
4750 _Sentinel() = default;
4753 _Sentinel(_Sentinel<!_Const> __i)
4755 && (convertible_to<sentinel_t<_Vs>,
4756 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4757 : _M_end(std::move(__i._M_end))
4760 template<bool _OtherConst>
4761 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4762 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4763 friend constexpr bool
4764 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4766 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4767 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4768 }(make_index_sequence<sizeof...(_Vs)>{});
4771 template<bool _OtherConst>
4772 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4773 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4774 friend constexpr auto
4775 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4778 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4779 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4780 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4783 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4785 }(make_index_sequence<sizeof...(_Vs)>{});
4788 template<bool _OtherConst>
4789 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4790 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4791 friend constexpr auto
4792 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4793 { return -(__x - __y); }
4800 template<typename... _Ts>
4801 concept __can_zip_view
4802 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4807 template<typename... _Ts>
4808 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4810 operator() [[nodiscard]] (_Ts&&... __ts) const
4812 if constexpr (sizeof...(_Ts) == 0)
4813 return views::empty<tuple<>>;
4815 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4819 inline constexpr _Zip zip;
4824 template<typename _Range, bool _Const>
4825 using __range_iter_cat
4826 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4829 template<copy_constructible _Fp, input_range... _Vs>
4830 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4831 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4832 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4833 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
4835 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4836 zip_view<_Vs...> _M_zip;
4838 using _InnerView = zip_view<_Vs...>;
4840 template<bool _Const>
4841 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4843 template<bool _Const>
4844 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4846 template<bool _Const>
4847 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
4849 template<bool _Const>
4853 template<bool _Const>
4854 requires forward_range<_Base<_Const>>
4855 struct __iter_cat<_Const>
4861 using __detail::__maybe_const_t;
4862 using __detail::__range_iter_cat;
4863 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
4864 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
4865 if constexpr (!is_lvalue_reference_v<_Res>)
4866 return input_iterator_tag{};
4867 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4868 random_access_iterator_tag> && ...))
4869 return random_access_iterator_tag{};
4870 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4871 bidirectional_iterator_tag> && ...))
4872 return bidirectional_iterator_tag{};
4873 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4874 forward_iterator_tag> && ...))
4875 return forward_iterator_tag{};
4877 return input_iterator_tag{};
4880 using iterator_category = decltype(_S_iter_cat());
4883 template<bool> class _Iterator;
4884 template<bool> class _Sentinel;
4887 zip_transform_view() = default;
4890 zip_transform_view(_Fp __fun, _Vs... __views)
4891 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
4896 { return _Iterator<false>(*this, _M_zip.begin()); }
4900 requires range<const _InnerView>
4901 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4902 { return _Iterator<true>(*this, _M_zip.begin()); }
4907 if constexpr (common_range<_InnerView>)
4908 return _Iterator<false>(*this, _M_zip.end());
4910 return _Sentinel<false>(_M_zip.end());
4915 requires range<const _InnerView>
4916 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4918 if constexpr (common_range<const _InnerView>)
4919 return _Iterator<true>(*this, _M_zip.end());
4921 return _Sentinel<true>(_M_zip.end());
4925 size() requires sized_range<_InnerView>
4926 { return _M_zip.size(); }
4929 size() const requires sized_range<const _InnerView>
4930 { return _M_zip.size(); }
4933 template<class _Fp, class... Rs>
4934 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
4936 template<copy_constructible _Fp, input_range... _Vs>
4937 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4938 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4939 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4940 template<bool _Const>
4941 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
4943 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
4945 _Parent* _M_parent = nullptr;
4946 __ziperator<_Const> _M_inner;
4949 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
4950 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
4953 friend class zip_transform_view;
4956 // iterator_category defined in zip_transform_view::__iter_cat
4957 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
4959 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
4960 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
4961 using difference_type = range_difference_t<_Base<_Const>>;
4963 _Iterator() = default;
4966 _Iterator(_Iterator<!_Const> __i)
4967 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
4968 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
4971 constexpr decltype(auto)
4974 return std::apply([&](const auto&... __iters) -> decltype(auto) {
4975 return std::__invoke(*_M_parent->_M_fun, *__iters...);
4976 }, _M_inner._M_current);
4979 constexpr _Iterator&
4991 operator++(int) requires forward_range<_Base<_Const>>
4998 constexpr _Iterator&
4999 operator--() requires bidirectional_range<_Base<_Const>>
5006 operator--(int) requires bidirectional_range<_Base<_Const>>
5013 constexpr _Iterator&
5014 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5020 constexpr _Iterator&
5021 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5027 constexpr decltype(auto)
5028 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5030 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5031 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5032 }, _M_inner._M_current);
5035 friend constexpr bool
5036 operator==(const _Iterator& __x, const _Iterator& __y)
5037 requires equality_comparable<__ziperator<_Const>>
5038 { return __x._M_inner == __y._M_inner; }
5040 friend constexpr auto
5041 operator<=>(const _Iterator& __x, const _Iterator& __y)
5042 requires random_access_range<_Base<_Const>>
5043 { return __x._M_inner <=> __y._M_inner; }
5045 friend constexpr _Iterator
5046 operator+(const _Iterator& __i, difference_type __n)
5047 requires random_access_range<_Base<_Const>>
5048 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5050 friend constexpr _Iterator
5051 operator+(difference_type __n, const _Iterator& __i)
5052 requires random_access_range<_Base<_Const>>
5053 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5055 friend constexpr _Iterator
5056 operator-(const _Iterator& __i, difference_type __n)
5057 requires random_access_range<_Base<_Const>>
5058 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5060 friend constexpr difference_type
5061 operator-(const _Iterator& __x, const _Iterator& __y)
5062 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5063 { return __x._M_inner - __y._M_inner; }
5066 template<copy_constructible _Fp, input_range... _Vs>
5067 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5068 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5069 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5070 template<bool _Const>
5071 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5073 __zentinel<_Const> _M_inner;
5076 _Sentinel(__zentinel<_Const> __inner)
5080 friend class zip_transform_view;
5083 _Sentinel() = default;
5086 _Sentinel(_Sentinel<!_Const> __i)
5087 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5088 : _M_inner(std::move(__i._M_inner))
5091 template<bool _OtherConst>
5092 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5093 friend constexpr bool
5094 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5095 { return __x._M_inner == __y._M_inner; }
5097 template<bool _OtherConst>
5098 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5099 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5100 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5101 { return __x._M_inner - __y._M_inner; }
5103 template<bool _OtherConst>
5104 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5105 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5106 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5107 { return __x._M_inner - __y._M_inner; }
5114 template<typename _Fp, typename... _Ts>
5115 concept __can_zip_transform_view
5116 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5119 struct _ZipTransform
5121 template<typename _Fp, typename... _Ts>
5122 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5124 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5126 if constexpr (sizeof...(_Ts) == 0)
5127 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5129 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5133 inline constexpr _ZipTransform zip_transform;
5136 template<forward_range _Vp, size_t _Nm>
5137 requires view<_Vp> && (_Nm > 0)
5138 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5140 _Vp _M_base = _Vp();
5142 template<bool> class _Iterator;
5143 template<bool> class _Sentinel;
5145 struct __as_sentinel
5149 adjacent_view() requires default_initializable<_Vp> = default;
5152 adjacent_view(_Vp __base)
5153 : _M_base(std::move(__base))
5157 begin() requires (!__detail::__simple_view<_Vp>)
5158 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5161 begin() const requires range<const _Vp>
5162 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5165 end() requires (!__detail::__simple_view<_Vp>)
5167 if constexpr (common_range<_Vp>)
5168 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5170 return _Sentinel<false>(ranges::end(_M_base));
5174 end() const requires range<const _Vp>
5176 if constexpr (common_range<const _Vp>)
5177 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5179 return _Sentinel<true>(ranges::end(_M_base));
5183 size() requires sized_range<_Vp>
5185 using _ST = decltype(ranges::size(_M_base));
5186 using _CT = common_type_t<_ST, size_t>;
5187 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5188 __sz -= std::min<_CT>(__sz, _Nm - 1);
5189 return static_cast<_ST>(__sz);
5193 size() const requires sized_range<const _Vp>
5195 using _ST = decltype(ranges::size(_M_base));
5196 using _CT = common_type_t<_ST, size_t>;
5197 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5198 __sz -= std::min<_CT>(__sz, _Nm - 1);
5199 return static_cast<_ST>(__sz);
5203 template<typename _Vp, size_t _Nm>
5204 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5205 = enable_borrowed_range<_Vp>;
5209 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5210 template<typename _Tp, size_t _Nm>
5211 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5213 // For a functor F that is callable with N arguments, the expression
5214 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5215 template<typename _Fp, size_t _Nm>
5218 template<typename... _Ts>
5219 static invoke_result_t<_Fp, _Ts...>
5220 __tuple_apply(const tuple<_Ts...>&); // not defined
5222 template<typename _Tp>
5223 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5224 operator()(_Tp&&); // not defined
5228 template<forward_range _Vp, size_t _Nm>
5229 requires view<_Vp> && (_Nm > 0)
5230 template<bool _Const>
5231 class adjacent_view<_Vp, _Nm>::_Iterator
5233 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5234 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5237 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5239 for (auto& __i : _M_current)
5242 ranges::advance(__first, 1, __last);
5247 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5249 if constexpr (!bidirectional_range<_Base>)
5250 for (auto& __it : _M_current)
5253 for (size_t __i = 0; __i < _Nm; ++__i)
5255 _M_current[_Nm - 1 - __i] = __last;
5256 ranges::advance(__last, -1, __first);
5263 if constexpr (random_access_range<_Base>)
5264 return random_access_iterator_tag{};
5265 else if constexpr (bidirectional_range<_Base>)
5266 return bidirectional_iterator_tag{};
5268 return forward_iterator_tag{};
5271 friend class adjacent_view;
5273 template<forward_range _Wp, copy_constructible _Fp, size_t _Mm>
5274 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5275 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5276 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5277 range_reference_t<_Wp>>>
5278 friend class adjacent_transform_view;
5281 using iterator_category = input_iterator_tag;
5282 using iterator_concept = decltype(_S_iter_concept());
5283 using value_type = conditional_t<_Nm == 2,
5284 pair<range_value_t<_Base>, range_value_t<_Base>>,
5285 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5286 using difference_type = range_difference_t<_Base>;
5288 _Iterator() = default;
5291 _Iterator(_Iterator<!_Const> __i)
5292 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5294 for (size_t __j = 0; __j < _Nm; ++__j)
5295 _M_current[__j] = std::move(__i._M_current[__j]);
5301 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5302 return __detail::__tuple_transform(__f, _M_current);
5305 constexpr _Iterator&
5308 for (auto& __i : _M_current)
5321 constexpr _Iterator&
5322 operator--() requires bidirectional_range<_Base>
5324 for (auto& __i : _M_current)
5330 operator--(int) requires bidirectional_range<_Base>
5337 constexpr _Iterator&
5338 operator+=(difference_type __x)
5339 requires random_access_range<_Base>
5341 for (auto& __i : _M_current)
5346 constexpr _Iterator&
5347 operator-=(difference_type __x)
5348 requires random_access_range<_Base>
5350 for (auto& __i : _M_current)
5356 operator[](difference_type __n) const
5357 requires random_access_range<_Base>
5359 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5360 return __detail::__tuple_transform(__f, _M_current);
5363 friend constexpr bool
5364 operator==(const _Iterator& __x, const _Iterator& __y)
5365 { return __x._M_current.back() == __y._M_current.back(); }
5367 friend constexpr bool
5368 operator<(const _Iterator& __x, const _Iterator& __y)
5369 requires random_access_range<_Base>
5370 { return __x._M_current.back() < __y._M_current.back(); }
5372 friend constexpr bool
5373 operator>(const _Iterator& __x, const _Iterator& __y)
5374 requires random_access_range<_Base>
5375 { return __y < __x; }
5377 friend constexpr bool
5378 operator<=(const _Iterator& __x, const _Iterator& __y)
5379 requires random_access_range<_Base>
5380 { return !(__y < __x); }
5382 friend constexpr bool
5383 operator>=(const _Iterator& __x, const _Iterator& __y)
5384 requires random_access_range<_Base>
5385 { return !(__x < __y); }
5387 friend constexpr auto
5388 operator<=>(const _Iterator& __x, const _Iterator& __y)
5389 requires random_access_range<_Base>
5390 && three_way_comparable<iterator_t<_Base>>
5391 { return __x._M_current.back() <=> __y._M_current.back(); }
5393 friend constexpr _Iterator
5394 operator+(const _Iterator& __i, difference_type __n)
5395 requires random_access_range<_Base>
5402 friend constexpr _Iterator
5403 operator+(difference_type __n, const _Iterator& __i)
5404 requires random_access_range<_Base>
5411 friend constexpr _Iterator
5412 operator-(const _Iterator& __i, difference_type __n)
5413 requires random_access_range<_Base>
5420 friend constexpr difference_type
5421 operator-(const _Iterator& __x, const _Iterator& __y)
5422 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5423 { return __x._M_current.back() - __y._M_current.back(); }
5425 friend constexpr auto
5426 iter_move(const _Iterator& __i)
5427 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5429 friend constexpr void
5430 iter_swap(const _Iterator& __l, const _Iterator& __r)
5431 requires indirectly_swappable<iterator_t<_Base>>
5433 for (size_t __i = 0; __i < _Nm; __i++)
5434 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5438 template<forward_range _Vp, size_t _Nm>
5439 requires view<_Vp> && (_Nm > 0)
5440 template<bool _Const>
5441 class adjacent_view<_Vp, _Nm>::_Sentinel
5443 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5445 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5448 _Sentinel(sentinel_t<_Base> __end)
5452 friend class adjacent_view;
5455 _Sentinel() = default;
5458 _Sentinel(_Sentinel<!_Const> __i)
5459 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5460 : _M_end(std::move(__i._M_end))
5463 template<bool _OtherConst>
5464 requires sentinel_for<sentinel_t<_Base>,
5465 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5466 friend constexpr bool
5467 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5468 { return __x._M_current.back() == __y._M_end; }
5470 template<bool _OtherConst>
5471 requires sized_sentinel_for<sentinel_t<_Base>,
5472 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5473 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5474 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5475 { return __x._M_current.back() - __y._M_end; }
5477 template<bool _OtherConst>
5478 requires sized_sentinel_for<sentinel_t<_Base>,
5479 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5480 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5481 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5482 { return __y._M_end - __x._M_current.back(); }
5489 template<size_t _Nm, typename _Range>
5490 concept __can_adjacent_view
5491 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5494 template<size_t _Nm>
5495 struct _Adjacent : __adaptor::_RangeAdaptorClosure
5497 template<viewable_range _Range>
5498 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5500 operator() [[nodiscard]] (_Range&& __r) const
5502 if constexpr (_Nm == 0)
5503 return views::empty<tuple<>>;
5505 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5509 template<size_t _Nm>
5510 inline constexpr _Adjacent<_Nm> adjacent;
5512 inline constexpr auto pairwise = adjacent<2>;
5515 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5516 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5517 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5518 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5519 range_reference_t<_Vp>>>
5520 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5522 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5523 adjacent_view<_Vp, _Nm> _M_inner;
5525 using _InnerView = adjacent_view<_Vp, _Nm>;
5527 template<bool _Const>
5528 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5530 template<bool _Const>
5531 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5533 template<bool> class _Iterator;
5534 template<bool> class _Sentinel;
5537 adjacent_transform_view() = default;
5540 adjacent_transform_view(_Vp __base, _Fp __fun)
5541 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5546 { return _Iterator<false>(*this, _M_inner.begin()); }
5550 requires range<const _InnerView>
5551 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5552 range_reference_t<const _Vp>>
5553 { return _Iterator<true>(*this, _M_inner.begin()); }
5558 if constexpr (common_range<_InnerView>)
5559 return _Iterator<false>(*this, _M_inner.end());
5561 return _Sentinel<false>(_M_inner.end());
5566 requires range<const _InnerView>
5567 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5568 range_reference_t<const _Vp>>
5570 if constexpr (common_range<const _InnerView>)
5571 return _Iterator<true>(*this, _M_inner.end());
5573 return _Sentinel<true>(_M_inner.end());
5577 size() requires sized_range<_InnerView>
5578 { return _M_inner.size(); }
5581 size() const requires sized_range<const _InnerView>
5582 { return _M_inner.size(); }
5585 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5586 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5587 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5588 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5589 range_reference_t<_Vp>>>
5590 template<bool _Const>
5591 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5593 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5594 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5596 _Parent* _M_parent = nullptr;
5597 _InnerIter<_Const> _M_inner;
5600 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5601 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5607 using __detail::__maybe_const_t;
5608 using __detail::__unarize;
5609 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5610 range_reference_t<_Base>>;
5611 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5612 if constexpr (!is_lvalue_reference_v<_Res>)
5613 return input_iterator_tag{};
5614 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5615 return random_access_iterator_tag{};
5616 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5617 return bidirectional_iterator_tag{};
5618 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5619 return forward_iterator_tag{};
5621 return input_iterator_tag{};
5624 friend class adjacent_transform_view;
5627 using iterator_category = decltype(_S_iter_cat());
5628 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5630 = remove_cvref_t<invoke_result_t
5631 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5632 range_reference_t<_Base>>>;
5633 using difference_type = range_difference_t<_Base>;
5635 _Iterator() = default;
5638 _Iterator(_Iterator<!_Const> __i)
5639 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5640 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5643 constexpr decltype(auto)
5646 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5647 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5648 }, _M_inner._M_current);
5651 constexpr _Iterator&
5666 constexpr _Iterator&
5667 operator--() requires bidirectional_range<_Base>
5674 operator--(int) requires bidirectional_range<_Base>
5681 constexpr _Iterator&
5682 operator+=(difference_type __x) requires random_access_range<_Base>
5688 constexpr _Iterator&
5689 operator-=(difference_type __x) requires random_access_range<_Base>
5695 constexpr decltype(auto)
5696 operator[](difference_type __n) const requires random_access_range<_Base>
5698 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5699 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5700 }, _M_inner._M_current);
5703 friend constexpr bool
5704 operator==(const _Iterator& __x, const _Iterator& __y)
5705 { return __x._M_inner == __y._M_inner; }
5707 friend constexpr bool
5708 operator<(const _Iterator& __x, const _Iterator& __y)
5709 requires random_access_range<_Base>
5710 { return __x._M_inner < __y._M_inner; }
5712 friend constexpr bool
5713 operator>(const _Iterator& __x, const _Iterator& __y)
5714 requires random_access_range<_Base>
5715 { return __x._M_inner > __y._M_inner; }
5717 friend constexpr bool
5718 operator<=(const _Iterator& __x, const _Iterator& __y)
5719 requires random_access_range<_Base>
5720 { return __x._M_inner <= __y._M_inner; }
5722 friend constexpr bool
5723 operator>=(const _Iterator& __x, const _Iterator& __y)
5724 requires random_access_range<_Base>
5725 { return __x._M_inner >= __y._M_inner; }
5727 friend constexpr auto
5728 operator<=>(const _Iterator& __x, const _Iterator& __y)
5729 requires random_access_range<_Base> &&
5730 three_way_comparable<_InnerIter<_Const>>
5731 { return __x._M_inner <=> __y._M_inner; }
5733 friend constexpr _Iterator
5734 operator+(const _Iterator& __i, difference_type __n)
5735 requires random_access_range<_Base>
5736 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5738 friend constexpr _Iterator
5739 operator+(difference_type __n, const _Iterator& __i)
5740 requires random_access_range<_Base>
5741 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5743 friend constexpr _Iterator
5744 operator-(const _Iterator& __i, difference_type __n)
5745 requires random_access_range<_Base>
5746 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5748 friend constexpr difference_type
5749 operator-(const _Iterator& __x, const _Iterator& __y)
5750 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5751 { return __x._M_inner - __y._M_inner; }
5754 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5755 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5756 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5757 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5758 range_reference_t<_Vp>>>
5759 template<bool _Const>
5760 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5762 _InnerSent<_Const> _M_inner;
5765 _Sentinel(_InnerSent<_Const> __inner)
5769 friend class adjacent_transform_view;
5772 _Sentinel() = default;
5775 _Sentinel(_Sentinel<!_Const> __i)
5776 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5777 : _M_inner(std::move(__i._M_inner))
5780 template<bool _OtherConst>
5781 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5782 friend constexpr bool
5783 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5784 { return __x._M_inner == __y._M_inner; }
5786 template<bool _OtherConst>
5787 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5788 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5789 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5790 { return __x._M_inner - __y._M_inner; }
5792 template<bool _OtherConst>
5793 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5794 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5795 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5796 { return __x._M_inner - __y._M_inner; }
5803 template<size_t _Nm, typename _Range, typename _Fp>
5804 concept __can_adjacent_transform_view
5805 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5806 (std::declval<_Range>(), std::declval<_Fp>()); };
5809 template<size_t _Nm>
5810 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5812 template<viewable_range _Range, typename _Fp>
5813 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5815 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
5817 if constexpr (_Nm == 0)
5818 return zip_transform(std::forward<_Fp>(__f));
5820 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5821 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5824 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5825 static constexpr int _S_arity = 2;
5826 static constexpr bool _S_has_simple_extra_args = true;
5829 template<size_t _Nm>
5830 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
5832 inline constexpr auto pairwise_transform = adjacent_transform<2>;
5835#define __cpp_lib_ranges_chunk 202202L
5839 template<typename _Tp>
5840 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
5842 _Tp __r = __num / __denom;
5843 if (__num % __denom)
5850 requires input_range<_Vp>
5851 class chunk_view : public view_interface<chunk_view<_Vp>>
5854 range_difference_t<_Vp> _M_n;
5855 range_difference_t<_Vp> _M_remainder = 0;
5856 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
5863 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
5864 : _M_base(std::move(__base)), _M_n(__n)
5865 { __glibcxx_assert(__n >= 0); }
5868 base() const & requires copy_constructible<_Vp>
5873 { return std::move(_M_base); }
5875 constexpr _OuterIter
5878 _M_current = ranges::begin(_M_base);
5879 _M_remainder = _M_n;
5880 return _OuterIter(*this);
5883 constexpr default_sentinel_t
5884 end() const noexcept
5885 { return default_sentinel; }
5888 size() requires sized_range<_Vp>
5890 return __detail::__to_unsigned_like(__detail::__div_ceil
5891 (ranges::distance(_M_base), _M_n));
5895 size() const requires sized_range<const _Vp>
5897 return __detail::__to_unsigned_like(__detail::__div_ceil
5898 (ranges::distance(_M_base), _M_n));
5902 template<typename _Range>
5903 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
5906 requires input_range<_Vp>
5907 class chunk_view<_Vp>::_OuterIter
5909 chunk_view* _M_parent;
5912 _OuterIter(chunk_view& __parent) noexcept
5913 : _M_parent(std::__addressof(__parent))
5919 using iterator_concept = input_iterator_tag;
5920 using difference_type = range_difference_t<_Vp>;
5924 _OuterIter(_OuterIter&&) = default;
5925 _OuterIter& operator=(_OuterIter&&) = default;
5927 constexpr value_type
5930 __glibcxx_assert(*this != default_sentinel);
5931 return value_type(*_M_parent);
5934 constexpr _OuterIter&
5937 __glibcxx_assert(*this != default_sentinel);
5938 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
5939 ranges::end(_M_parent->_M_base));
5940 _M_parent->_M_remainder = _M_parent->_M_n;
5948 friend constexpr bool
5949 operator==(const _OuterIter& __x, default_sentinel_t)
5951 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
5952 && __x._M_parent->_M_remainder != 0;
5955 friend constexpr difference_type
5956 operator-(default_sentinel_t, const _OuterIter& __x)
5957 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5959 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
5961 if (__dist < __x._M_parent->_M_remainder)
5962 return __dist == 0 ? 0 : 1;
5964 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
5965 __x._M_parent->_M_n);
5968 friend constexpr difference_type
5969 operator-(const _OuterIter& __x, default_sentinel_t __y)
5970 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5971 { return -(__y - __x); }
5975 requires input_range<_Vp>
5976 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
5979 chunk_view* _M_parent;
5982 value_type(chunk_view& __parent) noexcept
5983 : _M_parent(std::__addressof(__parent))
5989 constexpr _InnerIter
5990 begin() const noexcept
5991 { return _InnerIter(*_M_parent); }
5993 constexpr default_sentinel_t
5994 end() const noexcept
5995 { return default_sentinel; }
5999 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6001 return __detail::__to_unsigned_like
6002 (ranges::min(_M_parent->_M_remainder,
6003 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6008 requires input_range<_Vp>
6009 class chunk_view<_Vp>::_InnerIter
6011 chunk_view* _M_parent;
6014 _InnerIter(chunk_view& __parent) noexcept
6015 : _M_parent(std::__addressof(__parent))
6018 friend _OuterIter::value_type;
6021 using iterator_concept = input_iterator_tag;
6022 using difference_type = range_difference_t<_Vp>;
6023 using value_type = range_value_t<_Vp>;
6025 _InnerIter(_InnerIter&&) = default;
6026 _InnerIter& operator=(_InnerIter&&) = default;
6028 constexpr const iterator_t<_Vp>&
6030 { return *_M_parent->_M_current; }
6032 constexpr range_reference_t<_Vp>
6035 __glibcxx_assert(*this != default_sentinel);
6036 return **_M_parent->_M_current;
6039 constexpr _InnerIter&
6042 __glibcxx_assert(*this != default_sentinel);
6043 ++*_M_parent->_M_current;
6044 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6045 _M_parent->_M_remainder = 0;
6047 --_M_parent->_M_remainder;
6055 friend constexpr bool
6056 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6057 { return __x._M_parent->_M_remainder == 0; }
6059 friend constexpr difference_type
6060 operator-(default_sentinel_t, const _InnerIter& __x)
6061 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6063 return ranges::min(__x._M_parent->_M_remainder,
6064 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6067 friend constexpr difference_type
6068 operator-(const _InnerIter& __x, default_sentinel_t __y)
6069 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6070 { return -(__y - __x); }
6074 requires forward_range<_Vp>
6075 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6078 range_difference_t<_Vp> _M_n;
6079 template<bool> class _Iterator;
6083 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6084 : _M_base(std::move(__base)), _M_n(__n)
6085 { __glibcxx_assert(__n > 0); }
6088 base() const & requires copy_constructible<_Vp>
6093 { return std::move(_M_base); }
6096 begin() requires (!__detail::__simple_view<_Vp>)
6097 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6100 begin() const requires forward_range<const _Vp>
6101 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6104 end() requires (!__detail::__simple_view<_Vp>)
6106 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6108 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6109 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6111 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6112 return _Iterator<false>(this, ranges::end(_M_base));
6114 return default_sentinel;
6118 end() const requires forward_range<const _Vp>
6120 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6122 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6123 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6125 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6126 return _Iterator<true>(this, ranges::end(_M_base));
6128 return default_sentinel;
6132 size() requires sized_range<_Vp>
6134 return __detail::__to_unsigned_like(__detail::__div_ceil
6135 (ranges::distance(_M_base), _M_n));
6139 size() const requires sized_range<const _Vp>
6141 return __detail::__to_unsigned_like(__detail::__div_ceil
6142 (ranges::distance(_M_base), _M_n));
6146 template<typename _Vp>
6147 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6148 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6151 requires forward_range<_Vp>
6152 template<bool _Const>
6153 class chunk_view<_Vp>::_Iterator
6155 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6156 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6158 iterator_t<_Base> _M_current = iterator_t<_Base>();
6159 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6160 range_difference_t<_Base> _M_n = 0;
6161 range_difference_t<_Base> _M_missing = 0;
6164 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6165 range_difference_t<_Base> __missing = 0)
6166 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6167 _M_n(__parent->_M_n), _M_missing(__missing)
6173 if constexpr (random_access_range<_Base>)
6174 return random_access_iterator_tag{};
6175 else if constexpr (bidirectional_range<_Base>)
6176 return bidirectional_iterator_tag{};
6178 return forward_iterator_tag{};
6184 using iterator_category = input_iterator_tag;
6185 using iterator_concept = decltype(_S_iter_cat());
6186 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6187 using difference_type = range_difference_t<_Base>;
6189 _Iterator() = default;
6191 constexpr _Iterator(_Iterator<!_Const> __i)
6193 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6194 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6195 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6196 _M_n(__i._M_n), _M_missing(__i._M_missing)
6199 constexpr iterator_t<_Base>
6201 { return _M_current; }
6203 constexpr value_type
6206 __glibcxx_assert(_M_current != _M_end);
6207 return views::take(subrange(_M_current, _M_end), _M_n);
6210 constexpr _Iterator&
6213 __glibcxx_assert(_M_current != _M_end);
6214 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6226 constexpr _Iterator&
6227 operator--() requires bidirectional_range<_Base>
6229 ranges::advance(_M_current, _M_missing - _M_n);
6235 operator--(int) requires bidirectional_range<_Base>
6242 constexpr _Iterator&
6243 operator+=(difference_type __x)
6244 requires random_access_range<_Base>
6248 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6249 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6253 ranges::advance(_M_current, _M_n * __x + _M_missing);
6259 constexpr _Iterator&
6260 operator-=(difference_type __x)
6261 requires random_access_range<_Base>
6262 { return *this += -__x; }
6264 constexpr value_type
6265 operator[](difference_type __n) const
6266 requires random_access_range<_Base>
6267 { return *(*this + __n); }
6269 friend constexpr bool
6270 operator==(const _Iterator& __x, const _Iterator& __y)
6271 { return __x._M_current == __y._M_current; }
6273 friend constexpr bool
6274 operator==(const _Iterator& __x, default_sentinel_t)
6275 { return __x._M_current == __x._M_end; }
6277 friend constexpr bool
6278 operator<(const _Iterator& __x, const _Iterator& __y)
6279 requires random_access_range<_Base>
6280 { return __x._M_current > __y._M_current; }
6282 friend constexpr bool
6283 operator>(const _Iterator& __x, const _Iterator& __y)
6284 requires random_access_range<_Base>
6285 { return __y < __x; }
6287 friend constexpr bool
6288 operator<=(const _Iterator& __x, const _Iterator& __y)
6289 requires random_access_range<_Base>
6290 { return !(__y < __x); }
6292 friend constexpr bool
6293 operator>=(const _Iterator& __x, const _Iterator& __y)
6294 requires random_access_range<_Base>
6295 { return !(__x < __y); }
6297 friend constexpr auto
6298 operator<=>(const _Iterator& __x, const _Iterator& __y)
6299 requires random_access_range<_Base>
6300 && three_way_comparable<iterator_t<_Base>>
6301 { return __x._M_current <=> __y._M_current; }
6303 friend constexpr _Iterator
6304 operator+(const _Iterator& __i, difference_type __n)
6305 requires random_access_range<_Base>
6312 friend constexpr _Iterator
6313 operator+(difference_type __n, const _Iterator& __i)
6314 requires random_access_range<_Base>
6321 friend constexpr _Iterator
6322 operator-(const _Iterator& __i, difference_type __n)
6323 requires random_access_range<_Base>
6330 friend constexpr difference_type
6331 operator-(const _Iterator& __x, const _Iterator& __y)
6332 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6334 return (__x._M_current - __y._M_current
6335 + __x._M_missing - __y._M_missing) / __x._M_n;
6338 friend constexpr difference_type
6339 operator-(default_sentinel_t __y, const _Iterator& __x)
6340 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6341 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6343 friend constexpr difference_type
6344 operator-(const _Iterator& __x, default_sentinel_t __y)
6345 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6346 { return -(__y - __x); }
6353 template<typename _Range, typename _Dp>
6354 concept __can_chunk_view
6355 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6358 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6360 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6361 requires __detail::__can_chunk_view<_Range, _Dp>
6363 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6364 { return chunk_view(std::forward<_Range>(__r), __n); }
6366 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6367 static constexpr int _S_arity = 2;
6368 static constexpr bool _S_has_simple_extra_args = true;
6371 inline constexpr _Chunk chunk;
6374#define __cpp_lib_ranges_slide 202202L
6378 template<typename _Vp>
6379 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6381 template<typename _Vp>
6382 concept __slide_caches_last
6383 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6385 template<typename _Vp>
6386 concept __slide_caches_first
6387 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6390 template<forward_range _Vp>
6392 class slide_view : public view_interface<slide_view<_Vp>>
6395 range_difference_t<_Vp> _M_n;
6396 [[no_unique_address]]
6397 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6398 __detail::_CachedPosition<_Vp>> _M_cached_begin;
6399 [[no_unique_address]]
6400 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6401 __detail::_CachedPosition<_Vp>> _M_cached_end;
6403 template<bool> class _Iterator;
6408 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6409 : _M_base(std::move(__base)), _M_n(__n)
6410 { __glibcxx_assert(__n > 0); }
6413 begin() requires (!(__detail::__simple_view<_Vp>
6414 && __detail::__slide_caches_nothing<const _Vp>))
6416 if constexpr (__detail::__slide_caches_first<_Vp>)
6418 iterator_t<_Vp> __it;
6419 if (_M_cached_begin._M_has_value())
6420 __it = _M_cached_begin._M_get(_M_base);
6423 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6424 _M_cached_begin._M_set(_M_base, __it);
6426 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6429 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6433 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6434 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6437 end() requires (!(__detail::__simple_view<_Vp>
6438 && __detail::__slide_caches_nothing<const _Vp>))
6440 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6441 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6443 else if constexpr (__detail::__slide_caches_last<_Vp>)
6445 iterator_t<_Vp> __it;
6446 if (_M_cached_end._M_has_value())
6447 __it = _M_cached_end._M_get(_M_base);
6450 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6451 _M_cached_end._M_set(_M_base, __it);
6453 return _Iterator<false>(std::move(__it), _M_n);
6455 else if constexpr (common_range<_Vp>)
6456 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6458 return _Sentinel(ranges::end(_M_base));
6462 end() const requires __detail::__slide_caches_nothing<const _Vp>
6463 { return begin() + range_difference_t<const _Vp>(size()); }
6466 size() requires sized_range<_Vp>
6468 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6471 return __detail::__to_unsigned_like(__sz);
6475 size() const requires sized_range<const _Vp>
6477 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6480 return __detail::__to_unsigned_like(__sz);
6484 template<typename _Range>
6485 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6487 template<typename _Vp>
6488 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6489 = enable_borrowed_range<_Vp>;
6491 template<forward_range _Vp>
6493 template<bool _Const>
6494 class slide_view<_Vp>::_Iterator
6496 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6497 static constexpr bool _S_last_elt_present
6498 = __detail::__slide_caches_first<_Base>;
6500 iterator_t<_Base> _M_current = iterator_t<_Base>();
6501 [[no_unique_address]]
6502 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6503 _M_last_elt = decltype(_M_last_elt)();
6504 range_difference_t<_Base> _M_n = 0;
6507 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6508 requires (!_S_last_elt_present)
6509 : _M_current(__current), _M_n(__n)
6513 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6514 range_difference_t<_Base> __n)
6515 requires _S_last_elt_present
6516 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6522 if constexpr (random_access_range<_Base>)
6523 return random_access_iterator_tag{};
6524 else if constexpr (bidirectional_range<_Base>)
6525 return bidirectional_iterator_tag{};
6527 return forward_iterator_tag{};
6531 friend slide_view::_Sentinel;
6534 using iterator_category = input_iterator_tag;
6535 using iterator_concept = decltype(_S_iter_concept());
6536 using value_type = decltype(views::counted(_M_current, _M_n));
6537 using difference_type = range_difference_t<_Base>;
6539 _Iterator() = default;
6542 _Iterator(_Iterator<!_Const> __i)
6543 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6544 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6549 { return views::counted(_M_current, _M_n); }
6551 constexpr _Iterator&
6555 if constexpr (_S_last_elt_present)
6568 constexpr _Iterator&
6569 operator--() requires bidirectional_range<_Base>
6572 if constexpr (_S_last_elt_present)
6578 operator--(int) requires bidirectional_range<_Base>
6585 constexpr _Iterator&
6586 operator+=(difference_type __x)
6587 requires random_access_range<_Base>
6590 if constexpr (_S_last_elt_present)
6595 constexpr _Iterator&
6596 operator-=(difference_type __x)
6597 requires random_access_range<_Base>
6600 if constexpr (_S_last_elt_present)
6606 operator[](difference_type __n) const
6607 requires random_access_range<_Base>
6608 { return views::counted(_M_current + __n, _M_n); }
6610 friend constexpr bool
6611 operator==(const _Iterator& __x, const _Iterator& __y)
6613 if constexpr (_S_last_elt_present)
6614 return __x._M_last_elt == __y._M_last_elt;
6616 return __x._M_current == __y._M_current;
6619 friend constexpr bool
6620 operator<(const _Iterator& __x, const _Iterator& __y)
6621 requires random_access_range<_Base>
6622 { return __x._M_current < __y._M_current; }
6624 friend constexpr bool
6625 operator>(const _Iterator& __x, const _Iterator& __y)
6626 requires random_access_range<_Base>
6627 { return __y < __x; }
6629 friend constexpr bool
6630 operator<=(const _Iterator& __x, const _Iterator& __y)
6631 requires random_access_range<_Base>
6632 { return !(__y < __x); }
6634 friend constexpr bool
6635 operator>=(const _Iterator& __x, const _Iterator& __y)
6636 requires random_access_range<_Base>
6637 { return !(__x < __y); }
6639 friend constexpr auto
6640 operator<=>(const _Iterator& __x, const _Iterator& __y)
6641 requires random_access_range<_Base>
6642 && three_way_comparable<iterator_t<_Base>>
6643 { return __x._M_current <=> __y._M_current; }
6645 friend constexpr _Iterator
6646 operator+(const _Iterator& __i, difference_type __n)
6647 requires random_access_range<_Base>
6654 friend constexpr _Iterator
6655 operator+(difference_type __n, const _Iterator& __i)
6656 requires random_access_range<_Base>
6663 friend constexpr _Iterator
6664 operator-(const _Iterator& __i, difference_type __n)
6665 requires random_access_range<_Base>
6672 friend constexpr difference_type
6673 operator-(const _Iterator& __x, const _Iterator& __y)
6674 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6676 if constexpr (_S_last_elt_present)
6677 return __x._M_last_elt - __y._M_last_elt;
6679 return __x._M_current - __y._M_current;
6683 template<forward_range _Vp>
6685 class slide_view<_Vp>::_Sentinel
6687 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6690 _Sentinel(sentinel_t<_Vp> __end)
6697 _Sentinel() = default;
6699 friend constexpr bool
6700 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6701 { return __x._M_last_elt == __y._M_end; }
6703 friend constexpr range_difference_t<_Vp>
6704 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6705 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6706 { return __x._M_last_elt - __y._M_end; }
6708 friend constexpr range_difference_t<_Vp>
6709 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6710 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6711 { return __y._M_end -__x._M_last_elt; }
6718 template<typename _Range, typename _Dp>
6719 concept __can_slide_view
6720 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6723 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6725 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6726 requires __detail::__can_slide_view<_Range, _Dp>
6728 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6729 { return slide_view(std::forward<_Range>(__r), __n); }
6731 using __adaptor::_RangeAdaptor<_Slide>::operator();
6732 static constexpr int _S_arity = 2;
6733 static constexpr bool _S_has_simple_extra_args = true;
6736 inline constexpr _Slide slide;
6739#define __cpp_lib_ranges_chunk_by 202202L
6741 template<forward_range _Vp,
6742 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6743 requires view<_Vp> && is_object_v<_Pred>
6744 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6746 _Vp _M_base = _Vp();
6747 __detail::__box<_Pred> _M_pred;
6748 __detail::_CachedPosition<_Vp> _M_cached_begin;
6750 constexpr iterator_t<_Vp>
6751 _M_find_next(iterator_t<_Vp> __current)
6753 __glibcxx_assert(_M_pred.has_value());
6754 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6755 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6757 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6758 return ranges::next(__it, 1, ranges::end(_M_base));
6761 constexpr iterator_t<_Vp>
6762 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6764 __glibcxx_assert(_M_pred.has_value());
6765 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6766 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6768 auto __rbegin = std::make_reverse_iterator(__current);
6769 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6770 __glibcxx_assert(__rbegin != __rend);
6771 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6772 return ranges::prev(__it, 1, ranges::begin(_M_base));
6778 chunk_by_view() requires (default_initializable<_Vp>
6779 && default_initializable<_Pred>)
6783 chunk_by_view(_Vp __base, _Pred __pred)
6784 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
6788 base() const & requires copy_constructible<_Vp>
6793 { return std::move(_M_base); }
6795 constexpr const _Pred&
6797 { return *_M_pred; }
6802 __glibcxx_assert(_M_pred.has_value());
6803 iterator_t<_Vp> __it;
6804 if (_M_cached_begin._M_has_value())
6805 __it = _M_cached_begin._M_get(_M_base);
6808 __it = _M_find_next(ranges::begin(_M_base));
6809 _M_cached_begin._M_set(_M_base, __it);
6811 return _Iterator(*this, ranges::begin(_M_base), __it);
6817 if constexpr (common_range<_Vp>)
6818 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
6820 return default_sentinel;
6824 template<typename _Range, typename _Pred>
6825 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6827 template<forward_range _Vp,
6828 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6829 requires view<_Vp> && is_object_v<_Pred>
6830 class chunk_by_view<_Vp, _Pred>::_Iterator
6832 chunk_by_view* _M_parent = nullptr;
6833 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
6834 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
6837 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
6838 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
6844 if constexpr (bidirectional_range<_Vp>)
6845 return bidirectional_iterator_tag{};
6847 return forward_iterator_tag{};
6850 friend chunk_by_view;
6853 using value_type = subrange<iterator_t<_Vp>>;
6854 using difference_type = range_difference_t<_Vp>;
6855 using iterator_category = input_iterator_tag;
6856 using iterator_concept = decltype(_S_iter_concept());
6858 _Iterator() = default;
6860 constexpr value_type
6863 __glibcxx_assert(_M_current != _M_next);
6864 return ranges::subrange(_M_current, _M_next);
6867 constexpr _Iterator&
6870 __glibcxx_assert(_M_current != _M_next);
6871 _M_current = _M_next;
6872 _M_next = _M_parent->_M_find_next(_M_current);
6884 constexpr _Iterator&
6885 operator--() requires bidirectional_range<_Vp>
6887 _M_next = _M_current;
6888 _M_current = _M_parent->_M_find_prev(_M_next);
6893 operator--(int) requires bidirectional_range<_Vp>
6900 friend constexpr bool
6901 operator==(const _Iterator& __x, const _Iterator& __y)
6902 { return __x._M_current == __y._M_current; }
6904 friend constexpr bool
6905 operator==(const _Iterator& __x, default_sentinel_t)
6906 { return __x._M_current == __x._M_next; }
6913 template<typename _Range, typename _Pred>
6914 concept __can_chunk_by_view
6915 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
6918 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
6920 template<viewable_range _Range, typename _Pred>
6921 requires __detail::__can_chunk_by_view<_Range, _Pred>
6923 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
6924 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
6926 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
6927 static constexpr int _S_arity = 2;
6928 static constexpr bool _S_has_simple_extra_args = true;
6931 inline constexpr _ChunkBy chunk_by;
6934#define __cpp_lib_ranges_join_with 202202L
6938 template<typename _Range, typename _Pattern>
6939 concept __compatible_joinable_ranges
6940 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
6941 && common_reference_with<range_reference_t<_Range>,
6942 range_reference_t<_Pattern>>
6943 && common_reference_with<range_rvalue_reference_t<_Range>,
6944 range_rvalue_reference_t<_Pattern>>;
6946 template<typename _Range>
6947 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
6950 template<input_range _Vp, forward_range _Pattern>
6951 requires view<_Vp> && view<_Pattern>
6952 && input_range<range_reference_t<_Vp>>
6953 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
6954 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
6956 using _InnerRange = range_reference_t<_Vp>;
6958 _Vp _M_base = _Vp();
6959 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
6960 _Pattern _M_pattern = _Pattern();
6962 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6963 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
6964 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
6966 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
6967 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
6968 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
6970 template<bool _Const>
6971 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
6973 template<bool _Const>
6977 template<bool _Const>
6978 requires _S_ref_is_glvalue<_Const>
6979 && forward_range<_Base<_Const>>
6980 && forward_range<_InnerBase<_Const>>
6981 struct __iter_cat<_Const>
6987 using _OuterIter = join_with_view::_OuterIter<_Const>;
6988 using _InnerIter = join_with_view::_InnerIter<_Const>;
6989 using _PatternIter = join_with_view::_PatternIter<_Const>;
6990 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
6991 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
6992 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
6993 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
6994 iter_reference_t<_PatternIter>>>)
6995 return input_iterator_tag{};
6996 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
6997 && derived_from<_InnerCat, bidirectional_iterator_tag>
6998 && derived_from<_PatternCat, bidirectional_iterator_tag>
6999 && common_range<_InnerBase<_Const>>
7000 && common_range<_PatternBase<_Const>>)
7001 return bidirectional_iterator_tag{};
7002 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7003 && derived_from<_InnerCat, forward_iterator_tag>
7004 && derived_from<_PatternCat, forward_iterator_tag>)
7005 return forward_iterator_tag{};
7007 return input_iterator_tag{};
7010 using iterator_category = decltype(_S_iter_cat());
7013 template<bool> struct _Iterator;
7014 template<bool> struct _Sentinel;
7017 join_with_view() requires (default_initializable<_Vp>
7018 && default_initializable<_Pattern>)
7022 join_with_view(_Vp __base, _Pattern __pattern)
7023 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7026 template<input_range _Range>
7027 requires constructible_from<_Vp, views::all_t<_Range>>
7028 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7030 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7031 : _M_base(views::all(std::forward<_Range>(__r))),
7032 _M_pattern(views::single(std::move(__e)))
7036 base() const& requires copy_constructible<_Vp>
7041 { return std::move(_M_base); }
7046 constexpr bool __use_const = is_reference_v<_InnerRange>
7047 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7048 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7053 requires input_range<const _Vp>
7054 && forward_range<const _Pattern>
7055 && is_reference_v<range_reference_t<const _Vp>>
7056 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7061 constexpr bool __use_const
7062 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7063 if constexpr (is_reference_v<_InnerRange>
7064 && forward_range<_Vp> && common_range<_Vp>
7065 && forward_range<_InnerRange> && common_range<_InnerRange>)
7066 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7068 return _Sentinel<__use_const>{*this};
7073 requires input_range<const _Vp>
7074 && forward_range<const _Pattern>
7075 && is_reference_v<range_reference_t<const _Vp>>
7077 using _InnerConstRange = range_reference_t<const _Vp>;
7078 if constexpr (forward_range<const _Vp>
7079 && forward_range<_InnerConstRange>
7080 && common_range<const _Vp>
7081 && common_range<_InnerConstRange>)
7082 return _Iterator<true>{*this, ranges::end(_M_base)};
7084 return _Sentinel<true>{*this};
7088 template<typename _Range, typename _Pattern>
7089 join_with_view(_Range&&, _Pattern&&)
7090 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7092 template<input_range _Range>
7093 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7094 -> join_with_view<views::all_t<_Range>,
7095 single_view<range_value_t<range_reference_t<_Range>>>>;
7097 template<input_range _Vp, forward_range _Pattern>
7098 requires view<_Vp> && view<_Pattern>
7099 && input_range<range_reference_t<_Vp>>
7100 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7101 template<bool _Const>
7102 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7104 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7105 using _Base = join_with_view::_Base<_Const>;
7106 using _InnerBase = join_with_view::_InnerBase<_Const>;
7107 using _PatternBase = join_with_view::_PatternBase<_Const>;
7109 using _OuterIter = join_with_view::_OuterIter<_Const>;
7110 using _InnerIter = join_with_view::_InnerIter<_Const>;
7111 using _PatternIter = join_with_view::_PatternIter<_Const>;
7113 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7115 _Parent* _M_parent = nullptr;
7116 _OuterIter _M_outer_it = _OuterIter();
7117 variant<_PatternIter, _InnerIter> _M_inner_it;
7120 _Iterator(_Parent& __parent, iterator_t<_Base> __outer)
7121 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7123 if (_M_outer_it != ranges::end(_M_parent->_M_base))
7125 auto&& __inner = _M_update_inner(_M_outer_it);
7126 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7132 _M_update_inner(const _OuterIter& __x)
7134 if constexpr (_S_ref_is_glvalue)
7137 return _M_parent->_M_inner._M_emplace_deref(__x);
7141 _M_get_inner(const _OuterIter& __x)
7143 if constexpr (_S_ref_is_glvalue)
7146 return *_M_parent->_M_inner;
7154 if (_M_inner_it.index() == 0)
7156 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7159 auto&& __inner = _M_update_inner(_M_outer_it);
7160 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7164 auto&& __inner = _M_get_inner(_M_outer_it);
7165 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7168 if (++_M_outer_it == ranges::end(_M_parent->_M_base))
7170 if constexpr (_S_ref_is_glvalue)
7171 _M_inner_it.template emplace<0>();
7175 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7183 if constexpr (_S_ref_is_glvalue
7184 && bidirectional_range<_Base>
7185 && __detail::__bidirectional_common<_InnerBase>
7186 && __detail::__bidirectional_common<_PatternBase>)
7187 return bidirectional_iterator_tag{};
7188 else if constexpr (_S_ref_is_glvalue
7189 && forward_range<_Base>
7190 && forward_range<_InnerBase>)
7191 return forward_iterator_tag{};
7193 return input_iterator_tag{};
7196 friend join_with_view;
7199 using iterator_concept = decltype(_S_iter_concept());
7200 // iterator_category defined in join_with_view::__iter_cat
7201 using value_type = common_type_t<iter_value_t<_InnerIter>,
7202 iter_value_t<_PatternIter>>;
7203 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7204 iter_difference_t<_InnerIter>,
7205 iter_difference_t<_PatternIter>>;
7207 _Iterator() requires default_initializable<_OuterIter> = default;
7210 _Iterator(_Iterator<!_Const> __i)
7212 && convertible_to<iterator_t<_Vp>, _OuterIter>
7213 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7214 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7215 : _M_parent(__i._M_parent),
7216 _M_outer_it(std::move(__i._M_outer_it))
7218 if (__i._M_inner_it.index() == 0)
7219 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7221 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7224 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7225 iter_reference_t<_PatternIter>>
7228 if (_M_inner_it.index() == 0)
7229 return *std::get<0>(_M_inner_it);
7231 return *std::get<1>(_M_inner_it);
7234 constexpr _Iterator&
7237 if (_M_inner_it.index() == 0)
7238 ++std::get<0>(_M_inner_it);
7240 ++std::get<1>(_M_inner_it);
7251 requires _S_ref_is_glvalue
7252 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7254 _Iterator __tmp = *this;
7259 constexpr _Iterator&
7261 requires _S_ref_is_glvalue
7262 && bidirectional_range<_Base>
7263 && __detail::__bidirectional_common<_InnerBase>
7264 && __detail::__bidirectional_common<_PatternBase>
7266 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7268 auto&& __inner = *--_M_outer_it;
7269 _M_inner_it.template emplace<1>(ranges::end(__inner));
7274 if (_M_inner_it.index() == 0)
7276 auto& __it = std::get<0>(_M_inner_it);
7277 if (__it == ranges::begin(_M_parent->_M_pattern))
7279 auto&& __inner = *--_M_outer_it;
7280 _M_inner_it.template emplace<1>(ranges::end(__inner));
7287 auto& __it = std::get<1>(_M_inner_it);
7288 auto&& __inner = *_M_outer_it;
7289 if (__it == ranges::begin(__inner))
7290 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7296 if (_M_inner_it.index() == 0)
7297 --std::get<0>(_M_inner_it);
7299 --std::get<1>(_M_inner_it);
7305 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7306 && __detail::__bidirectional_common<_InnerBase>
7307 && __detail::__bidirectional_common<_PatternBase>
7309 _Iterator __tmp = *this;
7314 friend constexpr bool
7315 operator==(const _Iterator& __x, const _Iterator& __y)
7316 requires _S_ref_is_glvalue
7317 && equality_comparable<_OuterIter> && equality_comparable<_InnerIter>
7318 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7320 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7321 iter_rvalue_reference_t<_PatternIter>>
7322 iter_move(const _Iterator& __x)
7324 if (__x._M_inner_it.index() == 0)
7325 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7327 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7330 friend constexpr void
7331 iter_swap(const _Iterator& __x, const _Iterator& __y)
7332 requires indirectly_swappable<_InnerIter, _PatternIter>
7334 if (__x._M_inner_it.index() == 0)
7336 if (__y._M_inner_it.index() == 0)
7337 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7339 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7343 if (__y._M_inner_it.index() == 0)
7344 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7346 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7351 template<input_range _Vp, forward_range _Pattern>
7352 requires view<_Vp> && view<_Pattern>
7353 && input_range<range_reference_t<_Vp>>
7354 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7355 template<bool _Const>
7356 class join_with_view<_Vp, _Pattern>::_Sentinel
7358 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7359 using _Base = join_with_view::_Base<_Const>;
7361 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7364 _Sentinel(_Parent& __parent)
7365 : _M_end(ranges::end(__parent._M_base))
7368 friend join_with_view;
7371 _Sentinel() = default;
7374 _Sentinel(_Sentinel<!_Const> __s)
7375 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7376 : _M_end(std::move(__s._M_end))
7379 template<bool _OtherConst>
7380 requires sentinel_for<sentinel_t<_Base>,
7381 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7382 friend constexpr bool
7383 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7384 { return __x._M_outer_it == __y._M_end; }
7391 template<typename _Range, typename _Pattern>
7392 concept __can_join_with_view
7393 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7394 } // namespace __detail
7396 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7398 template<viewable_range _Range, typename _Pattern>
7399 requires __detail::__can_join_with_view<_Range, _Pattern>
7401 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7403 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7406 using _RangeAdaptor<_JoinWith>::operator();
7407 static constexpr int _S_arity = 2;
7408 template<typename _Pattern>
7409 static constexpr bool _S_has_simple_extra_args
7410 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7413 inline constexpr _JoinWith join_with;
7414 } // namespace views
7416#define __cpp_lib_ranges_repeat 202207L
7418 template<copy_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7419 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7420 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7421 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7423 __detail::__box<_Tp> _M_value;
7424 [[no_unique_address]] _Bound _M_bound = _Bound();
7428 template<typename _Range>
7429 friend constexpr auto
7430 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7432 template<typename _Range>
7433 friend constexpr auto
7434 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7437 repeat_view() requires default_initializable<_Tp> = default;
7440 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7441 : _M_value(__value), _M_bound(__bound)
7443 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7444 __glibcxx_assert(__bound >= 0);
7448 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7449 : _M_value(std::move(__value)), _M_bound(__bound)
7452 template<typename... _Args, typename... _BoundArgs>
7453 requires constructible_from<_Tp, _Args...>
7454 && constructible_from<_Bound, _BoundArgs...>
7456 repeat_view(piecewise_construct_t,
7457 tuple<_Args...> __args,
7458 tuple<_BoundArgs...> __bound_args = tuple<>{})
7459 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7460 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7465 { return _Iterator(std::__addressof(*_M_value)); }
7468 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7469 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7471 constexpr unreachable_sentinel_t
7472 end() const noexcept
7473 { return unreachable_sentinel; }
7476 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7477 { return __detail::__to_unsigned_like(_M_bound); }
7480 template<typename _Tp, typename _Bound>
7481 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7483 template<copy_constructible _Tp, semiregular _Bound>
7484 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7485 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7486 class repeat_view<_Tp, _Bound>::_Iterator
7489 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7491 const _Tp* _M_value = nullptr;
7492 __index_type _M_current = __index_type();
7495 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7496 : _M_value(__value), _M_current(__bound)
7498 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7499 __glibcxx_assert(__bound >= 0);
7505 using iterator_concept = random_access_iterator_tag;
7506 using iterator_category = random_access_iterator_tag;
7507 using value_type = _Tp;
7508 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7510 __detail::__iota_diff_t<__index_type>>;
7512 _Iterator() = default;
7514 constexpr const _Tp&
7515 operator*() const noexcept
7516 { return *_M_value; }
7518 constexpr _Iterator&
7533 constexpr _Iterator&
7536 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7537 __glibcxx_assert(_M_current > 0);
7550 constexpr _Iterator&
7551 operator+=(difference_type __n)
7553 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7554 __glibcxx_assert(_M_current + __n >= 0);
7559 constexpr _Iterator&
7560 operator-=(difference_type __n)
7562 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7563 __glibcxx_assert(_M_current - __n >= 0);
7568 constexpr const _Tp&
7569 operator[](difference_type __n) const noexcept
7570 { return *(*this + __n); }
7572 friend constexpr bool
7573 operator==(const _Iterator& __x, const _Iterator& __y)
7574 { return __x._M_current == __y._M_current; }
7576 friend constexpr auto
7577 operator<=>(const _Iterator& __x, const _Iterator& __y)
7578 { return __x._M_current <=> __y._M_current; }
7580 friend constexpr _Iterator
7581 operator+(_Iterator __i, difference_type __n)
7587 friend constexpr _Iterator
7588 operator+(difference_type __n, _Iterator __i)
7589 { return __i + __n; }
7591 friend constexpr _Iterator
7592 operator-(_Iterator __i, difference_type __n)
7598 friend constexpr difference_type
7599 operator-(const _Iterator& __x, const _Iterator& __y)
7601 return (static_cast<difference_type>(__x._M_current)
7602 - static_cast<difference_type>(__y._M_current));
7610 template<typename _Tp, typename _Bound>
7611 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7613 template<typename _Tp>
7614 concept __can_repeat_view
7615 = requires { repeat_view(std::declval<_Tp>()); };
7617 template<typename _Tp, typename _Bound>
7618 concept __can_bounded_repeat_view
7619 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7624 template<typename _Tp>
7625 requires __detail::__can_repeat_view<_Tp>
7627 operator() [[nodiscard]] (_Tp&& __value) const
7628 { return repeat_view(std::forward<_Tp>(__value)); }
7630 template<typename _Tp, typename _Bound>
7631 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7633 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7634 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7637 inline constexpr _Repeat repeat;
7641 template<typename _Range>
7643 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7645 using _Tp = remove_cvref_t<_Range>;
7646 static_assert(__is_repeat_view<_Tp>);
7647 if constexpr (sized_range<_Tp>)
7648 return views::repeat(*__r._M_value, std::min(ranges::distance(__r), __n));
7650 return views::repeat(*__r._M_value, __n);
7653 template<typename _Range>
7655 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7657 using _Tp = remove_cvref_t<_Range>;
7658 static_assert(__is_repeat_view<_Tp>);
7659 if constexpr (sized_range<_Tp>)
7661 auto __sz = ranges::distance(__r);
7662 return views::repeat(*__r._M_value, __sz - std::min(__sz, __n));
7670#define __cpp_lib_ranges_stride 202207L
7672 template<input_range _Vp>
7674 class stride_view : public view_interface<stride_view<_Vp>>
7677 range_difference_t<_Vp> _M_stride;
7679 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7681 template<bool _Const>
7685 template<bool _Const>
7686 requires forward_range<_Base<_Const>>
7687 struct __iter_cat<_Const>
7693 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7694 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7695 return random_access_iterator_tag{};
7700 using iterator_category = decltype(_S_iter_cat());
7703 template<bool> class _Iterator;
7707 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7708 : _M_base(std::move(__base)), _M_stride(__stride)
7709 { __glibcxx_assert(__stride > 0); }
7712 base() const& requires copy_constructible<_Vp>
7717 { return std::move(_M_base); }
7719 constexpr range_difference_t<_Vp>
7720 stride() const noexcept
7721 { return _M_stride; }
7724 begin() requires (!__detail::__simple_view<_Vp>)
7725 { return _Iterator<false>(this, ranges::begin(_M_base)); }
7728 begin() const requires range<const _Vp>
7729 { return _Iterator<true>(this, ranges::begin(_M_base)); }
7732 end() requires (!__detail::__simple_view<_Vp>)
7734 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7736 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7737 return _Iterator<false>(this, ranges::end(_M_base), __missing);
7739 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7740 return _Iterator<false>(this, ranges::end(_M_base));
7742 return default_sentinel;
7746 end() const requires range<const _Vp>
7748 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7749 && forward_range<const _Vp>)
7751 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7752 return _Iterator<true>(this, ranges::end(_M_base), __missing);
7754 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7755 return _Iterator<true>(this, ranges::end(_M_base));
7757 return default_sentinel;
7761 size() requires sized_range<_Vp>
7763 return __detail::__to_unsigned_like
7764 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7768 size() const requires sized_range<const _Vp>
7770 return __detail::__to_unsigned_like
7771 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7775 template<typename _Range>
7776 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7778 template<typename _Vp>
7779 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7780 = enable_borrowed_range<_Vp>;
7782 template<input_range _Vp>
7784 template<bool _Const>
7785 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
7787 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
7788 using _Base = stride_view::_Base<_Const>;
7790 iterator_t<_Base> _M_current = iterator_t<_Base>();
7791 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7792 range_difference_t<_Base> _M_stride = 0;
7793 range_difference_t<_Base> _M_missing = 0;
7796 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
7797 range_difference_t<_Base> __missing = 0)
7798 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
7799 _M_stride(__parent->_M_stride), _M_missing(__missing)
7805 if constexpr (random_access_range<_Base>)
7806 return random_access_iterator_tag{};
7807 else if constexpr (bidirectional_range<_Base>)
7808 return bidirectional_iterator_tag{};
7809 else if constexpr (forward_range<_Base>)
7810 return forward_iterator_tag{};
7812 return input_iterator_tag{};
7818 using difference_type = range_difference_t<_Base>;
7819 using value_type = range_value_t<_Base>;
7820 using iterator_concept = decltype(_S_iter_concept());
7821 // iterator_category defined in stride_view::__iter_cat
7823 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
7826 _Iterator(_Iterator<!_Const> __other)
7828 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7829 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7830 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
7831 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
7834 constexpr iterator_t<_Base>
7836 { return std::move(_M_current); }
7838 constexpr const iterator_t<_Base>&
7839 base() const & noexcept
7840 { return _M_current; }
7842 constexpr decltype(auto)
7844 { return *_M_current; }
7846 constexpr _Iterator&
7849 __glibcxx_assert(_M_current != _M_end);
7850 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
7859 operator++(int) requires forward_range<_Base>
7866 constexpr _Iterator&
7867 operator--() requires bidirectional_range<_Base>
7869 ranges::advance(_M_current, _M_missing - _M_stride);
7875 operator--(int) requires bidirectional_range<_Base>
7882 constexpr _Iterator&
7883 operator+=(difference_type __n) requires random_access_range<_Base>
7887 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
7888 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
7892 ranges::advance(_M_current, _M_stride * __n + _M_missing);
7898 constexpr _Iterator&
7899 operator-=(difference_type __n) requires random_access_range<_Base>
7900 { return *this += -__n; }
7902 constexpr decltype(auto) operator[](difference_type __n) const
7903 requires random_access_range<_Base>
7904 { return *(*this + __n); }
7906 friend constexpr bool
7907 operator==(const _Iterator& __x, default_sentinel_t)
7908 { return __x._M_current == __x._M_end; }
7910 friend constexpr bool
7911 operator==(const _Iterator& __x, const _Iterator& __y)
7912 requires equality_comparable<iterator_t<_Base>>
7913 { return __x._M_current == __y._M_current; }
7915 friend constexpr bool
7916 operator<(const _Iterator& __x, const _Iterator& __y)
7917 requires random_access_range<_Base>
7918 { return __x._M_current < __y._M_current; }
7920 friend constexpr bool
7921 operator>(const _Iterator& __x, const _Iterator& __y)
7922 requires random_access_range<_Base>
7923 { return __y._M_current < __x._M_current; }
7925 friend constexpr bool
7926 operator<=(const _Iterator& __x, const _Iterator& __y)
7927 requires random_access_range<_Base>
7928 { return !(__y._M_current < __x._M_current); }
7930 friend constexpr bool
7931 operator>=(const _Iterator& __x, const _Iterator& __y)
7932 requires random_access_range<_Base>
7933 { return !(__x._M_current < __y._M_current); }
7935 friend constexpr auto
7936 operator<=>(const _Iterator& __x, const _Iterator& __y)
7937 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
7938 { return __x._M_current <=> __y._M_current; }
7940 friend constexpr _Iterator
7941 operator+(const _Iterator& __i, difference_type __n)
7942 requires random_access_range<_Base>
7949 friend constexpr _Iterator
7950 operator+(difference_type __n, const _Iterator& __i)
7951 requires random_access_range<_Base>
7952 { return __i + __n; }
7954 friend constexpr _Iterator
7955 operator-(const _Iterator& __i, difference_type __n)
7956 requires random_access_range<_Base>
7963 friend constexpr difference_type
7964 operator-(const _Iterator& __x, const _Iterator& __y)
7965 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7967 auto __n = __x._M_current - __y._M_current;
7968 if constexpr (forward_range<_Base>)
7969 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
7971 return -__detail::__div_ceil(-__n, __x._M_stride);
7973 return __detail::__div_ceil(__n, __x._M_stride);
7976 friend constexpr difference_type
7977 operator-(default_sentinel_t __y, const _Iterator& __x)
7978 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7979 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
7981 friend constexpr difference_type
7982 operator-(const _Iterator& __x, default_sentinel_t __y)
7983 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7984 { return -(__y - __x); }
7986 friend constexpr range_rvalue_reference_t<_Base>
7987 iter_move(const _Iterator& __i)
7988 noexcept(noexcept(ranges::iter_move(__i._M_current)))
7989 { return ranges::iter_move(__i._M_current); }
7991 friend constexpr void
7992 iter_swap(const _Iterator& __x, const _Iterator& __y)
7993 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
7994 requires indirectly_swappable<iterator_t<_Base>>
7995 { ranges::iter_swap(__x._M_current, __y._M_current); }
8002 template<typename _Range, typename _Dp>
8003 concept __can_stride_view
8004 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8007 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8009 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8010 requires __detail::__can_stride_view<_Range, _Dp>
8012 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8013 { return stride_view(std::forward<_Range>(__r), __n); }
8015 using __adaptor::_RangeAdaptor<_Stride>::operator();
8016 static constexpr int _S_arity = 2;
8017 static constexpr bool _S_has_simple_extra_args = true;
8020 inline constexpr _Stride stride;
8023#define __cpp_lib_ranges_cartesian_product 202207L
8027 template<bool _Const, typename _First, typename... _Vs>
8028 concept __cartesian_product_is_random_access
8029 = (random_access_range<__maybe_const_t<_Const, _First>>
8031 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8032 && sized_range<__maybe_const_t<_Const, _Vs>>));
8034 template<typename _Range>
8035 concept __cartesian_product_common_arg
8036 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8038 template<bool _Const, typename _First, typename... _Vs>
8039 concept __cartesian_product_is_bidirectional
8040 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8042 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8043 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8045 template<typename _First, typename... _Vs>
8046 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8048 template<typename... _Vs>
8049 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8051 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8052 concept __cartesian_is_sized_sentinel
8053 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8054 iterator_t<__maybe_const_t<_Const, _First>>>
8056 && (sized_range<__maybe_const_t<_Const, _Vs>>
8057 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8058 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8060 template<__cartesian_product_common_arg _Range>
8062 __cartesian_common_arg_end(_Range& __r)
8064 if constexpr (common_range<_Range>)
8065 return ranges::end(__r);
8067 return ranges::begin(__r) + ranges::distance(__r);
8069 } // namespace __detail
8071 template<input_range _First, forward_range... _Vs>
8072 requires (view<_First> && ... && view<_Vs>)
8073 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8075 tuple<_First, _Vs...> _M_bases;
8077 template<bool> class _Iterator;
8080 _S_difference_type()
8082 // TODO: Implement the recommended practice of using the smallest
8083 // sufficiently wide type according to the maximum sizes of the
8084 // underlying ranges?
8085 return common_type_t<ptrdiff_t,
8086 range_difference_t<_First>,
8087 range_difference_t<_Vs>...>{};
8091 cartesian_product_view() = default;
8094 cartesian_product_view(_First __first, _Vs... __rest)
8095 : _M_bases(std::move(__first), std::move(__rest)...)
8098 constexpr _Iterator<false>
8099 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8100 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8102 constexpr _Iterator<true>
8103 begin() const requires (range<const _First> && ... && range<const _Vs>)
8104 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8106 constexpr _Iterator<false>
8107 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8108 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8110 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8111 using _Ret = __detail::__tuple_or_pair_t<iterator_t<_First>,
8112 iterator_t<_Vs>...>;
8113 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8114 auto& __first = std::get<0>(_M_bases);
8115 return _Ret{(__empty_tail
8116 ? ranges::begin(__first)
8117 : __detail::__cartesian_common_arg_end(__first)),
8118 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8119 }(make_index_sequence<sizeof...(_Vs)>{});
8121 return _Iterator<false>{*this, std::move(__its)};
8124 constexpr _Iterator<true>
8125 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8127 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8128 using _Ret = __detail::__tuple_or_pair_t<iterator_t<const _First>,
8129 iterator_t<const _Vs>...>;
8130 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8131 auto& __first = std::get<0>(_M_bases);
8132 return _Ret{(__empty_tail
8133 ? ranges::begin(__first)
8134 : __detail::__cartesian_common_arg_end(__first)),
8135 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8136 }(make_index_sequence<sizeof...(_Vs)>{});
8138 return _Iterator<true>{*this, std::move(__its)};
8141 constexpr default_sentinel_t
8142 end() const noexcept
8143 { return default_sentinel; }
8146 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8148 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8149 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8150 auto __size = static_cast<_ST>(1);
8151#ifdef _GLIBCXX_ASSERTIONS
8152 if constexpr (integral<_ST>)
8155 = (__builtin_mul_overflow(__size,
8156 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8159 __glibcxx_assert(!__overflow);
8163 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8165 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8169 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8171 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8172 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8173 auto __size = static_cast<_ST>(1);
8174#ifdef _GLIBCXX_ASSERTIONS
8175 if constexpr (integral<_ST>)
8178 = (__builtin_mul_overflow(__size,
8179 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8182 __glibcxx_assert(!__overflow);
8186 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8188 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8192 template<typename... _Vs>
8193 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8195 template<input_range _First, forward_range... _Vs>
8196 requires (view<_First> && ... && view<_Vs>)
8197 template<bool _Const>
8198 class cartesian_product_view<_First, _Vs...>::_Iterator
8200 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8201 _Parent* _M_parent = nullptr;
8202 __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
8203 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8206 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8207 : _M_parent(std::__addressof(__parent)),
8208 _M_current(std::move(__current))
8214 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8215 return random_access_iterator_tag{};
8216 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8217 return bidirectional_iterator_tag{};
8218 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8219 return forward_iterator_tag{};
8221 return input_iterator_tag{};
8224 friend cartesian_product_view;
8227 using iterator_category = input_iterator_tag;
8228 using iterator_concept = decltype(_S_iter_concept());
8230 = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
8231 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8233 = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
8234 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8235 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8237 _Iterator() = default;
8240 _Iterator(_Iterator<!_Const> __i)
8242 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8243 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8244 : _M_parent(std::__addressof(__i._M_parent)),
8245 _M_current(std::move(__i._M_current))
8251 auto __f = [](auto& __i) -> decltype(auto) {
8254 return __detail::__tuple_transform(__f, _M_current);
8257 constexpr _Iterator&
8269 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8276 constexpr _Iterator&
8278 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8286 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8293 constexpr _Iterator&
8294 operator+=(difference_type __x)
8295 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8301 constexpr _Iterator&
8302 operator-=(difference_type __x)
8303 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8304 { return *this += -__x; }
8307 operator[](difference_type __n) const
8308 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8309 { return *((*this) + __n); }
8311 friend constexpr bool
8312 operator==(const _Iterator& __x, const _Iterator& __y)
8313 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8314 { return __x._M_current == __y._M_current; }
8316 friend constexpr bool
8317 operator==(const _Iterator& __x, default_sentinel_t)
8319 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8320 return ((std::get<_Is>(__x._M_current)
8321 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8323 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8326 friend constexpr auto
8327 operator<=>(const _Iterator& __x, const _Iterator& __y)
8328 requires __detail::__all_random_access<_Const, _First, _Vs...>
8329 { return __x._M_current <=> __y._M_current; }
8331 friend constexpr _Iterator
8332 operator+(_Iterator __x, difference_type __y)
8333 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8334 { return __x += __y; }
8336 friend constexpr _Iterator
8337 operator+(difference_type __x, _Iterator __y)
8338 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8339 { return __y += __x; }
8341 friend constexpr _Iterator
8342 operator-(_Iterator __x, difference_type __y)
8343 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8344 { return __x -= __y; }
8346 friend constexpr difference_type
8347 operator-(const _Iterator& __x, const _Iterator& __y)
8348 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8349 { return __x._M_distance_from(__y._M_current); }
8351 friend constexpr difference_type
8352 operator-(const _Iterator& __i, default_sentinel_t)
8353 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8355 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8356 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8357 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8358 }(make_index_sequence<sizeof...(_Vs)>{});
8359 return __i._M_distance_from(__end_tuple);
8362 friend constexpr difference_type
8363 operator-(default_sentinel_t, const _Iterator& __i)
8364 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8365 { return -(__i - default_sentinel); }
8367 friend constexpr auto
8368 iter_move(const _Iterator& __i)
8369 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8371 friend constexpr void
8372 iter_swap(const _Iterator& __l, const _Iterator& __r)
8373 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8375 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8377 [&]<size_t... _Is>(index_sequence<_Is...>) {
8378 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8379 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8383 template<size_t _Nm = sizeof...(_Vs)>
8387 auto& __it = std::get<_Nm>(_M_current);
8389 if constexpr (_Nm > 0)
8390 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8392 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8397 template<size_t _Nm = sizeof...(_Vs)>
8401 auto& __it = std::get<_Nm>(_M_current);
8402 if constexpr (_Nm > 0)
8403 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8405 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8411 template<size_t _Nm = sizeof...(_Vs)>
8413 _M_advance(difference_type __x)
8414 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8422 // Constant time iterator advancement.
8423 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8424 auto& __it = std::get<_Nm>(_M_current);
8425 if constexpr (_Nm == 0)
8427#ifdef _GLIBCXX_ASSERTIONS
8428 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8430 auto __size = ranges::ssize(__r);
8431 auto __begin = ranges::begin(__r);
8432 auto __offset = __it - __begin;
8433 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8440 auto __size = ranges::ssize(__r);
8441 auto __begin = ranges::begin(__r);
8442 auto __offset = __it - __begin;
8444 __x = __offset / __size;
8448 __offset = __size + __offset;
8451 __it = __begin + __offset;
8452 _M_advance<_Nm - 1>(__x);
8457 template<typename _Tuple>
8458 constexpr difference_type
8459 _M_distance_from(const _Tuple& __t) const
8461 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8462 auto __sum = static_cast<difference_type>(0);
8463#ifdef _GLIBCXX_ASSERTIONS
8464 if constexpr (integral<difference_type>)
8467 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8469 __glibcxx_assert(!__overflow);
8473 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8475 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8478 template<size_t _Nm, typename _Tuple>
8479 constexpr difference_type
8480 _M_scaled_distance(const _Tuple& __t) const
8482 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8483 - std::get<_Nm>(__t));
8484#ifdef _GLIBCXX_ASSERTIONS
8485 if constexpr (integral<difference_type>)
8487 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8488 __glibcxx_assert(!__overflow);
8492 __dist *= _M_scaled_size<_Nm+1>();
8496 template<size_t _Nm>
8497 constexpr difference_type
8498 _M_scaled_size() const
8500 if constexpr (_Nm <= sizeof...(_Vs))
8502 auto __size = static_cast<difference_type>(ranges::size
8503 (std::get<_Nm>(_M_parent->_M_bases)));
8504#ifdef _GLIBCXX_ASSERTIONS
8505 if constexpr (integral<difference_type>)
8507 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8508 __glibcxx_assert(!__overflow);
8512 __size *= _M_scaled_size<_Nm+1>();
8516 return static_cast<difference_type>(1);
8524 template<typename... _Ts>
8525 concept __can_cartesian_product_view
8526 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8529 struct _CartesianProduct
8531 template<typename... _Ts>
8532 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8534 operator() [[nodiscard]] (_Ts&&... __ts) const
8536 if constexpr (sizeof...(_Ts) == 0)
8537 return views::empty<tuple<>>;
8539 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8543 inline constexpr _CartesianProduct cartesian_product;
8546#define __cpp_lib_ranges_as_rvalue 202207L
8548 template<input_range _Vp>
8550 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8552 _Vp _M_base = _Vp();
8555 as_rvalue_view() requires default_initializable<_Vp> = default;
8558 as_rvalue_view(_Vp __base)
8559 : _M_base(std::move(__base))
8563 base() const& requires copy_constructible<_Vp>
8568 { return std::move(_M_base); }
8571 begin() requires (!__detail::__simple_view<_Vp>)
8572 { return move_iterator(ranges::begin(_M_base)); }
8575 begin() const requires range<const _Vp>
8576 { return move_iterator(ranges::begin(_M_base)); }
8579 end() requires (!__detail::__simple_view<_Vp>)
8581 if constexpr (common_range<_Vp>)
8582 return move_iterator(ranges::end(_M_base));
8584 return move_sentinel(ranges::end(_M_base));
8588 end() const requires range<const _Vp>
8590 if constexpr (common_range<const _Vp>)
8591 return move_iterator(ranges::end(_M_base));
8593 return move_sentinel(ranges::end(_M_base));
8597 size() requires sized_range<_Vp>
8598 { return ranges::size(_M_base); }
8601 size() const requires sized_range<const _Vp>
8602 { return ranges::size(_M_base); }
8605 template<typename _Range>
8606 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8608 template<typename _Tp>
8609 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8610 = enable_borrowed_range<_Tp>;
8616 template<typename _Tp>
8617 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8620 struct _AsRvalue : __adaptor::_RangeAdaptorClosure
8622 template<viewable_range _Range>
8623 requires __detail::__can_as_rvalue_view<_Range>
8625 operator() [[nodiscard]] (_Range&& __r) const
8627 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8628 range_reference_t<_Range>>)
8629 return views::all(std::forward<_Range>(__r));
8631 return as_rvalue_view(std::forward<_Range>(__r));
8635 inline constexpr _AsRvalue as_rvalue;
8638#define __cpp_lib_ranges_enumerate 202302L
8642 template<typename _Range>
8643 concept __range_with_movable_reference = input_range<_Range>
8644 && move_constructible<range_reference_t<_Range>>
8645 && move_constructible<range_rvalue_reference_t<_Range>>;
8649 requires __detail::__range_with_movable_reference<_Vp>
8650 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8652 _Vp _M_base = _Vp();
8654 template<bool _Const> class _Iterator;
8655 template<bool _Const> class _Sentinel;
8658 enumerate_view() requires default_initializable<_Vp> = default;
8661 enumerate_view(_Vp __base)
8662 : _M_base(std::move(__base))
8666 begin() requires (!__detail::__simple_view<_Vp>)
8667 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8670 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8671 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8674 end() requires (!__detail::__simple_view<_Vp>)
8676 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8677 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8679 return _Sentinel<false>(ranges::end(_M_base));
8683 end() const requires __detail::__range_with_movable_reference<const _Vp>
8685 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8686 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8688 return _Sentinel<true>(ranges::end(_M_base));
8692 size() requires sized_range<_Vp>
8693 { return ranges::size(_M_base); }
8696 size() const requires sized_range<const _Vp>
8697 { return ranges::size(_M_base); }
8700 base() const & requires copy_constructible<_Vp>
8705 { return std::move(_M_base); }
8708 template<typename _Range>
8709 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8711 template<typename _Tp>
8712 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8713 = enable_borrowed_range<_Tp>;
8716 requires __detail::__range_with_movable_reference<_Vp>
8717 template<bool _Const>
8718 class enumerate_view<_Vp>::_Iterator
8720 using _Base = __maybe_const_t<_Const, _Vp>;
8725 if constexpr (random_access_range<_Base>)
8726 return random_access_iterator_tag{};
8727 else if constexpr (bidirectional_range<_Base>)
8728 return bidirectional_iterator_tag{};
8729 else if constexpr (forward_range<_Base>)
8730 return forward_iterator_tag{};
8732 return input_iterator_tag{};
8735 friend enumerate_view;
8738 using iterator_category = input_iterator_tag;
8739 using iterator_concept = decltype(_S_iter_concept());
8740 using difference_type = range_difference_t<_Base>;
8741 using value_type = tuple<difference_type, range_value_t<_Base>>;
8744 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
8746 iterator_t<_Base> _M_current = iterator_t<_Base>();
8747 difference_type _M_pos = 0;
8750 _Iterator(iterator_t<_Base> __current, difference_type __pos)
8751 : _M_current(std::move(__current)), _M_pos(__pos)
8755 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8758 _Iterator(_Iterator<!_Const> __i)
8759 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8760 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
8763 constexpr const iterator_t<_Base> &
8764 base() const & noexcept
8765 { return _M_current; }
8767 constexpr iterator_t<_Base>
8769 { return std::move(_M_current); }
8771 constexpr difference_type
8772 index() const noexcept
8777 { return __reference_type(_M_pos, *_M_current); }
8779 constexpr _Iterator&
8792 operator++(int) requires forward_range<_Base>
8799 constexpr _Iterator&
8800 operator--() requires bidirectional_range<_Base>
8808 operator--(int) requires bidirectional_range<_Base>
8815 constexpr _Iterator&
8816 operator+=(difference_type __n) requires random_access_range<_Base>
8823 constexpr _Iterator&
8824 operator-=(difference_type __n) requires random_access_range<_Base>
8832 operator[](difference_type __n) const requires random_access_range<_Base>
8833 { return __reference_type(_M_pos + __n, _M_current[__n]); }
8835 friend constexpr bool
8836 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
8837 { return __x._M_pos == __y._M_pos; }
8839 friend constexpr strong_ordering
8840 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
8841 { return __x._M_pos <=> __y._M_pos; }
8843 friend constexpr _Iterator
8844 operator+(const _Iterator& __x, difference_type __y)
8845 requires random_access_range<_Base>
8846 { return (auto(__x) += __y); }
8848 friend constexpr _Iterator
8849 operator+(difference_type __x, const _Iterator& __y)
8850 requires random_access_range<_Base>
8851 { return auto(__y) += __x; }
8853 friend constexpr _Iterator
8854 operator-(const _Iterator& __x, difference_type __y)
8855 requires random_access_range<_Base>
8856 { return auto(__x) -= __y; }
8858 friend constexpr difference_type
8859 operator-(const _Iterator& __x, const _Iterator& __y)
8860 { return __x._M_pos - __y._M_pos; }
8862 friend constexpr auto
8863 iter_move(const _Iterator& __i)
8864 noexcept(noexcept(ranges::iter_move(__i._M_current))
8865 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
8867 return tuple<difference_type, range_rvalue_reference_t<_Base>>
8868 (__i._M_pos, ranges::iter_move(__i._M_current));
8873 requires __detail::__range_with_movable_reference<_Vp>
8874 template<bool _Const>
8875 class enumerate_view<_Vp>::_Sentinel
8877 using _Base = __maybe_const_t<_Const, _Vp>;
8879 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8882 _Sentinel(sentinel_t<_Base> __end)
8883 : _M_end(std::move(__end))
8886 friend enumerate_view;
8889 _Sentinel() = default;
8892 _Sentinel(_Sentinel<!_Const> __other)
8893 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8894 : _M_end(std::move(__other._M_end))
8897 constexpr sentinel_t<_Base>
8901 template<bool _OtherConst>
8902 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8903 friend constexpr bool
8904 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8905 { return __x._M_current == __y._M_end; }
8907 template<bool _OtherConst>
8908 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8909 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8910 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8911 { return __x._M_current - __y._M_end; }
8913 template<bool _OtherConst>
8914 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8915 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8916 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
8917 { return __x._M_end - __y._M_current; }
8924 template<typename _Tp>
8925 concept __can_enumerate_view
8926 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
8929 struct _Enumerate : __adaptor::_RangeAdaptorClosure
8931 template<viewable_range _Range>
8932 requires __detail::__can_enumerate_view<_Range>
8934 operator() [[nodiscard]] (_Range&& __r) const
8935 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
8938 inline constexpr _Enumerate enumerate;
8941#define __cpp_lib_ranges_as_const 202207L
8944 requires input_range<_Vp>
8945 class as_const_view : public view_interface<as_const_view<_Vp>>
8947 _Vp _M_base = _Vp();
8950 as_const_view() requires default_initializable<_Vp> = default;
8953 as_const_view(_Vp __base)
8954 noexcept(is_nothrow_move_constructible_v<_Vp>)
8955 : _M_base(std::move(__base))
8960 noexcept(is_nothrow_copy_constructible_v<_Vp>)
8961 requires copy_constructible<_Vp>
8966 noexcept(is_nothrow_move_constructible_v<_Vp>)
8967 { return std::move(_M_base); }
8970 begin() requires (!__detail::__simple_view<_Vp>)
8971 { return ranges::cbegin(_M_base); }
8974 begin() const requires range<const _Vp>
8975 { return ranges::cbegin(_M_base); }
8978 end() requires (!__detail::__simple_view<_Vp>)
8979 { return ranges::cend(_M_base); }
8982 end() const requires range<const _Vp>
8983 { return ranges::cend(_M_base); }
8986 size() requires sized_range<_Vp>
8987 { return ranges::size(_M_base); }
8990 size() const requires sized_range<const _Vp>
8991 { return ranges::size(_M_base); }
8994 template<typename _Range>
8995 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
8997 template<typename _Tp>
8998 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
8999 = enable_borrowed_range<_Tp>;
9005 template<typename _Tp>
9006 inline constexpr bool __is_ref_view = false;
9008 template<typename _Range>
9009 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9011 template<typename _Range>
9012 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9015 struct _AsConst : __adaptor::_RangeAdaptorClosure
9017 template<viewable_range _Range>
9019 operator()(_Range&& __r) const
9020 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9021 requires __detail::__can_as_const_view<_Range>
9023 using _Tp = remove_cvref_t<_Range>;
9024 using element_type = remove_reference_t<range_reference_t<_Range>>;
9025 if constexpr (constant_range<views::all_t<_Range>>)
9026 return views::all(std::forward<_Range>(__r));
9027 else if constexpr (__detail::__is_empty_view<_Tp>)
9028 return views::empty<const element_type>;
9029 else if constexpr (std::__detail::__is_span<_Tp>)
9030 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9031 else if constexpr (__detail::__is_ref_view<_Tp>
9032 && constant_range<const element_type>)
9033 return ref_view(static_cast<const element_type&>
9034 (std::forward<_Range>(__r).base()));
9035 else if constexpr (is_lvalue_reference_v<_Range>
9036 && constant_range<const _Tp>
9038 return ref_view(static_cast<const _Tp&>(__r));
9040 return as_const_view(std::forward<_Range>(__r));
9044 inline constexpr _AsConst as_const;
9047} // namespace ranges
9049 namespace views = ranges::views;
9051_GLIBCXX_END_NAMESPACE_VERSION
9053#endif // library concepts
9055#endif /* _GLIBCXX_RANGES */