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 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1753 // 3564. transform_view::iterator<true>::value_type and
1754 // iterator_category should use const F&
1755 using _Base = transform_view::_Base<_Const>;
1756 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1757 range_reference_t<_Base>>;
1758 if constexpr (is_lvalue_reference_v<_Res>)
1761 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1762 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1763 return random_access_iterator_tag{};
1768 return input_iterator_tag{};
1771 using iterator_category = decltype(_S_iter_cat());
1774 template<bool _Const>
1777 template<bool _Const>
1778 struct _Iterator : __iter_cat<_Const>
1781 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1782 using _Base = transform_view::_Base<_Const>;
1787 if constexpr (random_access_range<_Base>)
1788 return random_access_iterator_tag{};
1789 else if constexpr (bidirectional_range<_Base>)
1790 return bidirectional_iterator_tag{};
1791 else if constexpr (forward_range<_Base>)
1792 return forward_iterator_tag{};
1794 return input_iterator_tag{};
1797 using _Base_iter = iterator_t<_Base>;
1799 _Base_iter _M_current = _Base_iter();
1800 _Parent* _M_parent = nullptr;
1803 using iterator_concept = decltype(_S_iter_concept());
1804 // iterator_category defined in __transform_view_iter_cat
1806 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1807 range_reference_t<_Base>>>;
1808 using difference_type = range_difference_t<_Base>;
1810 _Iterator() requires default_initializable<_Base_iter> = default;
1813 _Iterator(_Parent* __parent, _Base_iter __current)
1814 : _M_current(std::move(__current)),
1819 _Iterator(_Iterator<!_Const> __i)
1821 && convertible_to<iterator_t<_Vp>, _Base_iter>
1822 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1825 constexpr const _Base_iter&
1826 base() const & noexcept
1827 { return _M_current; }
1829 constexpr _Base_iter
1831 { return std::move(_M_current); }
1833 constexpr decltype(auto)
1835 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1836 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1838 constexpr _Iterator&
1850 operator++(int) requires forward_range<_Base>
1857 constexpr _Iterator&
1858 operator--() requires bidirectional_range<_Base>
1865 operator--(int) requires bidirectional_range<_Base>
1872 constexpr _Iterator&
1873 operator+=(difference_type __n) requires random_access_range<_Base>
1879 constexpr _Iterator&
1880 operator-=(difference_type __n) requires random_access_range<_Base>
1886 constexpr decltype(auto)
1887 operator[](difference_type __n) const
1888 requires random_access_range<_Base>
1889 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
1891 friend constexpr bool
1892 operator==(const _Iterator& __x, const _Iterator& __y)
1893 requires equality_comparable<_Base_iter>
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 __x._M_current < __y._M_current; }
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 !(__y < __x); }
1911 friend constexpr bool
1912 operator>=(const _Iterator& __x, const _Iterator& __y)
1913 requires random_access_range<_Base>
1914 { return !(__x < __y); }
1916#ifdef __cpp_lib_three_way_comparison
1917 friend constexpr auto
1918 operator<=>(const _Iterator& __x, const _Iterator& __y)
1919 requires random_access_range<_Base>
1920 && three_way_comparable<_Base_iter>
1921 { return __x._M_current <=> __y._M_current; }
1924 friend constexpr _Iterator
1925 operator+(_Iterator __i, difference_type __n)
1926 requires random_access_range<_Base>
1927 { return {__i._M_parent, __i._M_current + __n}; }
1929 friend constexpr _Iterator
1930 operator+(difference_type __n, _Iterator __i)
1931 requires random_access_range<_Base>
1932 { return {__i._M_parent, __i._M_current + __n}; }
1934 friend constexpr _Iterator
1935 operator-(_Iterator __i, difference_type __n)
1936 requires random_access_range<_Base>
1937 { return {__i._M_parent, __i._M_current - __n}; }
1939 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1940 // 3483. transform_view::iterator's difference is overconstrained
1941 friend constexpr difference_type
1942 operator-(const _Iterator& __x, const _Iterator& __y)
1943 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
1944 { return __x._M_current - __y._M_current; }
1946 friend constexpr decltype(auto)
1947 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
1949 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
1950 return std::move(*__i);
1955 friend _Iterator<!_Const>;
1956 template<bool> friend struct _Sentinel;
1959 template<bool _Const>
1963 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1964 using _Base = transform_view::_Base<_Const>;
1966 template<bool _Const2>
1968 __distance_from(const _Iterator<_Const2>& __i) const
1969 { return _M_end - __i._M_current; }
1971 template<bool _Const2>
1973 __equal(const _Iterator<_Const2>& __i) const
1974 { return __i._M_current == _M_end; }
1976 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
1979 _Sentinel() = default;
1982 _Sentinel(sentinel_t<_Base> __end)
1987 _Sentinel(_Sentinel<!_Const> __i)
1989 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
1990 : _M_end(std::move(__i._M_end))
1993 constexpr sentinel_t<_Base>
1997 template<bool _Const2>
1998 requires sentinel_for<sentinel_t<_Base>,
1999 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2000 friend constexpr bool
2001 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2002 { return __y.__equal(__x); }
2004 template<bool _Const2,
2005 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2006 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2007 friend constexpr range_difference_t<_Base2>
2008 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2009 { return -__y.__distance_from(__x); }
2011 template<bool _Const2,
2012 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2013 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2014 friend constexpr range_difference_t<_Base2>
2015 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2016 { return __y.__distance_from(__x); }
2018 friend _Sentinel<!_Const>;
2021 _Vp _M_base = _Vp();
2022 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2025 transform_view() requires (default_initializable<_Vp>
2026 && default_initializable<_Fp>)
2030 transform_view(_Vp __base, _Fp __fun)
2031 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2035 base() const& requires copy_constructible<_Vp>
2036 { return _M_base ; }
2040 { return std::move(_M_base); }
2042 constexpr _Iterator<false>
2044 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2046 constexpr _Iterator<true>
2048 requires range<const _Vp>
2049 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2050 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2052 constexpr _Sentinel<false>
2054 { return _Sentinel<false>{ranges::end(_M_base)}; }
2056 constexpr _Iterator<false>
2057 end() requires common_range<_Vp>
2058 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2060 constexpr _Sentinel<true>
2062 requires range<const _Vp>
2063 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2064 { return _Sentinel<true>{ranges::end(_M_base)}; }
2066 constexpr _Iterator<true>
2068 requires common_range<const _Vp>
2069 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2070 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2073 size() requires sized_range<_Vp>
2074 { return ranges::size(_M_base); }
2077 size() const requires sized_range<const _Vp>
2078 { return ranges::size(_M_base); }
2081 template<typename _Range, typename _Fp>
2082 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2088 template<typename _Range, typename _Fp>
2089 concept __can_transform_view
2090 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2091 } // namespace __detail
2093 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2095 template<viewable_range _Range, typename _Fp>
2096 requires __detail::__can_transform_view<_Range, _Fp>
2098 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2100 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2103 using _RangeAdaptor<_Transform>::operator();
2104 static constexpr int _S_arity = 2;
2105 static constexpr bool _S_has_simple_extra_args = true;
2108 inline constexpr _Transform transform;
2109 } // namespace views
2112 class take_view : public view_interface<take_view<_Vp>>
2115 template<bool _Const>
2116 using _CI = counted_iterator<
2117 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2119 template<bool _Const>
2123 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2124 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2127 _Sentinel() = default;
2130 _Sentinel(sentinel_t<_Base> __end)
2135 _Sentinel(_Sentinel<!_Const> __s)
2136 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2137 : _M_end(std::move(__s._M_end))
2140 constexpr sentinel_t<_Base>
2144 friend constexpr bool
2145 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2146 { return __y.count() == 0 || __y.base() == __x._M_end; }
2148 template<bool _OtherConst = !_Const,
2149 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2150 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2151 friend constexpr bool
2152 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2153 { return __y.count() == 0 || __y.base() == __x._M_end; }
2155 friend _Sentinel<!_Const>;
2158 _Vp _M_base = _Vp();
2159 range_difference_t<_Vp> _M_count = 0;
2162 take_view() requires default_initializable<_Vp> = default;
2165 take_view(_Vp __base, range_difference_t<_Vp> __count)
2166 : _M_base(std::move(__base)), _M_count(std::move(__count))
2170 base() const& requires copy_constructible<_Vp>
2175 { return std::move(_M_base); }
2178 begin() requires (!__detail::__simple_view<_Vp>)
2180 if constexpr (sized_range<_Vp>)
2182 if constexpr (random_access_range<_Vp>)
2183 return ranges::begin(_M_base);
2187 return counted_iterator(ranges::begin(_M_base), __sz);
2191 return counted_iterator(ranges::begin(_M_base), _M_count);
2195 begin() const requires range<const _Vp>
2197 if constexpr (sized_range<const _Vp>)
2199 if constexpr (random_access_range<const _Vp>)
2200 return ranges::begin(_M_base);
2204 return counted_iterator(ranges::begin(_M_base), __sz);
2208 return counted_iterator(ranges::begin(_M_base), _M_count);
2212 end() requires (!__detail::__simple_view<_Vp>)
2214 if constexpr (sized_range<_Vp>)
2216 if constexpr (random_access_range<_Vp>)
2217 return ranges::begin(_M_base) + size();
2219 return default_sentinel;
2222 return _Sentinel<false>{ranges::end(_M_base)};
2226 end() const requires range<const _Vp>
2228 if constexpr (sized_range<const _Vp>)
2230 if constexpr (random_access_range<const _Vp>)
2231 return ranges::begin(_M_base) + size();
2233 return default_sentinel;
2236 return _Sentinel<true>{ranges::end(_M_base)};
2240 size() requires sized_range<_Vp>
2242 auto __n = ranges::size(_M_base);
2243 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2247 size() const requires sized_range<const _Vp>
2249 auto __n = ranges::size(_M_base);
2250 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2254 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2255 // 3447. Deduction guides for take_view and drop_view have different
2257 template<typename _Range>
2258 take_view(_Range&&, range_difference_t<_Range>)
2259 -> take_view<views::all_t<_Range>>;
2261 template<typename _Tp>
2262 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2263 = enable_borrowed_range<_Tp>;
2269 template<typename _Range>
2270 inline constexpr bool __is_empty_view = false;
2272 template<typename _Tp>
2273 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2275 template<typename _Range>
2276 inline constexpr bool __is_basic_string_view = false;
2278 template<typename _CharT, typename _Traits>
2279 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2282 template<typename _Range>
2283 inline constexpr bool __is_subrange = false;
2285 template<typename _Iter, typename _Sent, subrange_kind _Kind>
2286 inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
2288 template<typename _Range>
2289 inline constexpr bool __is_iota_view = false;
2291 template<typename _Winc, typename _Bound>
2292 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2294 template<typename _Range>
2295 inline constexpr bool __is_repeat_view = false;
2297 template<typename _Range>
2299 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2301 template<typename _Range, typename _Dp>
2302 concept __can_take_view
2303 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2304 } // namespace __detail
2306 struct _Take : __adaptor::_RangeAdaptor<_Take>
2308 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2309 requires __detail::__can_take_view<_Range, _Dp>
2311 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2313 using _Tp = remove_cvref_t<_Range>;
2314 if constexpr (__detail::__is_empty_view<_Tp>)
2316 else if constexpr (random_access_range<_Tp>
2318 && (std::__detail::__is_span<_Tp>
2319 || __detail::__is_basic_string_view<_Tp>
2320 || __detail::__is_subrange<_Tp>
2321 || __detail::__is_iota_view<_Tp>))
2323 __n = std::min<_Dp>(ranges::distance(__r), __n);
2324 auto __begin = ranges::begin(__r);
2325 auto __end = __begin + __n;
2326 if constexpr (std::__detail::__is_span<_Tp>)
2327 return span<typename _Tp::element_type>(__begin, __end);
2328 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2329 return _Tp(__begin, __end);
2330 else if constexpr (__detail::__is_subrange<_Tp>)
2331 return subrange<iterator_t<_Tp>>(__begin, __end);
2333 return iota_view(*__begin, *__end);
2335 else if constexpr (__detail::__is_repeat_view<_Tp>)
2336 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2338 return take_view(std::forward<_Range>(__r), __n);
2341 using _RangeAdaptor<_Take>::operator();
2342 static constexpr int _S_arity = 2;
2343 // The count argument of views::take is not always simple -- it can be
2344 // e.g. a move-only class that's implicitly convertible to the difference
2345 // type. But an integer-like count argument is surely simple.
2346 template<typename _Tp>
2347 static constexpr bool _S_has_simple_extra_args
2348 = ranges::__detail::__is_integer_like<_Tp>;
2351 inline constexpr _Take take;
2352 } // namespace views
2354 template<view _Vp, typename _Pred>
2355 requires input_range<_Vp> && is_object_v<_Pred>
2356 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2357 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2359 template<bool _Const>
2363 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2365 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2366 const _Pred* _M_pred = nullptr;
2369 _Sentinel() = default;
2372 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2373 : _M_end(__end), _M_pred(__pred)
2377 _Sentinel(_Sentinel<!_Const> __s)
2378 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2379 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2382 constexpr sentinel_t<_Base>
2383 base() const { return _M_end; }
2385 friend constexpr bool
2386 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2387 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2389 template<bool _OtherConst = !_Const,
2390 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2391 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2392 friend constexpr bool
2393 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2394 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2396 friend _Sentinel<!_Const>;
2399 _Vp _M_base = _Vp();
2400 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2403 take_while_view() requires (default_initializable<_Vp>
2404 && default_initializable<_Pred>)
2408 take_while_view(_Vp __base, _Pred __pred)
2409 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2413 base() const& requires copy_constructible<_Vp>
2418 { return std::move(_M_base); }
2420 constexpr const _Pred&
2422 { return *_M_pred; }
2425 begin() requires (!__detail::__simple_view<_Vp>)
2426 { return ranges::begin(_M_base); }
2429 begin() const requires range<const _Vp>
2430 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2431 { return ranges::begin(_M_base); }
2434 end() requires (!__detail::__simple_view<_Vp>)
2435 { return _Sentinel<false>(ranges::end(_M_base),
2436 std::__addressof(*_M_pred)); }
2439 end() const requires range<const _Vp>
2440 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2441 { return _Sentinel<true>(ranges::end(_M_base),
2442 std::__addressof(*_M_pred)); }
2445 template<typename _Range, typename _Pred>
2446 take_while_view(_Range&&, _Pred)
2447 -> take_while_view<views::all_t<_Range>, _Pred>;
2453 template<typename _Range, typename _Pred>
2454 concept __can_take_while_view
2455 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2456 } // namespace __detail
2458 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2460 template<viewable_range _Range, typename _Pred>
2461 requires __detail::__can_take_while_view<_Range, _Pred>
2463 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2465 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2468 using _RangeAdaptor<_TakeWhile>::operator();
2469 static constexpr int _S_arity = 2;
2470 static constexpr bool _S_has_simple_extra_args = true;
2473 inline constexpr _TakeWhile take_while;
2474 } // namespace views
2477 class drop_view : public view_interface<drop_view<_Vp>>
2480 _Vp _M_base = _Vp();
2481 range_difference_t<_Vp> _M_count = 0;
2483 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2484 // both random_access_range and sized_range. Otherwise, cache its result.
2485 static constexpr bool _S_needs_cached_begin
2486 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2487 [[no_unique_address]]
2488 __detail::__maybe_present_t<_S_needs_cached_begin,
2489 __detail::_CachedPosition<_Vp>>
2493 drop_view() requires default_initializable<_Vp> = default;
2496 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2497 : _M_base(std::move(__base)), _M_count(__count)
2498 { __glibcxx_assert(__count >= 0); }
2501 base() const& requires copy_constructible<_Vp>
2506 { return std::move(_M_base); }
2508 // This overload is disabled for simple views with constant-time begin().
2511 requires (!(__detail::__simple_view<_Vp>
2512 && random_access_range<const _Vp>
2513 && sized_range<const _Vp>))
2515 if constexpr (_S_needs_cached_begin)
2516 if (_M_cached_begin._M_has_value())
2517 return _M_cached_begin._M_get(_M_base);
2519 auto __it = ranges::next(ranges::begin(_M_base),
2520 _M_count, ranges::end(_M_base));
2521 if constexpr (_S_needs_cached_begin)
2522 _M_cached_begin._M_set(_M_base, __it);
2526 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2527 // 3482. drop_view's const begin should additionally require sized_range
2530 requires random_access_range<const _Vp> && sized_range<const _Vp>
2532 return ranges::next(ranges::begin(_M_base), _M_count,
2533 ranges::end(_M_base));
2537 end() requires (!__detail::__simple_view<_Vp>)
2538 { return ranges::end(_M_base); }
2541 end() const requires range<const _Vp>
2542 { return ranges::end(_M_base); }
2545 size() requires sized_range<_Vp>
2547 const auto __s = ranges::size(_M_base);
2548 const auto __c = static_cast<decltype(__s)>(_M_count);
2549 return __s < __c ? 0 : __s - __c;
2553 size() const requires sized_range<const _Vp>
2555 const auto __s = ranges::size(_M_base);
2556 const auto __c = static_cast<decltype(__s)>(_M_count);
2557 return __s < __c ? 0 : __s - __c;
2561 template<typename _Range>
2562 drop_view(_Range&&, range_difference_t<_Range>)
2563 -> drop_view<views::all_t<_Range>>;
2565 template<typename _Tp>
2566 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2567 = enable_borrowed_range<_Tp>;
2573 template<typename _Range>
2575 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2577 template<typename _Range, typename _Dp>
2578 concept __can_drop_view
2579 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2580 } // namespace __detail
2582 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2584 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2585 requires __detail::__can_drop_view<_Range, _Dp>
2587 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2589 using _Tp = remove_cvref_t<_Range>;
2590 if constexpr (__detail::__is_empty_view<_Tp>)
2592 else if constexpr (random_access_range<_Tp>
2594 && (std::__detail::__is_span<_Tp>
2595 || __detail::__is_basic_string_view<_Tp>
2596 || __detail::__is_iota_view<_Tp>
2597 || __detail::__is_subrange<_Tp>))
2599 __n = std::min<_Dp>(ranges::distance(__r), __n);
2600 auto __begin = ranges::begin(__r) + __n;
2601 auto __end = ranges::end(__r);
2602 if constexpr (std::__detail::__is_span<_Tp>)
2603 return span<typename _Tp::element_type>(__begin, __end);
2604 else if constexpr (__detail::__is_subrange<_Tp>)
2606 if constexpr (_Tp::_S_store_size)
2608 using ranges::__detail::__to_unsigned_like;
2609 auto __m = ranges::distance(__r) - __n;
2610 return _Tp(__begin, __end, __to_unsigned_like(__m));
2613 return _Tp(__begin, __end);
2616 return _Tp(__begin, __end);
2618 else if constexpr (__detail::__is_repeat_view<_Tp>)
2619 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2621 return drop_view(std::forward<_Range>(__r), __n);
2624 using _RangeAdaptor<_Drop>::operator();
2625 static constexpr int _S_arity = 2;
2626 template<typename _Tp>
2627 static constexpr bool _S_has_simple_extra_args
2628 = _Take::_S_has_simple_extra_args<_Tp>;
2631 inline constexpr _Drop drop;
2632 } // namespace views
2634 template<view _Vp, typename _Pred>
2635 requires input_range<_Vp> && is_object_v<_Pred>
2636 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2637 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2640 _Vp _M_base = _Vp();
2641 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2642 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2645 drop_while_view() requires (default_initializable<_Vp>
2646 && default_initializable<_Pred>)
2650 drop_while_view(_Vp __base, _Pred __pred)
2651 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2655 base() const& requires copy_constructible<_Vp>
2660 { return std::move(_M_base); }
2662 constexpr const _Pred&
2664 { return *_M_pred; }
2669 if (_M_cached_begin._M_has_value())
2670 return _M_cached_begin._M_get(_M_base);
2672 __glibcxx_assert(_M_pred.has_value());
2673 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2674 ranges::end(_M_base),
2675 std::cref(*_M_pred));
2676 _M_cached_begin._M_set(_M_base, __it);
2682 { return ranges::end(_M_base); }
2685 template<typename _Range, typename _Pred>
2686 drop_while_view(_Range&&, _Pred)
2687 -> drop_while_view<views::all_t<_Range>, _Pred>;
2689 template<typename _Tp, typename _Pred>
2690 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2691 = enable_borrowed_range<_Tp>;
2697 template<typename _Range, typename _Pred>
2698 concept __can_drop_while_view
2699 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2700 } // namespace __detail
2702 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2704 template<viewable_range _Range, typename _Pred>
2705 requires __detail::__can_drop_while_view<_Range, _Pred>
2707 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2709 return drop_while_view(std::forward<_Range>(__r),
2710 std::forward<_Pred>(__p));
2713 using _RangeAdaptor<_DropWhile>::operator();
2714 static constexpr int _S_arity = 2;
2715 static constexpr bool _S_has_simple_extra_args = true;
2718 inline constexpr _DropWhile drop_while;
2719 } // namespace views
2721 template<input_range _Vp>
2722 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2723 class join_view : public view_interface<join_view<_Vp>>
2726 using _InnerRange = range_reference_t<_Vp>;
2728 template<bool _Const>
2729 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2731 template<bool _Const>
2732 using _Outer_iter = iterator_t<_Base<_Const>>;
2734 template<bool _Const>
2735 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2737 template<bool _Const>
2738 static constexpr bool _S_ref_is_glvalue
2739 = is_reference_v<range_reference_t<_Base<_Const>>>;
2741 template<bool _Const>
2745 template<bool _Const>
2746 requires _S_ref_is_glvalue<_Const>
2747 && forward_range<_Base<_Const>>
2748 && forward_range<range_reference_t<_Base<_Const>>>
2749 struct __iter_cat<_Const>
2752 static constexpr auto
2755 using _Outer_iter = join_view::_Outer_iter<_Const>;
2756 using _Inner_iter = join_view::_Inner_iter<_Const>;
2757 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2758 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2759 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2760 && derived_from<_InnerCat, bidirectional_iterator_tag>
2761 && common_range<range_reference_t<_Base<_Const>>>)
2762 return bidirectional_iterator_tag{};
2763 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2764 && derived_from<_InnerCat, forward_iterator_tag>)
2765 return forward_iterator_tag{};
2767 return input_iterator_tag{};
2770 using iterator_category = decltype(_S_iter_cat());
2773 template<bool _Const>
2776 template<bool _Const>
2777 struct _Iterator : __iter_cat<_Const>
2780 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2781 using _Base = join_view::_Base<_Const>;
2783 static constexpr bool _S_ref_is_glvalue
2784 = join_view::_S_ref_is_glvalue<_Const>;
2789 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2790 if constexpr (_S_ref_is_glvalue)
2793 return _M_parent->_M_inner._M_emplace_deref(__x);
2796 for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
2798 auto&& __inner = __update_inner(_M_outer);
2799 _M_inner = ranges::begin(__inner);
2800 if (_M_inner != ranges::end(__inner))
2804 if constexpr (_S_ref_is_glvalue)
2808 static constexpr auto
2811 if constexpr (_S_ref_is_glvalue
2812 && bidirectional_range<_Base>
2813 && bidirectional_range<range_reference_t<_Base>>
2814 && common_range<range_reference_t<_Base>>)
2815 return bidirectional_iterator_tag{};
2816 else if constexpr (_S_ref_is_glvalue
2817 && forward_range<_Base>
2818 && forward_range<range_reference_t<_Base>>)
2819 return forward_iterator_tag{};
2821 return input_iterator_tag{};
2824 using _Outer_iter = join_view::_Outer_iter<_Const>;
2825 using _Inner_iter = join_view::_Inner_iter<_Const>;
2827 _Outer_iter _M_outer = _Outer_iter();
2828 optional<_Inner_iter> _M_inner;
2829 _Parent* _M_parent = nullptr;
2832 using iterator_concept = decltype(_S_iter_concept());
2833 // iterator_category defined in __join_view_iter_cat
2834 using value_type = range_value_t<range_reference_t<_Base>>;
2835 using difference_type
2836 = common_type_t<range_difference_t<_Base>,
2837 range_difference_t<range_reference_t<_Base>>>;
2839 _Iterator() requires default_initializable<_Outer_iter> = default;
2842 _Iterator(_Parent* __parent, _Outer_iter __outer)
2843 : _M_outer(std::move(__outer)),
2848 _Iterator(_Iterator<!_Const> __i)
2850 && convertible_to<iterator_t<_Vp>, _Outer_iter>
2851 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
2852 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
2853 _M_parent(__i._M_parent)
2856 constexpr decltype(auto)
2858 { return **_M_inner; }
2860 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2861 // 3500. join_view::iterator::operator->() is bogus
2862 constexpr _Inner_iter
2864 requires __detail::__has_arrow<_Inner_iter>
2865 && copyable<_Inner_iter>
2866 { return *_M_inner; }
2868 constexpr _Iterator&
2871 auto&& __inner_range = [this] () -> auto&& {
2872 if constexpr (_S_ref_is_glvalue)
2875 return *_M_parent->_M_inner;
2877 if (++*_M_inner == ranges::end(__inner_range))
2891 requires _S_ref_is_glvalue && forward_range<_Base>
2892 && forward_range<range_reference_t<_Base>>
2899 constexpr _Iterator&
2901 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2902 && bidirectional_range<range_reference_t<_Base>>
2903 && common_range<range_reference_t<_Base>>
2905 if (_M_outer == ranges::end(_M_parent->_M_base))
2906 _M_inner = ranges::end(*--_M_outer);
2907 while (*_M_inner == ranges::begin(*_M_outer))
2908 *_M_inner = ranges::end(*--_M_outer);
2915 requires _S_ref_is_glvalue && bidirectional_range<_Base>
2916 && bidirectional_range<range_reference_t<_Base>>
2917 && common_range<range_reference_t<_Base>>
2924 friend constexpr bool
2925 operator==(const _Iterator& __x, const _Iterator& __y)
2926 requires _S_ref_is_glvalue
2927 && equality_comparable<_Outer_iter>
2928 && equality_comparable<_Inner_iter>
2930 return (__x._M_outer == __y._M_outer
2931 && __x._M_inner == __y._M_inner);
2934 friend constexpr decltype(auto)
2935 iter_move(const _Iterator& __i)
2936 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
2937 { return ranges::iter_move(*__i._M_inner); }
2939 friend constexpr void
2940 iter_swap(const _Iterator& __x, const _Iterator& __y)
2941 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
2942 requires indirectly_swappable<_Inner_iter>
2943 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
2945 friend _Iterator<!_Const>;
2946 template<bool> friend struct _Sentinel;
2949 template<bool _Const>
2953 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2954 using _Base = join_view::_Base<_Const>;
2956 template<bool _Const2>
2958 __equal(const _Iterator<_Const2>& __i) const
2959 { return __i._M_outer == _M_end; }
2961 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2964 _Sentinel() = default;
2967 _Sentinel(_Parent* __parent)
2968 : _M_end(ranges::end(__parent->_M_base))
2972 _Sentinel(_Sentinel<!_Const> __s)
2973 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2974 : _M_end(std::move(__s._M_end))
2977 template<bool _Const2>
2978 requires sentinel_for<sentinel_t<_Base>,
2979 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2980 friend constexpr bool
2981 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2982 { return __y.__equal(__x); }
2984 friend _Sentinel<!_Const>;
2987 _Vp _M_base = _Vp();
2988 [[no_unique_address]]
2989 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
2992 join_view() requires default_initializable<_Vp> = default;
2995 join_view(_Vp __base)
2996 : _M_base(std::move(__base))
3000 base() const& requires copy_constructible<_Vp>
3005 { return std::move(_M_base); }
3010 constexpr bool __use_const
3011 = (__detail::__simple_view<_Vp>
3012 && is_reference_v<range_reference_t<_Vp>>);
3013 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3018 requires input_range<const _Vp>
3019 && is_reference_v<range_reference_t<const _Vp>>
3021 return _Iterator<true>{this, ranges::begin(_M_base)};
3027 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3028 && forward_range<_InnerRange>
3029 && common_range<_Vp> && common_range<_InnerRange>)
3030 return _Iterator<__detail::__simple_view<_Vp>>{this,
3031 ranges::end(_M_base)};
3033 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3038 requires input_range<const _Vp>
3039 && is_reference_v<range_reference_t<const _Vp>>
3041 if constexpr (forward_range<const _Vp>
3042 && is_reference_v<range_reference_t<const _Vp>>
3043 && forward_range<range_reference_t<const _Vp>>
3044 && common_range<const _Vp>
3045 && common_range<range_reference_t<const _Vp>>)
3046 return _Iterator<true>{this, ranges::end(_M_base)};
3048 return _Sentinel<true>{this};
3052 template<typename _Range>
3053 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3059 template<typename _Range>
3060 concept __can_join_view
3061 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3062 } // namespace __detail
3064 struct _Join : __adaptor::_RangeAdaptorClosure
3066 template<viewable_range _Range>
3067 requires __detail::__can_join_view<_Range>
3069 operator() [[nodiscard]] (_Range&& __r) const
3071 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3072 // 3474. Nesting join_views is broken because of CTAD
3073 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3076 static constexpr bool _S_has_simple_call_op = true;
3079 inline constexpr _Join join;
3080 } // namespace views
3085 struct __require_constant;
3087 template<typename _Range>
3088 concept __tiny_range = sized_range<_Range>
3090 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3091 && (remove_reference_t<_Range>::size() <= 1);
3093 template<typename _Base>
3094 struct __lazy_split_view_outer_iter_cat
3097 template<forward_range _Base>
3098 struct __lazy_split_view_outer_iter_cat<_Base>
3099 { using iterator_category = input_iterator_tag; };
3101 template<typename _Base>
3102 struct __lazy_split_view_inner_iter_cat
3105 template<forward_range _Base>
3106 struct __lazy_split_view_inner_iter_cat<_Base>
3109 static constexpr auto
3112 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3113 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3114 return forward_iterator_tag{};
3119 using iterator_category = decltype(_S_iter_cat());
3123 template<input_range _Vp, forward_range _Pattern>
3124 requires view<_Vp> && view<_Pattern>
3125 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3127 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3128 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3131 template<bool _Const>
3132 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3134 template<bool _Const>
3137 template<bool _Const>
3139 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3142 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3143 using _Base = lazy_split_view::_Base<_Const>;
3147 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3149 // [range.lazy.split.outer] p1
3150 // Many of the following specifications refer to the notional member
3151 // current of outer-iterator. current is equivalent to current_ if
3152 // V models forward_range, and parent_->current_ otherwise.
3154 __current() noexcept
3156 if constexpr (forward_range<_Vp>)
3159 return *_M_parent->_M_current;
3163 __current() const noexcept
3165 if constexpr (forward_range<_Vp>)
3168 return *_M_parent->_M_current;
3171 _Parent* _M_parent = nullptr;
3173 [[no_unique_address]]
3174 __detail::__maybe_present_t<forward_range<_Vp>,
3175 iterator_t<_Base>> _M_current;
3176 bool _M_trailing_empty = false;
3179 using iterator_concept = __conditional_t<forward_range<_Base>,
3180 forward_iterator_tag,
3181 input_iterator_tag>;
3182 // iterator_category defined in __lazy_split_view_outer_iter_cat
3183 using difference_type = range_difference_t<_Base>;
3185 struct value_type : view_interface<value_type>
3188 _OuterIter _M_i = _OuterIter();
3191 value_type() = default;
3194 value_type(_OuterIter __i)
3195 : _M_i(std::move(__i))
3198 constexpr _InnerIter<_Const>
3200 { return _InnerIter<_Const>{_M_i}; }
3202 constexpr default_sentinel_t
3203 end() const noexcept
3204 { return default_sentinel; }
3207 _OuterIter() = default;
3210 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3211 : _M_parent(__parent)
3215 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3216 requires forward_range<_Base>
3217 : _M_parent(__parent),
3218 _M_current(std::move(__current))
3222 _OuterIter(_OuterIter<!_Const> __i)
3224 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3225 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3226 _M_trailing_empty(__i._M_trailing_empty)
3229 constexpr value_type
3231 { return value_type{*this}; }
3233 constexpr _OuterIter&
3236 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3237 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3238 const auto __end = ranges::end(_M_parent->_M_base);
3239 if (__current() == __end)
3241 _M_trailing_empty = false;
3244 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3245 if (__pbegin == __pend)
3247 else if constexpr (__detail::__tiny_range<_Pattern>)
3249 __current() = ranges::find(std::move(__current()), __end,
3251 if (__current() != __end)
3254 if (__current() == __end)
3255 _M_trailing_empty = true;
3262 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3266 if (__current() == __end)
3267 _M_trailing_empty = true;
3270 } while (++__current() != __end);
3274 constexpr decltype(auto)
3277 if constexpr (forward_range<_Base>)
3287 friend constexpr bool
3288 operator==(const _OuterIter& __x, const _OuterIter& __y)
3289 requires forward_range<_Base>
3291 return __x._M_current == __y._M_current
3292 && __x._M_trailing_empty == __y._M_trailing_empty;
3295 friend constexpr bool
3296 operator==(const _OuterIter& __x, default_sentinel_t)
3297 { return __x.__at_end(); };
3299 friend _OuterIter<!_Const>;
3300 friend _InnerIter<_Const>;
3303 template<bool _Const>
3305 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3308 using _Base = lazy_split_view::_Base<_Const>;
3313 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3314 auto __end = ranges::end(_M_i._M_parent->_M_base);
3315 if constexpr (__detail::__tiny_range<_Pattern>)
3317 const auto& __cur = _M_i_current();
3320 if (__pcur == __pend)
3321 return _M_incremented;
3322 return *__cur == *__pcur;
3326 auto __cur = _M_i_current();
3329 if (__pcur == __pend)
3330 return _M_incremented;
3333 if (*__cur != *__pcur)
3335 if (++__pcur == __pend)
3337 } while (++__cur != __end);
3343 _M_i_current() noexcept
3344 { return _M_i.__current(); }
3347 _M_i_current() const noexcept
3348 { return _M_i.__current(); }
3350 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3351 bool _M_incremented = false;
3354 using iterator_concept
3355 = typename _OuterIter<_Const>::iterator_concept;
3356 // iterator_category defined in __lazy_split_view_inner_iter_cat
3357 using value_type = range_value_t<_Base>;
3358 using difference_type = range_difference_t<_Base>;
3360 _InnerIter() = default;
3363 _InnerIter(_OuterIter<_Const> __i)
3364 : _M_i(std::move(__i))
3367 constexpr const iterator_t<_Base>&
3368 base() const& noexcept
3369 { return _M_i_current(); }
3371 constexpr iterator_t<_Base>
3372 base() && requires forward_range<_Vp>
3373 { return std::move(_M_i_current()); }
3375 constexpr decltype(auto)
3377 { return *_M_i_current(); }
3379 constexpr _InnerIter&
3382 _M_incremented = true;
3383 if constexpr (!forward_range<_Base>)
3384 if constexpr (_Pattern::size() == 0)
3390 constexpr decltype(auto)
3393 if constexpr (forward_range<_Base>)
3403 friend constexpr bool
3404 operator==(const _InnerIter& __x, const _InnerIter& __y)
3405 requires forward_range<_Base>
3406 { return __x._M_i == __y._M_i; }
3408 friend constexpr bool
3409 operator==(const _InnerIter& __x, default_sentinel_t)
3410 { return __x.__at_end(); }
3412 friend constexpr decltype(auto)
3413 iter_move(const _InnerIter& __i)
3414 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3415 { return ranges::iter_move(__i._M_i_current()); }
3417 friend constexpr void
3418 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3419 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3420 __y._M_i_current())))
3421 requires indirectly_swappable<iterator_t<_Base>>
3422 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3425 _Vp _M_base = _Vp();
3426 _Pattern _M_pattern = _Pattern();
3427 [[no_unique_address]]
3428 __detail::__maybe_present_t<!forward_range<_Vp>,
3429 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3433 lazy_split_view() requires (default_initializable<_Vp>
3434 && default_initializable<_Pattern>)
3438 lazy_split_view(_Vp __base, _Pattern __pattern)
3439 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3442 template<input_range _Range>
3443 requires constructible_from<_Vp, views::all_t<_Range>>
3444 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3446 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3447 : _M_base(views::all(std::forward<_Range>(__r))),
3448 _M_pattern(views::single(std::move(__e)))
3452 base() const& requires copy_constructible<_Vp>
3457 { return std::move(_M_base); }
3462 if constexpr (forward_range<_Vp>)
3464 constexpr bool __simple
3465 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3466 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3470 _M_current = ranges::begin(_M_base);
3471 return _OuterIter<false>{this};
3476 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3478 return _OuterIter<true>{this, ranges::begin(_M_base)};
3482 end() requires forward_range<_Vp> && common_range<_Vp>
3484 constexpr bool __simple
3485 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3486 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3492 if constexpr (forward_range<_Vp>
3493 && forward_range<const _Vp>
3494 && common_range<const _Vp>)
3495 return _OuterIter<true>{this, ranges::end(_M_base)};
3497 return default_sentinel;
3501 template<typename _Range, typename _Pattern>
3502 lazy_split_view(_Range&&, _Pattern&&)
3503 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3505 template<input_range _Range>
3506 lazy_split_view(_Range&&, range_value_t<_Range>)
3507 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3513 template<typename _Range, typename _Pattern>
3514 concept __can_lazy_split_view
3515 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3516 } // namespace __detail
3518 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3520 template<viewable_range _Range, typename _Pattern>
3521 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3523 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3525 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3528 using _RangeAdaptor<_LazySplit>::operator();
3529 static constexpr int _S_arity = 2;
3530 // The pattern argument of views::lazy_split is not always simple -- it can be
3531 // a non-view range, the value category of which affects whether the call
3532 // is well-formed. But a scalar or a view pattern argument is surely
3534 template<typename _Pattern>
3535 static constexpr bool _S_has_simple_extra_args
3536 = is_scalar_v<_Pattern> || (view<_Pattern>
3537 && copy_constructible<_Pattern>);
3540 inline constexpr _LazySplit lazy_split;
3541 } // namespace views
3543 template<forward_range _Vp, forward_range _Pattern>
3544 requires view<_Vp> && view<_Pattern>
3545 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3547 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3550 _Vp _M_base = _Vp();
3551 _Pattern _M_pattern = _Pattern();
3552 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3558 split_view() requires (default_initializable<_Vp>
3559 && default_initializable<_Pattern>)
3563 split_view(_Vp __base, _Pattern __pattern)
3564 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3567 template<forward_range _Range>
3568 requires constructible_from<_Vp, views::all_t<_Range>>
3569 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3571 split_view(_Range&& __r, range_value_t<_Range> __e)
3572 : _M_base(views::all(std::forward<_Range>(__r))),
3573 _M_pattern(views::single(std::move(__e)))
3577 base() const& requires copy_constructible<_Vp>
3582 { return std::move(_M_base); }
3587 if (!_M_cached_begin)
3588 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3589 return {this, ranges::begin(_M_base), *_M_cached_begin};
3595 if constexpr (common_range<_Vp>)
3596 return _Iterator{this, ranges::end(_M_base), {}};
3598 return _Sentinel{this};
3601 constexpr subrange<iterator_t<_Vp>>
3602 _M_find_next(iterator_t<_Vp> __it)
3604 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3605 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3617 split_view* _M_parent = nullptr;
3618 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3619 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3620 bool _M_trailing_empty = false;
3622 friend struct _Sentinel;
3625 using iterator_concept = forward_iterator_tag;
3626 using iterator_category = input_iterator_tag;
3627 using value_type = subrange<iterator_t<_Vp>>;
3628 using difference_type = range_difference_t<_Vp>;
3630 _Iterator() = default;
3633 _Iterator(split_view* __parent,
3634 iterator_t<_Vp> __current,
3635 subrange<iterator_t<_Vp>> __next)
3636 : _M_parent(__parent),
3637 _M_cur(std::move(__current)),
3638 _M_next(std::move(__next))
3641 constexpr iterator_t<_Vp>
3645 constexpr value_type
3647 { return {_M_cur, _M_next.begin()}; }
3649 constexpr _Iterator&
3652 _M_cur = _M_next.begin();
3653 if (_M_cur != ranges::end(_M_parent->_M_base))
3655 _M_cur = _M_next.end();
3656 if (_M_cur == ranges::end(_M_parent->_M_base))
3658 _M_trailing_empty = true;
3659 _M_next = {_M_cur, _M_cur};
3662 _M_next = _M_parent->_M_find_next(_M_cur);
3665 _M_trailing_empty = false;
3677 friend constexpr bool
3678 operator==(const _Iterator& __x, const _Iterator& __y)
3680 return __x._M_cur == __y._M_cur
3681 && __x._M_trailing_empty == __y._M_trailing_empty;
3688 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3691 _M_equal(const _Iterator& __x) const
3692 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3695 _Sentinel() = default;
3698 _Sentinel(split_view* __parent)
3699 : _M_end(ranges::end(__parent->_M_base))
3702 friend constexpr bool
3703 operator==(const _Iterator& __x, const _Sentinel& __y)
3704 { return __y._M_equal(__x); }
3708 template<typename _Range, typename _Pattern>
3709 split_view(_Range&&, _Pattern&&)
3710 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3712 template<forward_range _Range>
3713 split_view(_Range&&, range_value_t<_Range>)
3714 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3720 template<typename _Range, typename _Pattern>
3721 concept __can_split_view
3722 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3723 } // namespace __detail
3725 struct _Split : __adaptor::_RangeAdaptor<_Split>
3727 template<viewable_range _Range, typename _Pattern>
3728 requires __detail::__can_split_view<_Range, _Pattern>
3730 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3732 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3735 using _RangeAdaptor<_Split>::operator();
3736 static constexpr int _S_arity = 2;
3737 template<typename _Pattern>
3738 static constexpr bool _S_has_simple_extra_args
3739 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3742 inline constexpr _Split split;
3743 } // namespace views
3749 template<input_or_output_iterator _Iter>
3751 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3753 if constexpr (contiguous_iterator<_Iter>)
3754 return span(std::__to_address(__i), __n);
3755 else if constexpr (random_access_iterator<_Iter>)
3756 return subrange(__i, __i + __n);
3758 return subrange(counted_iterator(std::move(__i), __n),
3763 inline constexpr _Counted counted{};
3764 } // namespace views
3767 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3768 class common_view : public view_interface<common_view<_Vp>>
3771 _Vp _M_base = _Vp();
3774 common_view() requires default_initializable<_Vp> = default;
3777 common_view(_Vp __r)
3778 : _M_base(std::move(__r))
3782 base() const& requires copy_constructible<_Vp>
3787 { return std::move(_M_base); }
3792 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3793 return ranges::begin(_M_base);
3795 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3796 (ranges::begin(_M_base));
3800 begin() const requires range<const _Vp>
3802 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3803 return ranges::begin(_M_base);
3805 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3806 (ranges::begin(_M_base));
3812 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3813 return ranges::begin(_M_base) + ranges::size(_M_base);
3815 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3816 (ranges::end(_M_base));
3820 end() const requires range<const _Vp>
3822 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3823 return ranges::begin(_M_base) + ranges::size(_M_base);
3825 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3826 (ranges::end(_M_base));
3830 size() requires sized_range<_Vp>
3831 { return ranges::size(_M_base); }
3834 size() const requires sized_range<const _Vp>
3835 { return ranges::size(_M_base); }
3838 template<typename _Range>
3839 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
3841 template<typename _Tp>
3842 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
3843 = enable_borrowed_range<_Tp>;
3849 template<typename _Range>
3850 concept __already_common = common_range<_Range>
3851 && requires { views::all(std::declval<_Range>()); };
3853 template<typename _Range>
3854 concept __can_common_view
3855 = requires { common_view{std::declval<_Range>()}; };
3856 } // namespace __detail
3858 struct _Common : __adaptor::_RangeAdaptorClosure
3860 template<viewable_range _Range>
3861 requires __detail::__already_common<_Range>
3862 || __detail::__can_common_view<_Range>
3864 operator() [[nodiscard]] (_Range&& __r) const
3866 if constexpr (__detail::__already_common<_Range>)
3867 return views::all(std::forward<_Range>(__r));
3869 return common_view{std::forward<_Range>(__r)};
3872 static constexpr bool _S_has_simple_call_op = true;
3875 inline constexpr _Common common;
3876 } // namespace views
3879 requires bidirectional_range<_Vp>
3880 class reverse_view : public view_interface<reverse_view<_Vp>>
3883 static constexpr bool _S_needs_cached_begin
3884 = !common_range<_Vp> && !(random_access_range<_Vp>
3885 && sized_sentinel_for<sentinel_t<_Vp>,
3888 _Vp _M_base = _Vp();
3889 [[no_unique_address]]
3890 __detail::__maybe_present_t<_S_needs_cached_begin,
3891 __detail::_CachedPosition<_Vp>>
3895 reverse_view() requires default_initializable<_Vp> = default;
3898 reverse_view(_Vp __r)
3899 : _M_base(std::move(__r))
3903 base() const& requires copy_constructible<_Vp>
3908 { return std::move(_M_base); }
3910 constexpr reverse_iterator<iterator_t<_Vp>>
3913 if constexpr (_S_needs_cached_begin)
3914 if (_M_cached_begin._M_has_value())
3915 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
3917 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
3918 if constexpr (_S_needs_cached_begin)
3919 _M_cached_begin._M_set(_M_base, __it);
3920 return std::make_reverse_iterator(std::move(__it));
3924 begin() requires common_range<_Vp>
3925 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3928 begin() const requires common_range<const _Vp>
3929 { return std::make_reverse_iterator(ranges::end(_M_base)); }
3931 constexpr reverse_iterator<iterator_t<_Vp>>
3933 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3936 end() const requires common_range<const _Vp>
3937 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
3940 size() requires sized_range<_Vp>
3941 { return ranges::size(_M_base); }
3944 size() const requires sized_range<const _Vp>
3945 { return ranges::size(_M_base); }
3948 template<typename _Range>
3949 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
3951 template<typename _Tp>
3952 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
3953 = enable_borrowed_range<_Tp>;
3960 inline constexpr bool __is_reversible_subrange = false;
3962 template<typename _Iter, subrange_kind _Kind>
3963 inline constexpr bool
3964 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
3965 reverse_iterator<_Iter>,
3969 inline constexpr bool __is_reverse_view = false;
3971 template<typename _Vp>
3972 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
3974 template<typename _Range>
3975 concept __can_reverse_view
3976 = requires { reverse_view{std::declval<_Range>()}; };
3977 } // namespace __detail
3979 struct _Reverse : __adaptor::_RangeAdaptorClosure
3981 template<viewable_range _Range>
3982 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
3983 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
3984 || __detail::__can_reverse_view<_Range>
3986 operator() [[nodiscard]] (_Range&& __r) const
3988 using _Tp = remove_cvref_t<_Range>;
3989 if constexpr (__detail::__is_reverse_view<_Tp>)
3990 return std::forward<_Range>(__r).base();
3991 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
3993 using _Iter = decltype(ranges::begin(__r).base());
3994 if constexpr (sized_range<_Tp>)
3995 return subrange<_Iter, _Iter, subrange_kind::sized>
3996 {__r.end().base(), __r.begin().base(), __r.size()};
3998 return subrange<_Iter, _Iter, subrange_kind::unsized>
3999 {__r.end().base(), __r.begin().base()};
4002 return reverse_view{std::forward<_Range>(__r)};
4005 static constexpr bool _S_has_simple_call_op = true;
4008 inline constexpr _Reverse reverse;
4009 } // namespace views
4013 template<typename _Tp, size_t _Nm>
4014 concept __has_tuple_element = requires(_Tp __t)
4016 typename tuple_size<_Tp>::type;
4017 requires _Nm < tuple_size_v<_Tp>;
4018 typename tuple_element_t<_Nm, _Tp>;
4019 { std::get<_Nm>(__t) }
4020 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4023 template<typename _Tp, size_t _Nm>
4024 concept __returnable_element
4025 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4028 template<input_range _Vp, size_t _Nm>
4030 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4031 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4033 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4034 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4037 elements_view() requires default_initializable<_Vp> = default;
4040 elements_view(_Vp __base)
4041 : _M_base(std::move(__base))
4045 base() const& requires copy_constructible<_Vp>
4050 { return std::move(_M_base); }
4053 begin() requires (!__detail::__simple_view<_Vp>)
4054 { return _Iterator<false>(ranges::begin(_M_base)); }
4057 begin() const requires range<const _Vp>
4058 { return _Iterator<true>(ranges::begin(_M_base)); }
4061 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4062 { return _Sentinel<false>{ranges::end(_M_base)}; }
4065 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4066 { return _Iterator<false>{ranges::end(_M_base)}; }
4069 end() const requires range<const _Vp>
4070 { return _Sentinel<true>{ranges::end(_M_base)}; }
4073 end() const requires common_range<const _Vp>
4074 { return _Iterator<true>{ranges::end(_M_base)}; }
4077 size() requires sized_range<_Vp>
4078 { return ranges::size(_M_base); }
4081 size() const requires sized_range<const _Vp>
4082 { return ranges::size(_M_base); }
4085 template<bool _Const>
4086 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4088 template<bool _Const>
4092 template<bool _Const>
4093 requires forward_range<_Base<_Const>>
4094 struct __iter_cat<_Const>
4097 static auto _S_iter_cat()
4099 using _Base = elements_view::_Base<_Const>;
4100 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4101 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4102 if constexpr (!is_lvalue_reference_v<_Res>)
4103 return input_iterator_tag{};
4104 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4105 return random_access_iterator_tag{};
4110 using iterator_category = decltype(_S_iter_cat());
4113 template<bool _Const>
4116 template<bool _Const>
4117 struct _Iterator : __iter_cat<_Const>
4120 using _Base = elements_view::_Base<_Const>;
4122 iterator_t<_Base> _M_current = iterator_t<_Base>();
4124 static constexpr decltype(auto)
4125 _S_get_element(const iterator_t<_Base>& __i)
4127 if constexpr (is_reference_v<range_reference_t<_Base>>)
4128 return std::get<_Nm>(*__i);
4131 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4132 return static_cast<_Et>(std::get<_Nm>(*__i));
4139 if constexpr (random_access_range<_Base>)
4140 return random_access_iterator_tag{};
4141 else if constexpr (bidirectional_range<_Base>)
4142 return bidirectional_iterator_tag{};
4143 else if constexpr (forward_range<_Base>)
4144 return forward_iterator_tag{};
4146 return input_iterator_tag{};
4149 friend _Iterator<!_Const>;
4152 using iterator_concept = decltype(_S_iter_concept());
4153 // iterator_category defined in elements_view::__iter_cat
4155 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4156 using difference_type = range_difference_t<_Base>;
4158 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4161 _Iterator(iterator_t<_Base> __current)
4162 : _M_current(std::move(__current))
4166 _Iterator(_Iterator<!_Const> __i)
4167 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4168 : _M_current(std::move(__i._M_current))
4171 constexpr const iterator_t<_Base>&
4172 base() const& noexcept
4173 { return _M_current; }
4175 constexpr iterator_t<_Base>
4177 { return std::move(_M_current); }
4179 constexpr decltype(auto)
4181 { return _S_get_element(_M_current); }
4183 constexpr _Iterator&
4195 operator++(int) requires forward_range<_Base>
4202 constexpr _Iterator&
4203 operator--() requires bidirectional_range<_Base>
4210 operator--(int) requires bidirectional_range<_Base>
4217 constexpr _Iterator&
4218 operator+=(difference_type __n)
4219 requires random_access_range<_Base>
4225 constexpr _Iterator&
4226 operator-=(difference_type __n)
4227 requires random_access_range<_Base>
4233 constexpr decltype(auto)
4234 operator[](difference_type __n) const
4235 requires random_access_range<_Base>
4236 { return _S_get_element(_M_current + __n); }
4238 friend constexpr bool
4239 operator==(const _Iterator& __x, const _Iterator& __y)
4240 requires equality_comparable<iterator_t<_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 __x._M_current < __y._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 !(__y._M_current > __x._M_current); }
4258 friend constexpr bool
4259 operator>=(const _Iterator& __x, const _Iterator& __y)
4260 requires random_access_range<_Base>
4261 { return !(__x._M_current > __y._M_current); }
4263#ifdef __cpp_lib_three_way_comparison
4264 friend constexpr auto
4265 operator<=>(const _Iterator& __x, const _Iterator& __y)
4266 requires random_access_range<_Base>
4267 && three_way_comparable<iterator_t<_Base>>
4268 { return __x._M_current <=> __y._M_current; }
4271 friend constexpr _Iterator
4272 operator+(const _Iterator& __x, difference_type __y)
4273 requires random_access_range<_Base>
4274 { return _Iterator{__x} += __y; }
4276 friend constexpr _Iterator
4277 operator+(difference_type __x, const _Iterator& __y)
4278 requires random_access_range<_Base>
4279 { return __y + __x; }
4281 friend constexpr _Iterator
4282 operator-(const _Iterator& __x, difference_type __y)
4283 requires random_access_range<_Base>
4284 { return _Iterator{__x} -= __y; }
4286 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4287 // 3483. transform_view::iterator's difference is overconstrained
4288 friend constexpr difference_type
4289 operator-(const _Iterator& __x, const _Iterator& __y)
4290 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4291 { return __x._M_current - __y._M_current; }
4293 template <bool> friend struct _Sentinel;
4296 template<bool _Const>
4300 template<bool _Const2>
4302 _M_equal(const _Iterator<_Const2>& __x) const
4303 { return __x._M_current == _M_end; }
4305 template<bool _Const2>
4307 _M_distance_from(const _Iterator<_Const2>& __i) const
4308 { return _M_end - __i._M_current; }
4310 using _Base = elements_view::_Base<_Const>;
4311 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4314 _Sentinel() = default;
4317 _Sentinel(sentinel_t<_Base> __end)
4318 : _M_end(std::move(__end))
4322 _Sentinel(_Sentinel<!_Const> __other)
4324 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4325 : _M_end(std::move(__other._M_end))
4328 constexpr sentinel_t<_Base>
4332 template<bool _Const2>
4333 requires sentinel_for<sentinel_t<_Base>,
4334 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4335 friend constexpr bool
4336 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4337 { return __y._M_equal(__x); }
4339 template<bool _Const2,
4340 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4341 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4342 friend constexpr range_difference_t<_Base2>
4343 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4344 { return -__y._M_distance_from(__x); }
4346 template<bool _Const2,
4347 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4348 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4349 friend constexpr range_difference_t<_Base2>
4350 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4351 { return __x._M_distance_from(__y); }
4353 friend _Sentinel<!_Const>;
4356 _Vp _M_base = _Vp();
4359 template<typename _Tp, size_t _Nm>
4360 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4361 = enable_borrowed_range<_Tp>;
4363 template<typename _Range>
4364 using keys_view = elements_view<views::all_t<_Range>, 0>;
4366 template<typename _Range>
4367 using values_view = elements_view<views::all_t<_Range>, 1>;
4373 template<size_t _Nm, typename _Range>
4374 concept __can_elements_view
4375 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4376 } // namespace __detail
4378 template<size_t _Nm>
4379 struct _Elements : __adaptor::_RangeAdaptorClosure
4381 template<viewable_range _Range>
4382 requires __detail::__can_elements_view<_Nm, _Range>
4384 operator() [[nodiscard]] (_Range&& __r) const
4386 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4389 static constexpr bool _S_has_simple_call_op = true;
4392 template<size_t _Nm>
4393 inline constexpr _Elements<_Nm> elements;
4394 inline constexpr auto keys = elements<0>;
4395 inline constexpr auto values = elements<1>;
4396 } // namespace views
4398#if __cplusplus > 202002L
4400#define __cpp_lib_ranges_zip 202110L
4404 template<typename... _Rs>
4405 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4406 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4407 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4409 template<typename... _Ts>
4410 struct __tuple_or_pair
4411 { using type = std::tuple<_Ts...>; };
4413 template<typename _Tp, typename _Up>
4414 struct __tuple_or_pair<_Tp, _Up>
4415 { using type = pair<_Tp, _Up>; };
4417 template<typename... _Ts>
4418 using __tuple_or_pair_t = typename __tuple_or_pair<_Ts...>::type;
4420 template<typename _Fp, typename _Tuple>
4422 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4424 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4425 return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
4426 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4427 }, std::forward<_Tuple>(__tuple));
4430 template<typename _Fp, typename _Tuple>
4432 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4434 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4435 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4436 }, std::forward<_Tuple>(__tuple));
4438 } // namespace __detail
4440 template<input_range... _Vs>
4441 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4442 class zip_view : public view_interface<zip_view<_Vs...>>
4444 tuple<_Vs...> _M_views;
4446 template<bool> class _Iterator;
4447 template<bool> class _Sentinel;
4450 zip_view() = default;
4453 zip_view(_Vs... __views)
4454 : _M_views(std::move(__views)...)
4458 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4459 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4462 begin() const requires (range<const _Vs> && ...)
4463 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4466 end() requires (!(__detail::__simple_view<_Vs> && ...))
4468 if constexpr (!__detail::__zip_is_common<_Vs...>)
4469 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4470 else if constexpr ((random_access_range<_Vs> && ...))
4471 return begin() + iter_difference_t<_Iterator<false>>(size());
4473 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4477 end() const requires (range<const _Vs> && ...)
4479 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4480 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4481 else if constexpr ((random_access_range<const _Vs> && ...))
4482 return begin() + iter_difference_t<_Iterator<true>>(size());
4484 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4488 size() requires (sized_range<_Vs> && ...)
4490 return std::apply([](auto... sizes) {
4491 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4492 return ranges::min({_CT(sizes)...});
4493 }, __detail::__tuple_transform(ranges::size, _M_views));
4497 size() const requires (sized_range<const _Vs> && ...)
4499 return std::apply([](auto... sizes) {
4500 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4501 return ranges::min({_CT(sizes)...});
4502 }, __detail::__tuple_transform(ranges::size, _M_views));
4506 template<typename... _Rs>
4507 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4509 template<typename... _Views>
4510 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4511 = (enable_borrowed_range<_Views> && ...);
4515 template<bool _Const, typename... _Vs>
4516 concept __all_random_access
4517 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4519 template<bool _Const, typename... _Vs>
4520 concept __all_bidirectional
4521 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4523 template<bool _Const, typename... _Vs>
4524 concept __all_forward
4525 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4527 template<bool _Const, typename... _Views>
4528 struct __zip_view_iter_cat
4531 template<bool _Const, typename... _Views>
4532 requires __all_forward<_Const, _Views...>
4533 struct __zip_view_iter_cat<_Const, _Views...>
4534 { using iterator_category = input_iterator_tag; };
4535 } // namespace __detail
4537 template<input_range... _Vs>
4538 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4539 template<bool _Const>
4540 class zip_view<_Vs...>::_Iterator
4541 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4543#ifdef __clang__ // LLVM-61763 workaround
4546 __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4549 _Iterator(decltype(_M_current) __current)
4550 : _M_current(std::move(__current))
4556 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4557 return random_access_iterator_tag{};
4558 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4559 return bidirectional_iterator_tag{};
4560 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4561 return forward_iterator_tag{};
4563 return input_iterator_tag{};
4566#ifndef __clang__ // LLVM-61763 workaround
4567 template<copy_constructible _Fp, input_range... _Ws>
4568 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4569 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4570 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4571 friend class zip_transform_view;
4575 // iterator_category defined in __zip_view_iter_cat
4576 using iterator_concept = decltype(_S_iter_concept());
4578 = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4579 using difference_type
4580 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4582 _Iterator() = default;
4585 _Iterator(_Iterator<!_Const> __i)
4587 && (convertible_to<iterator_t<_Vs>,
4588 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4589 : _M_current(std::move(__i._M_current))
4595 auto __f = [](auto& __i) -> decltype(auto) {
4598 return __detail::__tuple_transform(__f, _M_current);
4601 constexpr _Iterator&
4604 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4614 requires __detail::__all_forward<_Const, _Vs...>
4621 constexpr _Iterator&
4623 requires __detail::__all_bidirectional<_Const, _Vs...>
4625 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4631 requires __detail::__all_bidirectional<_Const, _Vs...>
4638 constexpr _Iterator&
4639 operator+=(difference_type __x)
4640 requires __detail::__all_random_access<_Const, _Vs...>
4642 auto __f = [&]<typename _It>(_It& __i) {
4643 __i += iter_difference_t<_It>(__x);
4645 __detail::__tuple_for_each(__f, _M_current);
4649 constexpr _Iterator&
4650 operator-=(difference_type __x)
4651 requires __detail::__all_random_access<_Const, _Vs...>
4653 auto __f = [&]<typename _It>(_It& __i) {
4654 __i -= iter_difference_t<_It>(__x);
4656 __detail::__tuple_for_each(__f, _M_current);
4661 operator[](difference_type __n) const
4662 requires __detail::__all_random_access<_Const, _Vs...>
4664 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4665 return __i[iter_difference_t<_It>(__n)];
4667 return __detail::__tuple_transform(__f, _M_current);
4670 friend constexpr bool
4671 operator==(const _Iterator& __x, const _Iterator& __y)
4672 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4674 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4675 return __x._M_current == __y._M_current;
4677 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4678 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4679 }(make_index_sequence<sizeof...(_Vs)>{});
4682 friend constexpr auto
4683 operator<=>(const _Iterator& __x, const _Iterator& __y)
4684 requires __detail::__all_random_access<_Const, _Vs...>
4685 { return __x._M_current <=> __y._M_current; }
4687 friend constexpr _Iterator
4688 operator+(const _Iterator& __i, difference_type __n)
4689 requires __detail::__all_random_access<_Const, _Vs...>
4696 friend constexpr _Iterator
4697 operator+(difference_type __n, const _Iterator& __i)
4698 requires __detail::__all_random_access<_Const, _Vs...>
4705 friend constexpr _Iterator
4706 operator-(const _Iterator& __i, difference_type __n)
4707 requires __detail::__all_random_access<_Const, _Vs...>
4714 friend constexpr difference_type
4715 operator-(const _Iterator& __x, const _Iterator& __y)
4716 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4717 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4719 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4720 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4721 - std::get<_Is>(__y._M_current))...},
4723 [](difference_type __i) {
4724 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4726 }(make_index_sequence<sizeof...(_Vs)>{});
4729 friend constexpr auto
4730 iter_move(const _Iterator& __i)
4731 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4733 friend constexpr void
4734 iter_swap(const _Iterator& __l, const _Iterator& __r)
4735 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4737 [&]<size_t... _Is>(index_sequence<_Is...>) {
4738 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4739 }(make_index_sequence<sizeof...(_Vs)>{});
4742 friend class zip_view;
4745 template<input_range... _Vs>
4746 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4747 template<bool _Const>
4748 class zip_view<_Vs...>::_Sentinel
4750 __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4753 _Sentinel(decltype(_M_end) __end)
4757 friend class zip_view;
4760 _Sentinel() = default;
4763 _Sentinel(_Sentinel<!_Const> __i)
4765 && (convertible_to<sentinel_t<_Vs>,
4766 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4767 : _M_end(std::move(__i._M_end))
4770 template<bool _OtherConst>
4771 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4772 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4773 friend constexpr bool
4774 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4776 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4777 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4778 }(make_index_sequence<sizeof...(_Vs)>{});
4781 template<bool _OtherConst>
4782 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4783 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4784 friend constexpr auto
4785 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4788 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4789 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4790 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4793 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4795 }(make_index_sequence<sizeof...(_Vs)>{});
4798 template<bool _OtherConst>
4799 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4800 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4801 friend constexpr auto
4802 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4803 { return -(__x - __y); }
4810 template<typename... _Ts>
4811 concept __can_zip_view
4812 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4817 template<typename... _Ts>
4818 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4820 operator() [[nodiscard]] (_Ts&&... __ts) const
4822 if constexpr (sizeof...(_Ts) == 0)
4823 return views::empty<tuple<>>;
4825 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
4829 inline constexpr _Zip zip;
4834 template<typename _Range, bool _Const>
4835 using __range_iter_cat
4836 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
4839 template<copy_constructible _Fp, input_range... _Vs>
4840 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4841 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4842 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4843 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
4845 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
4846 zip_view<_Vs...> _M_zip;
4848 using _InnerView = zip_view<_Vs...>;
4850 template<bool _Const>
4851 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4853 template<bool _Const>
4854 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
4856 template<bool _Const>
4857 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
4859 template<bool _Const>
4863 template<bool _Const>
4864 requires forward_range<_Base<_Const>>
4865 struct __iter_cat<_Const>
4871 using __detail::__maybe_const_t;
4872 using __detail::__range_iter_cat;
4873 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
4874 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
4875 if constexpr (!is_lvalue_reference_v<_Res>)
4876 return input_iterator_tag{};
4877 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4878 random_access_iterator_tag> && ...))
4879 return random_access_iterator_tag{};
4880 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4881 bidirectional_iterator_tag> && ...))
4882 return bidirectional_iterator_tag{};
4883 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
4884 forward_iterator_tag> && ...))
4885 return forward_iterator_tag{};
4887 return input_iterator_tag{};
4890 using iterator_category = decltype(_S_iter_cat());
4893 template<bool> class _Iterator;
4894 template<bool> class _Sentinel;
4897 zip_transform_view() = default;
4900 zip_transform_view(_Fp __fun, _Vs... __views)
4901 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
4906 { return _Iterator<false>(*this, _M_zip.begin()); }
4910 requires range<const _InnerView>
4911 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4912 { return _Iterator<true>(*this, _M_zip.begin()); }
4917 if constexpr (common_range<_InnerView>)
4918 return _Iterator<false>(*this, _M_zip.end());
4920 return _Sentinel<false>(_M_zip.end());
4925 requires range<const _InnerView>
4926 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
4928 if constexpr (common_range<const _InnerView>)
4929 return _Iterator<true>(*this, _M_zip.end());
4931 return _Sentinel<true>(_M_zip.end());
4935 size() requires sized_range<_InnerView>
4936 { return _M_zip.size(); }
4939 size() const requires sized_range<const _InnerView>
4940 { return _M_zip.size(); }
4943 template<class _Fp, class... Rs>
4944 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
4946 template<copy_constructible _Fp, input_range... _Vs>
4947 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
4948 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
4949 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
4950 template<bool _Const>
4951 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
4953 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
4955 _Parent* _M_parent = nullptr;
4956 __ziperator<_Const> _M_inner;
4959 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
4960 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
4963 friend class zip_transform_view;
4966 // iterator_category defined in zip_transform_view::__iter_cat
4967 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
4969 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
4970 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
4971 using difference_type = range_difference_t<_Base<_Const>>;
4973 _Iterator() = default;
4976 _Iterator(_Iterator<!_Const> __i)
4977 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
4978 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
4981 constexpr decltype(auto)
4984 return std::apply([&](const auto&... __iters) -> decltype(auto) {
4985 return std::__invoke(*_M_parent->_M_fun, *__iters...);
4986 }, _M_inner._M_current);
4989 constexpr _Iterator&
5001 operator++(int) requires forward_range<_Base<_Const>>
5008 constexpr _Iterator&
5009 operator--() requires bidirectional_range<_Base<_Const>>
5016 operator--(int) requires bidirectional_range<_Base<_Const>>
5023 constexpr _Iterator&
5024 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5030 constexpr _Iterator&
5031 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5037 constexpr decltype(auto)
5038 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5040 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5041 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5042 }, _M_inner._M_current);
5045 friend constexpr bool
5046 operator==(const _Iterator& __x, const _Iterator& __y)
5047 requires equality_comparable<__ziperator<_Const>>
5048 { return __x._M_inner == __y._M_inner; }
5050 friend constexpr auto
5051 operator<=>(const _Iterator& __x, const _Iterator& __y)
5052 requires random_access_range<_Base<_Const>>
5053 { return __x._M_inner <=> __y._M_inner; }
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 _Iterator
5061 operator+(difference_type __n, const _Iterator& __i)
5062 requires random_access_range<_Base<_Const>>
5063 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5065 friend constexpr _Iterator
5066 operator-(const _Iterator& __i, difference_type __n)
5067 requires random_access_range<_Base<_Const>>
5068 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5070 friend constexpr difference_type
5071 operator-(const _Iterator& __x, const _Iterator& __y)
5072 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5073 { return __x._M_inner - __y._M_inner; }
5076 template<copy_constructible _Fp, input_range... _Vs>
5077 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5078 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5079 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5080 template<bool _Const>
5081 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5083 __zentinel<_Const> _M_inner;
5086 _Sentinel(__zentinel<_Const> __inner)
5090 friend class zip_transform_view;
5093 _Sentinel() = default;
5096 _Sentinel(_Sentinel<!_Const> __i)
5097 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5098 : _M_inner(std::move(__i._M_inner))
5101 template<bool _OtherConst>
5102 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5103 friend constexpr bool
5104 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5105 { return __x._M_inner == __y._M_inner; }
5107 template<bool _OtherConst>
5108 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5109 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5110 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5111 { return __x._M_inner - __y._M_inner; }
5113 template<bool _OtherConst>
5114 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5115 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5116 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5117 { return __x._M_inner - __y._M_inner; }
5124 template<typename _Fp, typename... _Ts>
5125 concept __can_zip_transform_view
5126 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5129 struct _ZipTransform
5131 template<typename _Fp, typename... _Ts>
5132 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5134 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5136 if constexpr (sizeof...(_Ts) == 0)
5137 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5139 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5143 inline constexpr _ZipTransform zip_transform;
5146 template<forward_range _Vp, size_t _Nm>
5147 requires view<_Vp> && (_Nm > 0)
5148 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5150 _Vp _M_base = _Vp();
5152 template<bool> class _Iterator;
5153 template<bool> class _Sentinel;
5155 struct __as_sentinel
5159 adjacent_view() requires default_initializable<_Vp> = default;
5162 adjacent_view(_Vp __base)
5163 : _M_base(std::move(__base))
5167 begin() requires (!__detail::__simple_view<_Vp>)
5168 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5171 begin() const requires range<const _Vp>
5172 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5175 end() requires (!__detail::__simple_view<_Vp>)
5177 if constexpr (common_range<_Vp>)
5178 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5180 return _Sentinel<false>(ranges::end(_M_base));
5184 end() const requires range<const _Vp>
5186 if constexpr (common_range<const _Vp>)
5187 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5189 return _Sentinel<true>(ranges::end(_M_base));
5193 size() requires sized_range<_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 size() const requires sized_range<const _Vp>
5205 using _ST = decltype(ranges::size(_M_base));
5206 using _CT = common_type_t<_ST, size_t>;
5207 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5208 __sz -= std::min<_CT>(__sz, _Nm - 1);
5209 return static_cast<_ST>(__sz);
5213 template<typename _Vp, size_t _Nm>
5214 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5215 = enable_borrowed_range<_Vp>;
5219 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5220 template<typename _Tp, size_t _Nm>
5221 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5223 // For a functor F that is callable with N arguments, the expression
5224 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5225 template<typename _Fp, size_t _Nm>
5228 template<typename... _Ts>
5229 static invoke_result_t<_Fp, _Ts...>
5230 __tuple_apply(const tuple<_Ts...>&); // not defined
5232 template<typename _Tp>
5233 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5234 operator()(_Tp&&); // not defined
5238 template<forward_range _Vp, size_t _Nm>
5239 requires view<_Vp> && (_Nm > 0)
5240 template<bool _Const>
5241 class adjacent_view<_Vp, _Nm>::_Iterator
5243#ifdef __clang__ // LLVM-61763 workaround
5246 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5247 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5250 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5252 for (auto& __i : _M_current)
5255 ranges::advance(__first, 1, __last);
5260 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5262 if constexpr (!bidirectional_range<_Base>)
5263 for (auto& __it : _M_current)
5266 for (size_t __i = 0; __i < _Nm; ++__i)
5268 _M_current[_Nm - 1 - __i] = __last;
5269 ranges::advance(__last, -1, __first);
5276 if constexpr (random_access_range<_Base>)
5277 return random_access_iterator_tag{};
5278 else if constexpr (bidirectional_range<_Base>)
5279 return bidirectional_iterator_tag{};
5281 return forward_iterator_tag{};
5284 friend class adjacent_view;
5286#ifndef __clang__ // LLVM-61763 workaround
5287 template<forward_range _Wp, copy_constructible _Fp, size_t _Mm>
5288 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5289 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5290 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5291 range_reference_t<_Wp>>>
5292 friend class adjacent_transform_view;
5296 using iterator_category = input_iterator_tag;
5297 using iterator_concept = decltype(_S_iter_concept());
5298 using value_type = conditional_t<_Nm == 2,
5299 pair<range_value_t<_Base>, range_value_t<_Base>>,
5300 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5301 using difference_type = range_difference_t<_Base>;
5303 _Iterator() = default;
5306 _Iterator(_Iterator<!_Const> __i)
5307 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5309 for (size_t __j = 0; __j < _Nm; ++__j)
5310 _M_current[__j] = std::move(__i._M_current[__j]);
5316 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5317 return __detail::__tuple_transform(__f, _M_current);
5320 constexpr _Iterator&
5323 for (auto& __i : _M_current)
5336 constexpr _Iterator&
5337 operator--() requires bidirectional_range<_Base>
5339 for (auto& __i : _M_current)
5345 operator--(int) requires bidirectional_range<_Base>
5352 constexpr _Iterator&
5353 operator+=(difference_type __x)
5354 requires random_access_range<_Base>
5356 for (auto& __i : _M_current)
5361 constexpr _Iterator&
5362 operator-=(difference_type __x)
5363 requires random_access_range<_Base>
5365 for (auto& __i : _M_current)
5371 operator[](difference_type __n) const
5372 requires random_access_range<_Base>
5374 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5375 return __detail::__tuple_transform(__f, _M_current);
5378 friend constexpr bool
5379 operator==(const _Iterator& __x, const _Iterator& __y)
5380 { return __x._M_current.back() == __y._M_current.back(); }
5382 friend constexpr bool
5383 operator<(const _Iterator& __x, const _Iterator& __y)
5384 requires random_access_range<_Base>
5385 { return __x._M_current.back() < __y._M_current.back(); }
5387 friend constexpr bool
5388 operator>(const _Iterator& __x, const _Iterator& __y)
5389 requires random_access_range<_Base>
5390 { return __y < __x; }
5392 friend constexpr bool
5393 operator<=(const _Iterator& __x, const _Iterator& __y)
5394 requires random_access_range<_Base>
5395 { return !(__y < __x); }
5397 friend constexpr bool
5398 operator>=(const _Iterator& __x, const _Iterator& __y)
5399 requires random_access_range<_Base>
5400 { return !(__x < __y); }
5402 friend constexpr auto
5403 operator<=>(const _Iterator& __x, const _Iterator& __y)
5404 requires random_access_range<_Base>
5405 && three_way_comparable<iterator_t<_Base>>
5406 { return __x._M_current.back() <=> __y._M_current.back(); }
5408 friend constexpr _Iterator
5409 operator+(const _Iterator& __i, difference_type __n)
5410 requires random_access_range<_Base>
5417 friend constexpr _Iterator
5418 operator+(difference_type __n, const _Iterator& __i)
5419 requires random_access_range<_Base>
5426 friend constexpr _Iterator
5427 operator-(const _Iterator& __i, difference_type __n)
5428 requires random_access_range<_Base>
5435 friend constexpr difference_type
5436 operator-(const _Iterator& __x, const _Iterator& __y)
5437 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5438 { return __x._M_current.back() - __y._M_current.back(); }
5440 friend constexpr auto
5441 iter_move(const _Iterator& __i)
5442 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5444 friend constexpr void
5445 iter_swap(const _Iterator& __l, const _Iterator& __r)
5446 requires indirectly_swappable<iterator_t<_Base>>
5448 for (size_t __i = 0; __i < _Nm; __i++)
5449 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5453 template<forward_range _Vp, size_t _Nm>
5454 requires view<_Vp> && (_Nm > 0)
5455 template<bool _Const>
5456 class adjacent_view<_Vp, _Nm>::_Sentinel
5458 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5460 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5463 _Sentinel(sentinel_t<_Base> __end)
5467 friend class adjacent_view;
5470 _Sentinel() = default;
5473 _Sentinel(_Sentinel<!_Const> __i)
5474 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5475 : _M_end(std::move(__i._M_end))
5478 template<bool _OtherConst>
5479 requires sentinel_for<sentinel_t<_Base>,
5480 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5481 friend constexpr bool
5482 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5483 { return __x._M_current.back() == __y._M_end; }
5485 template<bool _OtherConst>
5486 requires sized_sentinel_for<sentinel_t<_Base>,
5487 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5488 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5489 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5490 { return __x._M_current.back() - __y._M_end; }
5492 template<bool _OtherConst>
5493 requires sized_sentinel_for<sentinel_t<_Base>,
5494 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5495 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5496 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5497 { return __y._M_end - __x._M_current.back(); }
5504 template<size_t _Nm, typename _Range>
5505 concept __can_adjacent_view
5506 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5509 template<size_t _Nm>
5510 struct _Adjacent : __adaptor::_RangeAdaptorClosure
5512 template<viewable_range _Range>
5513 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5515 operator() [[nodiscard]] (_Range&& __r) const
5517 if constexpr (_Nm == 0)
5518 return views::empty<tuple<>>;
5520 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5524 template<size_t _Nm>
5525 inline constexpr _Adjacent<_Nm> adjacent;
5527 inline constexpr auto pairwise = adjacent<2>;
5530 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5531 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5532 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5533 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5534 range_reference_t<_Vp>>>
5535 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5537 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5538 adjacent_view<_Vp, _Nm> _M_inner;
5540 using _InnerView = adjacent_view<_Vp, _Nm>;
5542 template<bool _Const>
5543 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5545 template<bool _Const>
5546 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5548 template<bool> class _Iterator;
5549 template<bool> class _Sentinel;
5552 adjacent_transform_view() = default;
5555 adjacent_transform_view(_Vp __base, _Fp __fun)
5556 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5561 { return _Iterator<false>(*this, _M_inner.begin()); }
5565 requires range<const _InnerView>
5566 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5567 range_reference_t<const _Vp>>
5568 { return _Iterator<true>(*this, _M_inner.begin()); }
5573 if constexpr (common_range<_InnerView>)
5574 return _Iterator<false>(*this, _M_inner.end());
5576 return _Sentinel<false>(_M_inner.end());
5581 requires range<const _InnerView>
5582 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5583 range_reference_t<const _Vp>>
5585 if constexpr (common_range<const _InnerView>)
5586 return _Iterator<true>(*this, _M_inner.end());
5588 return _Sentinel<true>(_M_inner.end());
5592 size() requires sized_range<_InnerView>
5593 { return _M_inner.size(); }
5596 size() const requires sized_range<const _InnerView>
5597 { return _M_inner.size(); }
5600 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5601 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5602 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5603 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5604 range_reference_t<_Vp>>>
5605 template<bool _Const>
5606 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5608 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5609 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5611 _Parent* _M_parent = nullptr;
5612 _InnerIter<_Const> _M_inner;
5615 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5616 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5622 using __detail::__maybe_const_t;
5623 using __detail::__unarize;
5624 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5625 range_reference_t<_Base>>;
5626 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5627 if constexpr (!is_lvalue_reference_v<_Res>)
5628 return input_iterator_tag{};
5629 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5630 return random_access_iterator_tag{};
5631 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5632 return bidirectional_iterator_tag{};
5633 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5634 return forward_iterator_tag{};
5636 return input_iterator_tag{};
5639 friend class adjacent_transform_view;
5642 using iterator_category = decltype(_S_iter_cat());
5643 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5645 = remove_cvref_t<invoke_result_t
5646 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5647 range_reference_t<_Base>>>;
5648 using difference_type = range_difference_t<_Base>;
5650 _Iterator() = default;
5653 _Iterator(_Iterator<!_Const> __i)
5654 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5655 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5658 constexpr decltype(auto)
5661 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5662 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5663 }, _M_inner._M_current);
5666 constexpr _Iterator&
5681 constexpr _Iterator&
5682 operator--() requires bidirectional_range<_Base>
5689 operator--(int) requires bidirectional_range<_Base>
5696 constexpr _Iterator&
5697 operator+=(difference_type __x) requires random_access_range<_Base>
5703 constexpr _Iterator&
5704 operator-=(difference_type __x) requires random_access_range<_Base>
5710 constexpr decltype(auto)
5711 operator[](difference_type __n) const requires random_access_range<_Base>
5713 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5714 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5715 }, _M_inner._M_current);
5718 friend constexpr bool
5719 operator==(const _Iterator& __x, const _Iterator& __y)
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 bool
5728 operator>(const _Iterator& __x, const _Iterator& __y)
5729 requires random_access_range<_Base>
5730 { return __x._M_inner > __y._M_inner; }
5732 friend constexpr bool
5733 operator<=(const _Iterator& __x, const _Iterator& __y)
5734 requires random_access_range<_Base>
5735 { return __x._M_inner <= __y._M_inner; }
5737 friend constexpr bool
5738 operator>=(const _Iterator& __x, const _Iterator& __y)
5739 requires random_access_range<_Base>
5740 { return __x._M_inner >= __y._M_inner; }
5742 friend constexpr auto
5743 operator<=>(const _Iterator& __x, const _Iterator& __y)
5744 requires random_access_range<_Base> &&
5745 three_way_comparable<_InnerIter<_Const>>
5746 { return __x._M_inner <=> __y._M_inner; }
5748 friend constexpr _Iterator
5749 operator+(const _Iterator& __i, difference_type __n)
5750 requires random_access_range<_Base>
5751 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5753 friend constexpr _Iterator
5754 operator+(difference_type __n, const _Iterator& __i)
5755 requires random_access_range<_Base>
5756 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5758 friend constexpr _Iterator
5759 operator-(const _Iterator& __i, difference_type __n)
5760 requires random_access_range<_Base>
5761 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5763 friend constexpr difference_type
5764 operator-(const _Iterator& __x, const _Iterator& __y)
5765 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5766 { return __x._M_inner - __y._M_inner; }
5769 template<forward_range _Vp, copy_constructible _Fp, size_t _Nm>
5770 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5771 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5772 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5773 range_reference_t<_Vp>>>
5774 template<bool _Const>
5775 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5777 _InnerSent<_Const> _M_inner;
5780 _Sentinel(_InnerSent<_Const> __inner)
5784 friend class adjacent_transform_view;
5787 _Sentinel() = default;
5790 _Sentinel(_Sentinel<!_Const> __i)
5791 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5792 : _M_inner(std::move(__i._M_inner))
5795 template<bool _OtherConst>
5796 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5797 friend constexpr bool
5798 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5799 { return __x._M_inner == __y._M_inner; }
5801 template<bool _OtherConst>
5802 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5803 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5804 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5805 { return __x._M_inner - __y._M_inner; }
5807 template<bool _OtherConst>
5808 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5809 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5810 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5811 { return __x._M_inner - __y._M_inner; }
5818 template<size_t _Nm, typename _Range, typename _Fp>
5819 concept __can_adjacent_transform_view
5820 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5821 (std::declval<_Range>(), std::declval<_Fp>()); };
5824 template<size_t _Nm>
5825 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
5827 template<viewable_range _Range, typename _Fp>
5828 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
5830 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
5832 if constexpr (_Nm == 0)
5833 return zip_transform(std::forward<_Fp>(__f));
5835 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
5836 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
5839 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
5840 static constexpr int _S_arity = 2;
5841 static constexpr bool _S_has_simple_extra_args = true;
5844 template<size_t _Nm>
5845 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
5847 inline constexpr auto pairwise_transform = adjacent_transform<2>;
5850#define __cpp_lib_ranges_chunk 202202L
5854 template<typename _Tp>
5855 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
5857 _Tp __r = __num / __denom;
5858 if (__num % __denom)
5865 requires input_range<_Vp>
5866 class chunk_view : public view_interface<chunk_view<_Vp>>
5869 range_difference_t<_Vp> _M_n;
5870 range_difference_t<_Vp> _M_remainder = 0;
5871 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
5878 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
5879 : _M_base(std::move(__base)), _M_n(__n)
5880 { __glibcxx_assert(__n >= 0); }
5883 base() const & requires copy_constructible<_Vp>
5888 { return std::move(_M_base); }
5890 constexpr _OuterIter
5893 _M_current = ranges::begin(_M_base);
5894 _M_remainder = _M_n;
5895 return _OuterIter(*this);
5898 constexpr default_sentinel_t
5899 end() const noexcept
5900 { return default_sentinel; }
5903 size() requires sized_range<_Vp>
5905 return __detail::__to_unsigned_like(__detail::__div_ceil
5906 (ranges::distance(_M_base), _M_n));
5910 size() const requires sized_range<const _Vp>
5912 return __detail::__to_unsigned_like(__detail::__div_ceil
5913 (ranges::distance(_M_base), _M_n));
5917 template<typename _Range>
5918 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
5921 requires input_range<_Vp>
5922 class chunk_view<_Vp>::_OuterIter
5924 chunk_view* _M_parent;
5927 _OuterIter(chunk_view& __parent) noexcept
5928 : _M_parent(std::__addressof(__parent))
5934 using iterator_concept = input_iterator_tag;
5935 using difference_type = range_difference_t<_Vp>;
5939 _OuterIter(_OuterIter&&) = default;
5940 _OuterIter& operator=(_OuterIter&&) = default;
5942 constexpr value_type
5945 __glibcxx_assert(*this != default_sentinel);
5946 return value_type(*_M_parent);
5949 constexpr _OuterIter&
5952 __glibcxx_assert(*this != default_sentinel);
5953 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
5954 ranges::end(_M_parent->_M_base));
5955 _M_parent->_M_remainder = _M_parent->_M_n;
5963 friend constexpr bool
5964 operator==(const _OuterIter& __x, default_sentinel_t)
5966 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
5967 && __x._M_parent->_M_remainder != 0;
5970 friend constexpr difference_type
5971 operator-(default_sentinel_t, const _OuterIter& __x)
5972 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5974 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
5976 if (__dist < __x._M_parent->_M_remainder)
5977 return __dist == 0 ? 0 : 1;
5979 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
5980 __x._M_parent->_M_n);
5983 friend constexpr difference_type
5984 operator-(const _OuterIter& __x, default_sentinel_t __y)
5985 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
5986 { return -(__y - __x); }
5990 requires input_range<_Vp>
5991 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
5994 chunk_view* _M_parent;
5997 value_type(chunk_view& __parent) noexcept
5998 : _M_parent(std::__addressof(__parent))
6004 constexpr _InnerIter
6005 begin() const noexcept
6006 { return _InnerIter(*_M_parent); }
6008 constexpr default_sentinel_t
6009 end() const noexcept
6010 { return default_sentinel; }
6014 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6016 return __detail::__to_unsigned_like
6017 (ranges::min(_M_parent->_M_remainder,
6018 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6023 requires input_range<_Vp>
6024 class chunk_view<_Vp>::_InnerIter
6026 chunk_view* _M_parent;
6029 _InnerIter(chunk_view& __parent) noexcept
6030 : _M_parent(std::__addressof(__parent))
6033 friend _OuterIter::value_type;
6036 using iterator_concept = input_iterator_tag;
6037 using difference_type = range_difference_t<_Vp>;
6038 using value_type = range_value_t<_Vp>;
6040 _InnerIter(_InnerIter&&) = default;
6041 _InnerIter& operator=(_InnerIter&&) = default;
6043 constexpr const iterator_t<_Vp>&
6045 { return *_M_parent->_M_current; }
6047 constexpr range_reference_t<_Vp>
6050 __glibcxx_assert(*this != default_sentinel);
6051 return **_M_parent->_M_current;
6054 constexpr _InnerIter&
6057 __glibcxx_assert(*this != default_sentinel);
6058 ++*_M_parent->_M_current;
6059 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6060 _M_parent->_M_remainder = 0;
6062 --_M_parent->_M_remainder;
6070 friend constexpr bool
6071 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6072 { return __x._M_parent->_M_remainder == 0; }
6074 friend constexpr difference_type
6075 operator-(default_sentinel_t, const _InnerIter& __x)
6076 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6078 return ranges::min(__x._M_parent->_M_remainder,
6079 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6082 friend constexpr difference_type
6083 operator-(const _InnerIter& __x, default_sentinel_t __y)
6084 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6085 { return -(__y - __x); }
6089 requires forward_range<_Vp>
6090 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6093 range_difference_t<_Vp> _M_n;
6094 template<bool> class _Iterator;
6098 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6099 : _M_base(std::move(__base)), _M_n(__n)
6100 { __glibcxx_assert(__n > 0); }
6103 base() const & requires copy_constructible<_Vp>
6108 { return std::move(_M_base); }
6111 begin() requires (!__detail::__simple_view<_Vp>)
6112 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6115 begin() const requires forward_range<const _Vp>
6116 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6119 end() requires (!__detail::__simple_view<_Vp>)
6121 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6123 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6124 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6126 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6127 return _Iterator<false>(this, ranges::end(_M_base));
6129 return default_sentinel;
6133 end() const requires forward_range<const _Vp>
6135 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6137 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6138 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6140 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6141 return _Iterator<true>(this, ranges::end(_M_base));
6143 return default_sentinel;
6147 size() requires sized_range<_Vp>
6149 return __detail::__to_unsigned_like(__detail::__div_ceil
6150 (ranges::distance(_M_base), _M_n));
6154 size() const requires sized_range<const _Vp>
6156 return __detail::__to_unsigned_like(__detail::__div_ceil
6157 (ranges::distance(_M_base), _M_n));
6161 template<typename _Vp>
6162 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6163 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6166 requires forward_range<_Vp>
6167 template<bool _Const>
6168 class chunk_view<_Vp>::_Iterator
6170 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6171 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6173 iterator_t<_Base> _M_current = iterator_t<_Base>();
6174 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6175 range_difference_t<_Base> _M_n = 0;
6176 range_difference_t<_Base> _M_missing = 0;
6179 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6180 range_difference_t<_Base> __missing = 0)
6181 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6182 _M_n(__parent->_M_n), _M_missing(__missing)
6188 if constexpr (random_access_range<_Base>)
6189 return random_access_iterator_tag{};
6190 else if constexpr (bidirectional_range<_Base>)
6191 return bidirectional_iterator_tag{};
6193 return forward_iterator_tag{};
6199 using iterator_category = input_iterator_tag;
6200 using iterator_concept = decltype(_S_iter_cat());
6201 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6202 using difference_type = range_difference_t<_Base>;
6204 _Iterator() = default;
6206 constexpr _Iterator(_Iterator<!_Const> __i)
6208 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6209 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6210 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6211 _M_n(__i._M_n), _M_missing(__i._M_missing)
6214 constexpr iterator_t<_Base>
6216 { return _M_current; }
6218 constexpr value_type
6221 __glibcxx_assert(_M_current != _M_end);
6222 return views::take(subrange(_M_current, _M_end), _M_n);
6225 constexpr _Iterator&
6228 __glibcxx_assert(_M_current != _M_end);
6229 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6241 constexpr _Iterator&
6242 operator--() requires bidirectional_range<_Base>
6244 ranges::advance(_M_current, _M_missing - _M_n);
6250 operator--(int) requires bidirectional_range<_Base>
6257 constexpr _Iterator&
6258 operator+=(difference_type __x)
6259 requires random_access_range<_Base>
6263 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6264 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6268 ranges::advance(_M_current, _M_n * __x + _M_missing);
6274 constexpr _Iterator&
6275 operator-=(difference_type __x)
6276 requires random_access_range<_Base>
6277 { return *this += -__x; }
6279 constexpr value_type
6280 operator[](difference_type __n) const
6281 requires random_access_range<_Base>
6282 { return *(*this + __n); }
6284 friend constexpr bool
6285 operator==(const _Iterator& __x, const _Iterator& __y)
6286 { return __x._M_current == __y._M_current; }
6288 friend constexpr bool
6289 operator==(const _Iterator& __x, default_sentinel_t)
6290 { return __x._M_current == __x._M_end; }
6292 friend constexpr bool
6293 operator<(const _Iterator& __x, const _Iterator& __y)
6294 requires random_access_range<_Base>
6295 { return __x._M_current > __y._M_current; }
6297 friend constexpr bool
6298 operator>(const _Iterator& __x, const _Iterator& __y)
6299 requires random_access_range<_Base>
6300 { return __y < __x; }
6302 friend constexpr bool
6303 operator<=(const _Iterator& __x, const _Iterator& __y)
6304 requires random_access_range<_Base>
6305 { return !(__y < __x); }
6307 friend constexpr bool
6308 operator>=(const _Iterator& __x, const _Iterator& __y)
6309 requires random_access_range<_Base>
6310 { return !(__x < __y); }
6312 friend constexpr auto
6313 operator<=>(const _Iterator& __x, const _Iterator& __y)
6314 requires random_access_range<_Base>
6315 && three_way_comparable<iterator_t<_Base>>
6316 { return __x._M_current <=> __y._M_current; }
6318 friend constexpr _Iterator
6319 operator+(const _Iterator& __i, difference_type __n)
6320 requires random_access_range<_Base>
6327 friend constexpr _Iterator
6328 operator+(difference_type __n, const _Iterator& __i)
6329 requires random_access_range<_Base>
6336 friend constexpr _Iterator
6337 operator-(const _Iterator& __i, difference_type __n)
6338 requires random_access_range<_Base>
6345 friend constexpr difference_type
6346 operator-(const _Iterator& __x, const _Iterator& __y)
6347 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6349 return (__x._M_current - __y._M_current
6350 + __x._M_missing - __y._M_missing) / __x._M_n;
6353 friend constexpr difference_type
6354 operator-(default_sentinel_t __y, const _Iterator& __x)
6355 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6356 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6358 friend constexpr difference_type
6359 operator-(const _Iterator& __x, default_sentinel_t __y)
6360 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6361 { return -(__y - __x); }
6368 template<typename _Range, typename _Dp>
6369 concept __can_chunk_view
6370 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6373 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6375 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6376 requires __detail::__can_chunk_view<_Range, _Dp>
6378 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6379 { return chunk_view(std::forward<_Range>(__r), __n); }
6381 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6382 static constexpr int _S_arity = 2;
6383 static constexpr bool _S_has_simple_extra_args = true;
6386 inline constexpr _Chunk chunk;
6389#define __cpp_lib_ranges_slide 202202L
6393 template<typename _Vp>
6394 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6396 template<typename _Vp>
6397 concept __slide_caches_last
6398 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6400 template<typename _Vp>
6401 concept __slide_caches_first
6402 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6405 template<forward_range _Vp>
6407 class slide_view : public view_interface<slide_view<_Vp>>
6410 range_difference_t<_Vp> _M_n;
6411 [[no_unique_address]]
6412 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6413 __detail::_CachedPosition<_Vp>> _M_cached_begin;
6414 [[no_unique_address]]
6415 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6416 __detail::_CachedPosition<_Vp>> _M_cached_end;
6418 template<bool> class _Iterator;
6423 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6424 : _M_base(std::move(__base)), _M_n(__n)
6425 { __glibcxx_assert(__n > 0); }
6428 begin() requires (!(__detail::__simple_view<_Vp>
6429 && __detail::__slide_caches_nothing<const _Vp>))
6431 if constexpr (__detail::__slide_caches_first<_Vp>)
6433 iterator_t<_Vp> __it;
6434 if (_M_cached_begin._M_has_value())
6435 __it = _M_cached_begin._M_get(_M_base);
6438 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6439 _M_cached_begin._M_set(_M_base, __it);
6441 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6444 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6448 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6449 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6452 end() requires (!(__detail::__simple_view<_Vp>
6453 && __detail::__slide_caches_nothing<const _Vp>))
6455 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6456 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6458 else if constexpr (__detail::__slide_caches_last<_Vp>)
6460 iterator_t<_Vp> __it;
6461 if (_M_cached_end._M_has_value())
6462 __it = _M_cached_end._M_get(_M_base);
6465 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6466 _M_cached_end._M_set(_M_base, __it);
6468 return _Iterator<false>(std::move(__it), _M_n);
6470 else if constexpr (common_range<_Vp>)
6471 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6473 return _Sentinel(ranges::end(_M_base));
6477 end() const requires __detail::__slide_caches_nothing<const _Vp>
6478 { return begin() + range_difference_t<const _Vp>(size()); }
6481 size() requires sized_range<_Vp>
6483 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6486 return __detail::__to_unsigned_like(__sz);
6490 size() const requires sized_range<const _Vp>
6492 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6495 return __detail::__to_unsigned_like(__sz);
6499 template<typename _Range>
6500 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6502 template<typename _Vp>
6503 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6504 = enable_borrowed_range<_Vp>;
6506 template<forward_range _Vp>
6508 template<bool _Const>
6509 class slide_view<_Vp>::_Iterator
6511 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6512 static constexpr bool _S_last_elt_present
6513 = __detail::__slide_caches_first<_Base>;
6515 iterator_t<_Base> _M_current = iterator_t<_Base>();
6516 [[no_unique_address]]
6517 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6518 _M_last_elt = decltype(_M_last_elt)();
6519 range_difference_t<_Base> _M_n = 0;
6522 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6523 requires (!_S_last_elt_present)
6524 : _M_current(__current), _M_n(__n)
6528 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6529 range_difference_t<_Base> __n)
6530 requires _S_last_elt_present
6531 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6537 if constexpr (random_access_range<_Base>)
6538 return random_access_iterator_tag{};
6539 else if constexpr (bidirectional_range<_Base>)
6540 return bidirectional_iterator_tag{};
6542 return forward_iterator_tag{};
6546 friend slide_view::_Sentinel;
6549 using iterator_category = input_iterator_tag;
6550 using iterator_concept = decltype(_S_iter_concept());
6551 using value_type = decltype(views::counted(_M_current, _M_n));
6552 using difference_type = range_difference_t<_Base>;
6554 _Iterator() = default;
6557 _Iterator(_Iterator<!_Const> __i)
6558 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6559 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6564 { return views::counted(_M_current, _M_n); }
6566 constexpr _Iterator&
6570 if constexpr (_S_last_elt_present)
6583 constexpr _Iterator&
6584 operator--() requires bidirectional_range<_Base>
6587 if constexpr (_S_last_elt_present)
6593 operator--(int) requires bidirectional_range<_Base>
6600 constexpr _Iterator&
6601 operator+=(difference_type __x)
6602 requires random_access_range<_Base>
6605 if constexpr (_S_last_elt_present)
6610 constexpr _Iterator&
6611 operator-=(difference_type __x)
6612 requires random_access_range<_Base>
6615 if constexpr (_S_last_elt_present)
6621 operator[](difference_type __n) const
6622 requires random_access_range<_Base>
6623 { return views::counted(_M_current + __n, _M_n); }
6625 friend constexpr bool
6626 operator==(const _Iterator& __x, const _Iterator& __y)
6628 if constexpr (_S_last_elt_present)
6629 return __x._M_last_elt == __y._M_last_elt;
6631 return __x._M_current == __y._M_current;
6634 friend constexpr bool
6635 operator<(const _Iterator& __x, const _Iterator& __y)
6636 requires random_access_range<_Base>
6637 { return __x._M_current < __y._M_current; }
6639 friend constexpr bool
6640 operator>(const _Iterator& __x, const _Iterator& __y)
6641 requires random_access_range<_Base>
6642 { return __y < __x; }
6644 friend constexpr bool
6645 operator<=(const _Iterator& __x, const _Iterator& __y)
6646 requires random_access_range<_Base>
6647 { return !(__y < __x); }
6649 friend constexpr bool
6650 operator>=(const _Iterator& __x, const _Iterator& __y)
6651 requires random_access_range<_Base>
6652 { return !(__x < __y); }
6654 friend constexpr auto
6655 operator<=>(const _Iterator& __x, const _Iterator& __y)
6656 requires random_access_range<_Base>
6657 && three_way_comparable<iterator_t<_Base>>
6658 { return __x._M_current <=> __y._M_current; }
6660 friend constexpr _Iterator
6661 operator+(const _Iterator& __i, difference_type __n)
6662 requires random_access_range<_Base>
6669 friend constexpr _Iterator
6670 operator+(difference_type __n, const _Iterator& __i)
6671 requires random_access_range<_Base>
6678 friend constexpr _Iterator
6679 operator-(const _Iterator& __i, difference_type __n)
6680 requires random_access_range<_Base>
6687 friend constexpr difference_type
6688 operator-(const _Iterator& __x, const _Iterator& __y)
6689 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6691 if constexpr (_S_last_elt_present)
6692 return __x._M_last_elt - __y._M_last_elt;
6694 return __x._M_current - __y._M_current;
6698 template<forward_range _Vp>
6700 class slide_view<_Vp>::_Sentinel
6702 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6705 _Sentinel(sentinel_t<_Vp> __end)
6712 _Sentinel() = default;
6714 friend constexpr bool
6715 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6716 { return __x._M_last_elt == __y._M_end; }
6718 friend constexpr range_difference_t<_Vp>
6719 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6720 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6721 { return __x._M_last_elt - __y._M_end; }
6723 friend constexpr range_difference_t<_Vp>
6724 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6725 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6726 { return __y._M_end -__x._M_last_elt; }
6733 template<typename _Range, typename _Dp>
6734 concept __can_slide_view
6735 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6738 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6740 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6741 requires __detail::__can_slide_view<_Range, _Dp>
6743 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6744 { return slide_view(std::forward<_Range>(__r), __n); }
6746 using __adaptor::_RangeAdaptor<_Slide>::operator();
6747 static constexpr int _S_arity = 2;
6748 static constexpr bool _S_has_simple_extra_args = true;
6751 inline constexpr _Slide slide;
6754#define __cpp_lib_ranges_chunk_by 202202L
6756 template<forward_range _Vp,
6757 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6758 requires view<_Vp> && is_object_v<_Pred>
6759 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6761 _Vp _M_base = _Vp();
6762 __detail::__box<_Pred> _M_pred;
6763 __detail::_CachedPosition<_Vp> _M_cached_begin;
6765 constexpr iterator_t<_Vp>
6766 _M_find_next(iterator_t<_Vp> __current)
6768 __glibcxx_assert(_M_pred.has_value());
6769 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6770 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6772 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6773 return ranges::next(__it, 1, ranges::end(_M_base));
6776 constexpr iterator_t<_Vp>
6777 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
6779 __glibcxx_assert(_M_pred.has_value());
6780 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6781 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
6783 auto __rbegin = std::make_reverse_iterator(__current);
6784 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
6785 __glibcxx_assert(__rbegin != __rend);
6786 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
6787 return ranges::prev(__it, 1, ranges::begin(_M_base));
6793 chunk_by_view() requires (default_initializable<_Vp>
6794 && default_initializable<_Pred>)
6798 chunk_by_view(_Vp __base, _Pred __pred)
6799 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
6803 base() const & requires copy_constructible<_Vp>
6808 { return std::move(_M_base); }
6810 constexpr const _Pred&
6812 { return *_M_pred; }
6817 __glibcxx_assert(_M_pred.has_value());
6818 iterator_t<_Vp> __it;
6819 if (_M_cached_begin._M_has_value())
6820 __it = _M_cached_begin._M_get(_M_base);
6823 __it = _M_find_next(ranges::begin(_M_base));
6824 _M_cached_begin._M_set(_M_base, __it);
6826 return _Iterator(*this, ranges::begin(_M_base), __it);
6832 if constexpr (common_range<_Vp>)
6833 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
6835 return default_sentinel;
6839 template<typename _Range, typename _Pred>
6840 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
6842 template<forward_range _Vp,
6843 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6844 requires view<_Vp> && is_object_v<_Pred>
6845 class chunk_by_view<_Vp, _Pred>::_Iterator
6847 chunk_by_view* _M_parent = nullptr;
6848 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
6849 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
6852 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
6853 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
6859 if constexpr (bidirectional_range<_Vp>)
6860 return bidirectional_iterator_tag{};
6862 return forward_iterator_tag{};
6865 friend chunk_by_view;
6868 using value_type = subrange<iterator_t<_Vp>>;
6869 using difference_type = range_difference_t<_Vp>;
6870 using iterator_category = input_iterator_tag;
6871 using iterator_concept = decltype(_S_iter_concept());
6873 _Iterator() = default;
6875 constexpr value_type
6878 __glibcxx_assert(_M_current != _M_next);
6879 return ranges::subrange(_M_current, _M_next);
6882 constexpr _Iterator&
6885 __glibcxx_assert(_M_current != _M_next);
6886 _M_current = _M_next;
6887 _M_next = _M_parent->_M_find_next(_M_current);
6899 constexpr _Iterator&
6900 operator--() requires bidirectional_range<_Vp>
6902 _M_next = _M_current;
6903 _M_current = _M_parent->_M_find_prev(_M_next);
6908 operator--(int) requires bidirectional_range<_Vp>
6915 friend constexpr bool
6916 operator==(const _Iterator& __x, const _Iterator& __y)
6917 { return __x._M_current == __y._M_current; }
6919 friend constexpr bool
6920 operator==(const _Iterator& __x, default_sentinel_t)
6921 { return __x._M_current == __x._M_next; }
6928 template<typename _Range, typename _Pred>
6929 concept __can_chunk_by_view
6930 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
6933 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
6935 template<viewable_range _Range, typename _Pred>
6936 requires __detail::__can_chunk_by_view<_Range, _Pred>
6938 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
6939 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
6941 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
6942 static constexpr int _S_arity = 2;
6943 static constexpr bool _S_has_simple_extra_args = true;
6946 inline constexpr _ChunkBy chunk_by;
6949#define __cpp_lib_ranges_join_with 202202L
6953 template<typename _Range, typename _Pattern>
6954 concept __compatible_joinable_ranges
6955 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
6956 && common_reference_with<range_reference_t<_Range>,
6957 range_reference_t<_Pattern>>
6958 && common_reference_with<range_rvalue_reference_t<_Range>,
6959 range_rvalue_reference_t<_Pattern>>;
6961 template<typename _Range>
6962 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
6965 template<input_range _Vp, forward_range _Pattern>
6966 requires view<_Vp> && view<_Pattern>
6967 && input_range<range_reference_t<_Vp>>
6968 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
6969 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
6971 using _InnerRange = range_reference_t<_Vp>;
6973 _Vp _M_base = _Vp();
6974 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
6975 _Pattern _M_pattern = _Pattern();
6977 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6978 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
6979 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
6981 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
6982 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
6983 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
6985 template<bool _Const>
6986 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
6988 template<bool _Const>
6992 template<bool _Const>
6993 requires _S_ref_is_glvalue<_Const>
6994 && forward_range<_Base<_Const>>
6995 && forward_range<_InnerBase<_Const>>
6996 struct __iter_cat<_Const>
7002 using _OuterIter = join_with_view::_OuterIter<_Const>;
7003 using _InnerIter = join_with_view::_InnerIter<_Const>;
7004 using _PatternIter = join_with_view::_PatternIter<_Const>;
7005 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7006 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7007 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7008 if constexpr (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7009 iter_reference_t<_PatternIter>>>)
7010 return input_iterator_tag{};
7011 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7012 && derived_from<_InnerCat, bidirectional_iterator_tag>
7013 && derived_from<_PatternCat, bidirectional_iterator_tag>
7014 && common_range<_InnerBase<_Const>>
7015 && common_range<_PatternBase<_Const>>)
7016 return bidirectional_iterator_tag{};
7017 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7018 && derived_from<_InnerCat, forward_iterator_tag>
7019 && derived_from<_PatternCat, forward_iterator_tag>)
7020 return forward_iterator_tag{};
7022 return input_iterator_tag{};
7025 using iterator_category = decltype(_S_iter_cat());
7028 template<bool> struct _Iterator;
7029 template<bool> struct _Sentinel;
7032 join_with_view() requires (default_initializable<_Vp>
7033 && default_initializable<_Pattern>)
7037 join_with_view(_Vp __base, _Pattern __pattern)
7038 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7041 template<input_range _Range>
7042 requires constructible_from<_Vp, views::all_t<_Range>>
7043 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7045 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7046 : _M_base(views::all(std::forward<_Range>(__r))),
7047 _M_pattern(views::single(std::move(__e)))
7051 base() const& requires copy_constructible<_Vp>
7056 { return std::move(_M_base); }
7061 constexpr bool __use_const = is_reference_v<_InnerRange>
7062 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7063 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7068 requires input_range<const _Vp>
7069 && forward_range<const _Pattern>
7070 && is_reference_v<range_reference_t<const _Vp>>
7071 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7076 constexpr bool __use_const
7077 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7078 if constexpr (is_reference_v<_InnerRange>
7079 && forward_range<_Vp> && common_range<_Vp>
7080 && forward_range<_InnerRange> && common_range<_InnerRange>)
7081 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7083 return _Sentinel<__use_const>{*this};
7088 requires input_range<const _Vp>
7089 && forward_range<const _Pattern>
7090 && is_reference_v<range_reference_t<const _Vp>>
7092 using _InnerConstRange = range_reference_t<const _Vp>;
7093 if constexpr (forward_range<const _Vp>
7094 && forward_range<_InnerConstRange>
7095 && common_range<const _Vp>
7096 && common_range<_InnerConstRange>)
7097 return _Iterator<true>{*this, ranges::end(_M_base)};
7099 return _Sentinel<true>{*this};
7103 template<typename _Range, typename _Pattern>
7104 join_with_view(_Range&&, _Pattern&&)
7105 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7107 template<input_range _Range>
7108 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7109 -> join_with_view<views::all_t<_Range>,
7110 single_view<range_value_t<range_reference_t<_Range>>>>;
7112 template<input_range _Vp, forward_range _Pattern>
7113 requires view<_Vp> && view<_Pattern>
7114 && input_range<range_reference_t<_Vp>>
7115 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7116 template<bool _Const>
7117 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7119 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7120 using _Base = join_with_view::_Base<_Const>;
7121 using _InnerBase = join_with_view::_InnerBase<_Const>;
7122 using _PatternBase = join_with_view::_PatternBase<_Const>;
7124 using _OuterIter = join_with_view::_OuterIter<_Const>;
7125 using _InnerIter = join_with_view::_InnerIter<_Const>;
7126 using _PatternIter = join_with_view::_PatternIter<_Const>;
7128 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7130 _Parent* _M_parent = nullptr;
7131 _OuterIter _M_outer_it = _OuterIter();
7132 variant<_PatternIter, _InnerIter> _M_inner_it;
7135 _Iterator(_Parent& __parent, iterator_t<_Base> __outer)
7136 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7138 if (_M_outer_it != ranges::end(_M_parent->_M_base))
7140 auto&& __inner = _M_update_inner(_M_outer_it);
7141 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7147 _M_update_inner(const _OuterIter& __x)
7149 if constexpr (_S_ref_is_glvalue)
7152 return _M_parent->_M_inner._M_emplace_deref(__x);
7156 _M_get_inner(const _OuterIter& __x)
7158 if constexpr (_S_ref_is_glvalue)
7161 return *_M_parent->_M_inner;
7169 if (_M_inner_it.index() == 0)
7171 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7174 auto&& __inner = _M_update_inner(_M_outer_it);
7175 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7179 auto&& __inner = _M_get_inner(_M_outer_it);
7180 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7183 if (++_M_outer_it == ranges::end(_M_parent->_M_base))
7185 if constexpr (_S_ref_is_glvalue)
7186 _M_inner_it.template emplace<0>();
7190 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7198 if constexpr (_S_ref_is_glvalue
7199 && bidirectional_range<_Base>
7200 && __detail::__bidirectional_common<_InnerBase>
7201 && __detail::__bidirectional_common<_PatternBase>)
7202 return bidirectional_iterator_tag{};
7203 else if constexpr (_S_ref_is_glvalue
7204 && forward_range<_Base>
7205 && forward_range<_InnerBase>)
7206 return forward_iterator_tag{};
7208 return input_iterator_tag{};
7211 friend join_with_view;
7214 using iterator_concept = decltype(_S_iter_concept());
7215 // iterator_category defined in join_with_view::__iter_cat
7216 using value_type = common_type_t<iter_value_t<_InnerIter>,
7217 iter_value_t<_PatternIter>>;
7218 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7219 iter_difference_t<_InnerIter>,
7220 iter_difference_t<_PatternIter>>;
7222 _Iterator() requires default_initializable<_OuterIter> = default;
7225 _Iterator(_Iterator<!_Const> __i)
7227 && convertible_to<iterator_t<_Vp>, _OuterIter>
7228 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7229 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7230 : _M_parent(__i._M_parent),
7231 _M_outer_it(std::move(__i._M_outer_it))
7233 if (__i._M_inner_it.index() == 0)
7234 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7236 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7239 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7240 iter_reference_t<_PatternIter>>
7243 if (_M_inner_it.index() == 0)
7244 return *std::get<0>(_M_inner_it);
7246 return *std::get<1>(_M_inner_it);
7249 constexpr _Iterator&
7252 if (_M_inner_it.index() == 0)
7253 ++std::get<0>(_M_inner_it);
7255 ++std::get<1>(_M_inner_it);
7266 requires _S_ref_is_glvalue
7267 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7269 _Iterator __tmp = *this;
7274 constexpr _Iterator&
7276 requires _S_ref_is_glvalue
7277 && bidirectional_range<_Base>
7278 && __detail::__bidirectional_common<_InnerBase>
7279 && __detail::__bidirectional_common<_PatternBase>
7281 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7283 auto&& __inner = *--_M_outer_it;
7284 _M_inner_it.template emplace<1>(ranges::end(__inner));
7289 if (_M_inner_it.index() == 0)
7291 auto& __it = std::get<0>(_M_inner_it);
7292 if (__it == ranges::begin(_M_parent->_M_pattern))
7294 auto&& __inner = *--_M_outer_it;
7295 _M_inner_it.template emplace<1>(ranges::end(__inner));
7302 auto& __it = std::get<1>(_M_inner_it);
7303 auto&& __inner = *_M_outer_it;
7304 if (__it == ranges::begin(__inner))
7305 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7311 if (_M_inner_it.index() == 0)
7312 --std::get<0>(_M_inner_it);
7314 --std::get<1>(_M_inner_it);
7320 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7321 && __detail::__bidirectional_common<_InnerBase>
7322 && __detail::__bidirectional_common<_PatternBase>
7324 _Iterator __tmp = *this;
7329 friend constexpr bool
7330 operator==(const _Iterator& __x, const _Iterator& __y)
7331 requires _S_ref_is_glvalue
7332 && equality_comparable<_OuterIter> && equality_comparable<_InnerIter>
7333 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7335 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7336 iter_rvalue_reference_t<_PatternIter>>
7337 iter_move(const _Iterator& __x)
7339 if (__x._M_inner_it.index() == 0)
7340 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7342 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7345 friend constexpr void
7346 iter_swap(const _Iterator& __x, const _Iterator& __y)
7347 requires indirectly_swappable<_InnerIter, _PatternIter>
7349 if (__x._M_inner_it.index() == 0)
7351 if (__y._M_inner_it.index() == 0)
7352 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7354 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7358 if (__y._M_inner_it.index() == 0)
7359 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7361 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7366 template<input_range _Vp, forward_range _Pattern>
7367 requires view<_Vp> && view<_Pattern>
7368 && input_range<range_reference_t<_Vp>>
7369 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7370 template<bool _Const>
7371 class join_with_view<_Vp, _Pattern>::_Sentinel
7373 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7374 using _Base = join_with_view::_Base<_Const>;
7376 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7379 _Sentinel(_Parent& __parent)
7380 : _M_end(ranges::end(__parent._M_base))
7383 friend join_with_view;
7386 _Sentinel() = default;
7389 _Sentinel(_Sentinel<!_Const> __s)
7390 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7391 : _M_end(std::move(__s._M_end))
7394 template<bool _OtherConst>
7395 requires sentinel_for<sentinel_t<_Base>,
7396 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7397 friend constexpr bool
7398 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7399 { return __x._M_outer_it == __y._M_end; }
7406 template<typename _Range, typename _Pattern>
7407 concept __can_join_with_view
7408 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7409 } // namespace __detail
7411 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7413 template<viewable_range _Range, typename _Pattern>
7414 requires __detail::__can_join_with_view<_Range, _Pattern>
7416 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7418 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7421 using _RangeAdaptor<_JoinWith>::operator();
7422 static constexpr int _S_arity = 2;
7423 template<typename _Pattern>
7424 static constexpr bool _S_has_simple_extra_args
7425 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7428 inline constexpr _JoinWith join_with;
7429 } // namespace views
7431#define __cpp_lib_ranges_repeat 202207L
7433 template<copy_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7434 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7435 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7436 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7438 __detail::__box<_Tp> _M_value;
7439 [[no_unique_address]] _Bound _M_bound = _Bound();
7443 template<typename _Range>
7444 friend constexpr auto
7445 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7447 template<typename _Range>
7448 friend constexpr auto
7449 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7452 repeat_view() requires default_initializable<_Tp> = default;
7455 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7456 : _M_value(__value), _M_bound(__bound)
7458 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7459 __glibcxx_assert(__bound >= 0);
7463 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7464 : _M_value(std::move(__value)), _M_bound(__bound)
7467 template<typename... _Args, typename... _BoundArgs>
7468 requires constructible_from<_Tp, _Args...>
7469 && constructible_from<_Bound, _BoundArgs...>
7471 repeat_view(piecewise_construct_t,
7472 tuple<_Args...> __args,
7473 tuple<_BoundArgs...> __bound_args = tuple<>{})
7474 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7475 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7480 { return _Iterator(std::__addressof(*_M_value)); }
7483 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7484 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7486 constexpr unreachable_sentinel_t
7487 end() const noexcept
7488 { return unreachable_sentinel; }
7491 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7492 { return __detail::__to_unsigned_like(_M_bound); }
7495 template<typename _Tp, typename _Bound>
7496 repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>;
7498 template<copy_constructible _Tp, semiregular _Bound>
7499 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7500 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7501 class repeat_view<_Tp, _Bound>::_Iterator
7504 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7506 const _Tp* _M_value = nullptr;
7507 __index_type _M_current = __index_type();
7510 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7511 : _M_value(__value), _M_current(__bound)
7513 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7514 __glibcxx_assert(__bound >= 0);
7520 using iterator_concept = random_access_iterator_tag;
7521 using iterator_category = random_access_iterator_tag;
7522 using value_type = _Tp;
7523 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7525 __detail::__iota_diff_t<__index_type>>;
7527 _Iterator() = default;
7529 constexpr const _Tp&
7530 operator*() const noexcept
7531 { return *_M_value; }
7533 constexpr _Iterator&
7548 constexpr _Iterator&
7551 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7552 __glibcxx_assert(_M_current > 0);
7565 constexpr _Iterator&
7566 operator+=(difference_type __n)
7568 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7569 __glibcxx_assert(_M_current + __n >= 0);
7574 constexpr _Iterator&
7575 operator-=(difference_type __n)
7577 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7578 __glibcxx_assert(_M_current - __n >= 0);
7583 constexpr const _Tp&
7584 operator[](difference_type __n) const noexcept
7585 { return *(*this + __n); }
7587 friend constexpr bool
7588 operator==(const _Iterator& __x, const _Iterator& __y)
7589 { return __x._M_current == __y._M_current; }
7591 friend constexpr auto
7592 operator<=>(const _Iterator& __x, const _Iterator& __y)
7593 { return __x._M_current <=> __y._M_current; }
7595 friend constexpr _Iterator
7596 operator+(_Iterator __i, difference_type __n)
7602 friend constexpr _Iterator
7603 operator+(difference_type __n, _Iterator __i)
7604 { return __i + __n; }
7606 friend constexpr _Iterator
7607 operator-(_Iterator __i, difference_type __n)
7613 friend constexpr difference_type
7614 operator-(const _Iterator& __x, const _Iterator& __y)
7616 return (static_cast<difference_type>(__x._M_current)
7617 - static_cast<difference_type>(__y._M_current));
7625 template<typename _Tp, typename _Bound>
7626 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7628 template<typename _Tp>
7629 concept __can_repeat_view
7630 = requires { repeat_view(std::declval<_Tp>()); };
7632 template<typename _Tp, typename _Bound>
7633 concept __can_bounded_repeat_view
7634 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7639 template<typename _Tp>
7640 requires __detail::__can_repeat_view<_Tp>
7642 operator() [[nodiscard]] (_Tp&& __value) const
7643 { return repeat_view(std::forward<_Tp>(__value)); }
7645 template<typename _Tp, typename _Bound>
7646 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7648 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7649 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7652 inline constexpr _Repeat repeat;
7656 template<typename _Range>
7658 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7660 using _Tp = remove_cvref_t<_Range>;
7661 static_assert(__is_repeat_view<_Tp>);
7662 if constexpr (sized_range<_Tp>)
7663 return views::repeat(*__r._M_value, std::min(ranges::distance(__r), __n));
7665 return views::repeat(*__r._M_value, __n);
7668 template<typename _Range>
7670 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7672 using _Tp = remove_cvref_t<_Range>;
7673 static_assert(__is_repeat_view<_Tp>);
7674 if constexpr (sized_range<_Tp>)
7676 auto __sz = ranges::distance(__r);
7677 return views::repeat(*__r._M_value, __sz - std::min(__sz, __n));
7685#define __cpp_lib_ranges_stride 202207L
7687 template<input_range _Vp>
7689 class stride_view : public view_interface<stride_view<_Vp>>
7692 range_difference_t<_Vp> _M_stride;
7694 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7696 template<bool _Const>
7700 template<bool _Const>
7701 requires forward_range<_Base<_Const>>
7702 struct __iter_cat<_Const>
7708 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7709 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7710 return random_access_iterator_tag{};
7715 using iterator_category = decltype(_S_iter_cat());
7718 template<bool> class _Iterator;
7722 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
7723 : _M_base(std::move(__base)), _M_stride(__stride)
7724 { __glibcxx_assert(__stride > 0); }
7727 base() const& requires copy_constructible<_Vp>
7732 { return std::move(_M_base); }
7734 constexpr range_difference_t<_Vp>
7735 stride() const noexcept
7736 { return _M_stride; }
7739 begin() requires (!__detail::__simple_view<_Vp>)
7740 { return _Iterator<false>(this, ranges::begin(_M_base)); }
7743 begin() const requires range<const _Vp>
7744 { return _Iterator<true>(this, ranges::begin(_M_base)); }
7747 end() requires (!__detail::__simple_view<_Vp>)
7749 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
7751 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7752 return _Iterator<false>(this, ranges::end(_M_base), __missing);
7754 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
7755 return _Iterator<false>(this, ranges::end(_M_base));
7757 return default_sentinel;
7761 end() const requires range<const _Vp>
7763 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
7764 && forward_range<const _Vp>)
7766 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
7767 return _Iterator<true>(this, ranges::end(_M_base), __missing);
7769 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
7770 return _Iterator<true>(this, ranges::end(_M_base));
7772 return default_sentinel;
7776 size() requires sized_range<_Vp>
7778 return __detail::__to_unsigned_like
7779 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7783 size() const requires sized_range<const _Vp>
7785 return __detail::__to_unsigned_like
7786 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
7790 template<typename _Range>
7791 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
7793 template<typename _Vp>
7794 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
7795 = enable_borrowed_range<_Vp>;
7797 template<input_range _Vp>
7799 template<bool _Const>
7800 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
7802 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
7803 using _Base = stride_view::_Base<_Const>;
7805 iterator_t<_Base> _M_current = iterator_t<_Base>();
7806 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7807 range_difference_t<_Base> _M_stride = 0;
7808 range_difference_t<_Base> _M_missing = 0;
7811 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
7812 range_difference_t<_Base> __missing = 0)
7813 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
7814 _M_stride(__parent->_M_stride), _M_missing(__missing)
7820 if constexpr (random_access_range<_Base>)
7821 return random_access_iterator_tag{};
7822 else if constexpr (bidirectional_range<_Base>)
7823 return bidirectional_iterator_tag{};
7824 else if constexpr (forward_range<_Base>)
7825 return forward_iterator_tag{};
7827 return input_iterator_tag{};
7833 using difference_type = range_difference_t<_Base>;
7834 using value_type = range_value_t<_Base>;
7835 using iterator_concept = decltype(_S_iter_concept());
7836 // iterator_category defined in stride_view::__iter_cat
7838 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
7841 _Iterator(_Iterator<!_Const> __other)
7843 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
7844 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7845 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
7846 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
7849 constexpr iterator_t<_Base>
7851 { return std::move(_M_current); }
7853 constexpr const iterator_t<_Base>&
7854 base() const & noexcept
7855 { return _M_current; }
7857 constexpr decltype(auto)
7859 { return *_M_current; }
7861 constexpr _Iterator&
7864 __glibcxx_assert(_M_current != _M_end);
7865 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
7874 operator++(int) requires forward_range<_Base>
7881 constexpr _Iterator&
7882 operator--() requires bidirectional_range<_Base>
7884 ranges::advance(_M_current, _M_missing - _M_stride);
7890 operator--(int) requires bidirectional_range<_Base>
7897 constexpr _Iterator&
7898 operator+=(difference_type __n) requires random_access_range<_Base>
7902 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
7903 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
7907 ranges::advance(_M_current, _M_stride * __n + _M_missing);
7913 constexpr _Iterator&
7914 operator-=(difference_type __n) requires random_access_range<_Base>
7915 { return *this += -__n; }
7917 constexpr decltype(auto) operator[](difference_type __n) const
7918 requires random_access_range<_Base>
7919 { return *(*this + __n); }
7921 friend constexpr bool
7922 operator==(const _Iterator& __x, default_sentinel_t)
7923 { return __x._M_current == __x._M_end; }
7925 friend constexpr bool
7926 operator==(const _Iterator& __x, const _Iterator& __y)
7927 requires equality_comparable<iterator_t<_Base>>
7928 { return __x._M_current == __y._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 bool
7936 operator>(const _Iterator& __x, const _Iterator& __y)
7937 requires random_access_range<_Base>
7938 { return __y._M_current < __x._M_current; }
7940 friend constexpr bool
7941 operator<=(const _Iterator& __x, const _Iterator& __y)
7942 requires random_access_range<_Base>
7943 { return !(__y._M_current < __x._M_current); }
7945 friend constexpr bool
7946 operator>=(const _Iterator& __x, const _Iterator& __y)
7947 requires random_access_range<_Base>
7948 { return !(__x._M_current < __y._M_current); }
7950 friend constexpr auto
7951 operator<=>(const _Iterator& __x, const _Iterator& __y)
7952 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
7953 { return __x._M_current <=> __y._M_current; }
7955 friend constexpr _Iterator
7956 operator+(const _Iterator& __i, difference_type __n)
7957 requires random_access_range<_Base>
7964 friend constexpr _Iterator
7965 operator+(difference_type __n, const _Iterator& __i)
7966 requires random_access_range<_Base>
7967 { return __i + __n; }
7969 friend constexpr _Iterator
7970 operator-(const _Iterator& __i, difference_type __n)
7971 requires random_access_range<_Base>
7978 friend constexpr difference_type
7979 operator-(const _Iterator& __x, const _Iterator& __y)
7980 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
7982 auto __n = __x._M_current - __y._M_current;
7983 if constexpr (forward_range<_Base>)
7984 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
7986 return -__detail::__div_ceil(-__n, __x._M_stride);
7988 return __detail::__div_ceil(__n, __x._M_stride);
7991 friend constexpr difference_type
7992 operator-(default_sentinel_t __y, const _Iterator& __x)
7993 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7994 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
7996 friend constexpr difference_type
7997 operator-(const _Iterator& __x, default_sentinel_t __y)
7998 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
7999 { return -(__y - __x); }
8001 friend constexpr range_rvalue_reference_t<_Base>
8002 iter_move(const _Iterator& __i)
8003 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8004 { return ranges::iter_move(__i._M_current); }
8006 friend constexpr void
8007 iter_swap(const _Iterator& __x, const _Iterator& __y)
8008 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8009 requires indirectly_swappable<iterator_t<_Base>>
8010 { ranges::iter_swap(__x._M_current, __y._M_current); }
8017 template<typename _Range, typename _Dp>
8018 concept __can_stride_view
8019 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8022 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8024 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8025 requires __detail::__can_stride_view<_Range, _Dp>
8027 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8028 { return stride_view(std::forward<_Range>(__r), __n); }
8030 using __adaptor::_RangeAdaptor<_Stride>::operator();
8031 static constexpr int _S_arity = 2;
8032 static constexpr bool _S_has_simple_extra_args = true;
8035 inline constexpr _Stride stride;
8038#define __cpp_lib_ranges_cartesian_product 202207L
8042 template<bool _Const, typename _First, typename... _Vs>
8043 concept __cartesian_product_is_random_access
8044 = (random_access_range<__maybe_const_t<_Const, _First>>
8046 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8047 && sized_range<__maybe_const_t<_Const, _Vs>>));
8049 template<typename _Range>
8050 concept __cartesian_product_common_arg
8051 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8053 template<bool _Const, typename _First, typename... _Vs>
8054 concept __cartesian_product_is_bidirectional
8055 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8057 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8058 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8060 template<typename _First, typename... _Vs>
8061 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8063 template<typename... _Vs>
8064 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8066 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8067 concept __cartesian_is_sized_sentinel
8068 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8069 iterator_t<__maybe_const_t<_Const, _First>>>
8071 && (sized_range<__maybe_const_t<_Const, _Vs>>
8072 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8073 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8075 template<__cartesian_product_common_arg _Range>
8077 __cartesian_common_arg_end(_Range& __r)
8079 if constexpr (common_range<_Range>)
8080 return ranges::end(__r);
8082 return ranges::begin(__r) + ranges::distance(__r);
8084 } // namespace __detail
8086 template<input_range _First, forward_range... _Vs>
8087 requires (view<_First> && ... && view<_Vs>)
8088 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8090 tuple<_First, _Vs...> _M_bases;
8092 template<bool> class _Iterator;
8095 _S_difference_type()
8097 // TODO: Implement the recommended practice of using the smallest
8098 // sufficiently wide type according to the maximum sizes of the
8099 // underlying ranges?
8100 return common_type_t<ptrdiff_t,
8101 range_difference_t<_First>,
8102 range_difference_t<_Vs>...>{};
8106 cartesian_product_view() = default;
8109 cartesian_product_view(_First __first, _Vs... __rest)
8110 : _M_bases(std::move(__first), std::move(__rest)...)
8113 constexpr _Iterator<false>
8114 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8115 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8117 constexpr _Iterator<true>
8118 begin() const requires (range<const _First> && ... && range<const _Vs>)
8119 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8121 constexpr _Iterator<false>
8122 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8123 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8125 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8126 using _Ret = __detail::__tuple_or_pair_t<iterator_t<_First>,
8127 iterator_t<_Vs>...>;
8128 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8129 auto& __first = std::get<0>(_M_bases);
8130 return _Ret{(__empty_tail
8131 ? ranges::begin(__first)
8132 : __detail::__cartesian_common_arg_end(__first)),
8133 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8134 }(make_index_sequence<sizeof...(_Vs)>{});
8136 return _Iterator<false>{*this, std::move(__its)};
8139 constexpr _Iterator<true>
8140 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8142 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8143 using _Ret = __detail::__tuple_or_pair_t<iterator_t<const _First>,
8144 iterator_t<const _Vs>...>;
8145 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8146 auto& __first = std::get<0>(_M_bases);
8147 return _Ret{(__empty_tail
8148 ? ranges::begin(__first)
8149 : __detail::__cartesian_common_arg_end(__first)),
8150 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8151 }(make_index_sequence<sizeof...(_Vs)>{});
8153 return _Iterator<true>{*this, std::move(__its)};
8156 constexpr default_sentinel_t
8157 end() const noexcept
8158 { return default_sentinel; }
8161 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8163 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8164 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8165 auto __size = static_cast<_ST>(1);
8166#ifdef _GLIBCXX_ASSERTIONS
8167 if constexpr (integral<_ST>)
8170 = (__builtin_mul_overflow(__size,
8171 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8174 __glibcxx_assert(!__overflow);
8178 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8180 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8184 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8186 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8187 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8188 auto __size = static_cast<_ST>(1);
8189#ifdef _GLIBCXX_ASSERTIONS
8190 if constexpr (integral<_ST>)
8193 = (__builtin_mul_overflow(__size,
8194 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8197 __glibcxx_assert(!__overflow);
8201 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8203 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8207 template<typename... _Vs>
8208 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8210 template<input_range _First, forward_range... _Vs>
8211 requires (view<_First> && ... && view<_Vs>)
8212 template<bool _Const>
8213 class cartesian_product_view<_First, _Vs...>::_Iterator
8215 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8216 _Parent* _M_parent = nullptr;
8217 __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
8218 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8221 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8222 : _M_parent(std::__addressof(__parent)),
8223 _M_current(std::move(__current))
8229 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8230 return random_access_iterator_tag{};
8231 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8232 return bidirectional_iterator_tag{};
8233 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8234 return forward_iterator_tag{};
8236 return input_iterator_tag{};
8239 friend cartesian_product_view;
8242 using iterator_category = input_iterator_tag;
8243 using iterator_concept = decltype(_S_iter_concept());
8245 = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
8246 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8248 = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
8249 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8250 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8252 _Iterator() = default;
8255 _Iterator(_Iterator<!_Const> __i)
8257 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8258 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8259 : _M_parent(std::__addressof(__i._M_parent)),
8260 _M_current(std::move(__i._M_current))
8266 auto __f = [](auto& __i) -> decltype(auto) {
8269 return __detail::__tuple_transform(__f, _M_current);
8272 constexpr _Iterator&
8284 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8291 constexpr _Iterator&
8293 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8301 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8308 constexpr _Iterator&
8309 operator+=(difference_type __x)
8310 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8316 constexpr _Iterator&
8317 operator-=(difference_type __x)
8318 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8319 { return *this += -__x; }
8322 operator[](difference_type __n) const
8323 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8324 { return *((*this) + __n); }
8326 friend constexpr bool
8327 operator==(const _Iterator& __x, const _Iterator& __y)
8328 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8329 { return __x._M_current == __y._M_current; }
8331 friend constexpr bool
8332 operator==(const _Iterator& __x, default_sentinel_t)
8334 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8335 return ((std::get<_Is>(__x._M_current)
8336 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8338 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8341 friend constexpr auto
8342 operator<=>(const _Iterator& __x, const _Iterator& __y)
8343 requires __detail::__all_random_access<_Const, _First, _Vs...>
8344 { return __x._M_current <=> __y._M_current; }
8346 friend constexpr _Iterator
8347 operator+(_Iterator __x, difference_type __y)
8348 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8349 { return __x += __y; }
8351 friend constexpr _Iterator
8352 operator+(difference_type __x, _Iterator __y)
8353 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8354 { return __y += __x; }
8356 friend constexpr _Iterator
8357 operator-(_Iterator __x, difference_type __y)
8358 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8359 { return __x -= __y; }
8361 friend constexpr difference_type
8362 operator-(const _Iterator& __x, const _Iterator& __y)
8363 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8364 { return __x._M_distance_from(__y._M_current); }
8366 friend constexpr difference_type
8367 operator-(const _Iterator& __i, default_sentinel_t)
8368 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8370 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8371 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8372 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8373 }(make_index_sequence<sizeof...(_Vs)>{});
8374 return __i._M_distance_from(__end_tuple);
8377 friend constexpr difference_type
8378 operator-(default_sentinel_t, const _Iterator& __i)
8379 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8380 { return -(__i - default_sentinel); }
8382 friend constexpr auto
8383 iter_move(const _Iterator& __i)
8384 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8386 friend constexpr void
8387 iter_swap(const _Iterator& __l, const _Iterator& __r)
8388 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8390 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8392 [&]<size_t... _Is>(index_sequence<_Is...>) {
8393 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8394 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8398 template<size_t _Nm = sizeof...(_Vs)>
8402 auto& __it = std::get<_Nm>(_M_current);
8404 if constexpr (_Nm > 0)
8405 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8407 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8412 template<size_t _Nm = sizeof...(_Vs)>
8416 auto& __it = std::get<_Nm>(_M_current);
8417 if constexpr (_Nm > 0)
8418 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8420 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8426 template<size_t _Nm = sizeof...(_Vs)>
8428 _M_advance(difference_type __x)
8429 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8437 // Constant time iterator advancement.
8438 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8439 auto& __it = std::get<_Nm>(_M_current);
8440 if constexpr (_Nm == 0)
8442#ifdef _GLIBCXX_ASSERTIONS
8443 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8445 auto __size = ranges::ssize(__r);
8446 auto __begin = ranges::begin(__r);
8447 auto __offset = __it - __begin;
8448 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8455 auto __size = ranges::ssize(__r);
8456 auto __begin = ranges::begin(__r);
8457 auto __offset = __it - __begin;
8459 __x = __offset / __size;
8463 __offset = __size + __offset;
8466 __it = __begin + __offset;
8467 _M_advance<_Nm - 1>(__x);
8472 template<typename _Tuple>
8473 constexpr difference_type
8474 _M_distance_from(const _Tuple& __t) const
8476 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8477 auto __sum = static_cast<difference_type>(0);
8478#ifdef _GLIBCXX_ASSERTIONS
8479 if constexpr (integral<difference_type>)
8482 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8484 __glibcxx_assert(!__overflow);
8488 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8490 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8493 template<size_t _Nm, typename _Tuple>
8494 constexpr difference_type
8495 _M_scaled_distance(const _Tuple& __t) const
8497 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8498 - std::get<_Nm>(__t));
8499#ifdef _GLIBCXX_ASSERTIONS
8500 if constexpr (integral<difference_type>)
8502 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8503 __glibcxx_assert(!__overflow);
8507 __dist *= _M_scaled_size<_Nm+1>();
8511 template<size_t _Nm>
8512 constexpr difference_type
8513 _M_scaled_size() const
8515 if constexpr (_Nm <= sizeof...(_Vs))
8517 auto __size = static_cast<difference_type>(ranges::size
8518 (std::get<_Nm>(_M_parent->_M_bases)));
8519#ifdef _GLIBCXX_ASSERTIONS
8520 if constexpr (integral<difference_type>)
8522 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8523 __glibcxx_assert(!__overflow);
8527 __size *= _M_scaled_size<_Nm+1>();
8531 return static_cast<difference_type>(1);
8539 template<typename... _Ts>
8540 concept __can_cartesian_product_view
8541 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8544 struct _CartesianProduct
8546 template<typename... _Ts>
8547 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8549 operator() [[nodiscard]] (_Ts&&... __ts) const
8551 if constexpr (sizeof...(_Ts) == 0)
8552 return views::empty<tuple<>>;
8554 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8558 inline constexpr _CartesianProduct cartesian_product;
8561#define __cpp_lib_ranges_as_rvalue 202207L
8563 template<input_range _Vp>
8565 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8567 _Vp _M_base = _Vp();
8570 as_rvalue_view() requires default_initializable<_Vp> = default;
8573 as_rvalue_view(_Vp __base)
8574 : _M_base(std::move(__base))
8578 base() const& requires copy_constructible<_Vp>
8583 { return std::move(_M_base); }
8586 begin() requires (!__detail::__simple_view<_Vp>)
8587 { return move_iterator(ranges::begin(_M_base)); }
8590 begin() const requires range<const _Vp>
8591 { return move_iterator(ranges::begin(_M_base)); }
8594 end() requires (!__detail::__simple_view<_Vp>)
8596 if constexpr (common_range<_Vp>)
8597 return move_iterator(ranges::end(_M_base));
8599 return move_sentinel(ranges::end(_M_base));
8603 end() const requires range<const _Vp>
8605 if constexpr (common_range<const _Vp>)
8606 return move_iterator(ranges::end(_M_base));
8608 return move_sentinel(ranges::end(_M_base));
8612 size() requires sized_range<_Vp>
8613 { return ranges::size(_M_base); }
8616 size() const requires sized_range<const _Vp>
8617 { return ranges::size(_M_base); }
8620 template<typename _Range>
8621 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8623 template<typename _Tp>
8624 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8625 = enable_borrowed_range<_Tp>;
8631 template<typename _Tp>
8632 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8635 struct _AsRvalue : __adaptor::_RangeAdaptorClosure
8637 template<viewable_range _Range>
8638 requires __detail::__can_as_rvalue_view<_Range>
8640 operator() [[nodiscard]] (_Range&& __r) const
8642 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8643 range_reference_t<_Range>>)
8644 return views::all(std::forward<_Range>(__r));
8646 return as_rvalue_view(std::forward<_Range>(__r));
8650 inline constexpr _AsRvalue as_rvalue;
8653#define __cpp_lib_ranges_enumerate 202302L
8657 template<typename _Range>
8658 concept __range_with_movable_reference = input_range<_Range>
8659 && move_constructible<range_reference_t<_Range>>
8660 && move_constructible<range_rvalue_reference_t<_Range>>;
8664 requires __detail::__range_with_movable_reference<_Vp>
8665 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8667 _Vp _M_base = _Vp();
8669 template<bool _Const> class _Iterator;
8670 template<bool _Const> class _Sentinel;
8673 enumerate_view() requires default_initializable<_Vp> = default;
8676 enumerate_view(_Vp __base)
8677 : _M_base(std::move(__base))
8681 begin() requires (!__detail::__simple_view<_Vp>)
8682 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8685 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8686 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8689 end() requires (!__detail::__simple_view<_Vp>)
8691 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8692 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8694 return _Sentinel<false>(ranges::end(_M_base));
8698 end() const requires __detail::__range_with_movable_reference<const _Vp>
8700 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8701 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8703 return _Sentinel<true>(ranges::end(_M_base));
8707 size() requires sized_range<_Vp>
8708 { return ranges::size(_M_base); }
8711 size() const requires sized_range<const _Vp>
8712 { return ranges::size(_M_base); }
8715 base() const & requires copy_constructible<_Vp>
8720 { return std::move(_M_base); }
8723 template<typename _Range>
8724 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
8726 template<typename _Tp>
8727 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
8728 = enable_borrowed_range<_Tp>;
8731 requires __detail::__range_with_movable_reference<_Vp>
8732 template<bool _Const>
8733 class enumerate_view<_Vp>::_Iterator
8735 using _Base = __maybe_const_t<_Const, _Vp>;
8740 if constexpr (random_access_range<_Base>)
8741 return random_access_iterator_tag{};
8742 else if constexpr (bidirectional_range<_Base>)
8743 return bidirectional_iterator_tag{};
8744 else if constexpr (forward_range<_Base>)
8745 return forward_iterator_tag{};
8747 return input_iterator_tag{};
8750 friend enumerate_view;
8753 using iterator_category = input_iterator_tag;
8754 using iterator_concept = decltype(_S_iter_concept());
8755 using difference_type = range_difference_t<_Base>;
8756 using value_type = tuple<difference_type, range_value_t<_Base>>;
8759 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
8761 iterator_t<_Base> _M_current = iterator_t<_Base>();
8762 difference_type _M_pos = 0;
8765 _Iterator(iterator_t<_Base> __current, difference_type __pos)
8766 : _M_current(std::move(__current)), _M_pos(__pos)
8770 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8773 _Iterator(_Iterator<!_Const> __i)
8774 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8775 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
8778 constexpr const iterator_t<_Base> &
8779 base() const & noexcept
8780 { return _M_current; }
8782 constexpr iterator_t<_Base>
8784 { return std::move(_M_current); }
8786 constexpr difference_type
8787 index() const noexcept
8792 { return __reference_type(_M_pos, *_M_current); }
8794 constexpr _Iterator&
8807 operator++(int) requires forward_range<_Base>
8814 constexpr _Iterator&
8815 operator--() requires bidirectional_range<_Base>
8823 operator--(int) requires bidirectional_range<_Base>
8830 constexpr _Iterator&
8831 operator+=(difference_type __n) requires random_access_range<_Base>
8838 constexpr _Iterator&
8839 operator-=(difference_type __n) requires random_access_range<_Base>
8847 operator[](difference_type __n) const requires random_access_range<_Base>
8848 { return __reference_type(_M_pos + __n, _M_current[__n]); }
8850 friend constexpr bool
8851 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
8852 { return __x._M_pos == __y._M_pos; }
8854 friend constexpr strong_ordering
8855 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
8856 { return __x._M_pos <=> __y._M_pos; }
8858 friend constexpr _Iterator
8859 operator+(const _Iterator& __x, difference_type __y)
8860 requires random_access_range<_Base>
8861 { return (auto(__x) += __y); }
8863 friend constexpr _Iterator
8864 operator+(difference_type __x, const _Iterator& __y)
8865 requires random_access_range<_Base>
8866 { return auto(__y) += __x; }
8868 friend constexpr _Iterator
8869 operator-(const _Iterator& __x, difference_type __y)
8870 requires random_access_range<_Base>
8871 { return auto(__x) -= __y; }
8873 friend constexpr difference_type
8874 operator-(const _Iterator& __x, const _Iterator& __y)
8875 { return __x._M_pos - __y._M_pos; }
8877 friend constexpr auto
8878 iter_move(const _Iterator& __i)
8879 noexcept(noexcept(ranges::iter_move(__i._M_current))
8880 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
8882 return tuple<difference_type, range_rvalue_reference_t<_Base>>
8883 (__i._M_pos, ranges::iter_move(__i._M_current));
8888 requires __detail::__range_with_movable_reference<_Vp>
8889 template<bool _Const>
8890 class enumerate_view<_Vp>::_Sentinel
8892 using _Base = __maybe_const_t<_Const, _Vp>;
8894 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8897 _Sentinel(sentinel_t<_Base> __end)
8898 : _M_end(std::move(__end))
8901 friend enumerate_view;
8904 _Sentinel() = default;
8907 _Sentinel(_Sentinel<!_Const> __other)
8908 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8909 : _M_end(std::move(__other._M_end))
8912 constexpr sentinel_t<_Base>
8916 template<bool _OtherConst>
8917 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8918 friend constexpr bool
8919 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8920 { return __x._M_current == __y._M_end; }
8922 template<bool _OtherConst>
8923 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8924 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8925 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
8926 { return __x._M_current - __y._M_end; }
8928 template<bool _OtherConst>
8929 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
8930 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
8931 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
8932 { return __x._M_end - __y._M_current; }
8939 template<typename _Tp>
8940 concept __can_enumerate_view
8941 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
8944 struct _Enumerate : __adaptor::_RangeAdaptorClosure
8946 template<viewable_range _Range>
8947 requires __detail::__can_enumerate_view<_Range>
8949 operator() [[nodiscard]] (_Range&& __r) const
8950 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
8953 inline constexpr _Enumerate enumerate;
8956#define __cpp_lib_ranges_as_const 202207L
8959 requires input_range<_Vp>
8960 class as_const_view : public view_interface<as_const_view<_Vp>>
8962 _Vp _M_base = _Vp();
8965 as_const_view() requires default_initializable<_Vp> = default;
8968 as_const_view(_Vp __base)
8969 noexcept(is_nothrow_move_constructible_v<_Vp>)
8970 : _M_base(std::move(__base))
8975 noexcept(is_nothrow_copy_constructible_v<_Vp>)
8976 requires copy_constructible<_Vp>
8981 noexcept(is_nothrow_move_constructible_v<_Vp>)
8982 { return std::move(_M_base); }
8985 begin() requires (!__detail::__simple_view<_Vp>)
8986 { return ranges::cbegin(_M_base); }
8989 begin() const requires range<const _Vp>
8990 { return ranges::cbegin(_M_base); }
8993 end() requires (!__detail::__simple_view<_Vp>)
8994 { return ranges::cend(_M_base); }
8997 end() const requires range<const _Vp>
8998 { return ranges::cend(_M_base); }
9001 size() requires sized_range<_Vp>
9002 { return ranges::size(_M_base); }
9005 size() const requires sized_range<const _Vp>
9006 { return ranges::size(_M_base); }
9009 template<typename _Range>
9010 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9012 template<typename _Tp>
9013 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9014 = enable_borrowed_range<_Tp>;
9020 template<typename _Tp>
9021 inline constexpr bool __is_ref_view = false;
9023 template<typename _Range>
9024 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9026 template<typename _Range>
9027 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9030 struct _AsConst : __adaptor::_RangeAdaptorClosure
9032 template<viewable_range _Range>
9034 operator()(_Range&& __r) const
9035 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9036 requires __detail::__can_as_const_view<_Range>
9038 using _Tp = remove_cvref_t<_Range>;
9039 using element_type = remove_reference_t<range_reference_t<_Range>>;
9040 if constexpr (constant_range<views::all_t<_Range>>)
9041 return views::all(std::forward<_Range>(__r));
9042 else if constexpr (__detail::__is_empty_view<_Tp>)
9043 return views::empty<const element_type>;
9044 else if constexpr (std::__detail::__is_span<_Tp>)
9045 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9046 else if constexpr (__detail::__is_ref_view<_Tp>
9047 && constant_range<const element_type>)
9048 return ref_view(static_cast<const element_type&>
9049 (std::forward<_Range>(__r).base()));
9050 else if constexpr (is_lvalue_reference_v<_Range>
9051 && constant_range<const _Tp>
9053 return ref_view(static_cast<const _Tp&>(__r));
9055 return as_const_view(std::forward<_Range>(__r));
9059 inline constexpr _AsConst as_const;
9062} // namespace ranges
9064 namespace views = ranges::views;
9066_GLIBCXX_END_NAMESPACE_VERSION
9068#endif // library concepts
9070#endif /* _GLIBCXX_RANGES */