3// Copyright (C) 2019-2024 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
52#include <bits/ranges_util.h>
53#include <bits/refwrap.h>
55#define __glibcxx_want_ranges
56#define __glibcxx_want_ranges_as_const
57#define __glibcxx_want_ranges_as_rvalue
58#define __glibcxx_want_ranges_cartesian_product
59#define __glibcxx_want_ranges_chunk
60#define __glibcxx_want_ranges_chunk_by
61#define __glibcxx_want_ranges_enumerate
62#define __glibcxx_want_ranges_iota
63#define __glibcxx_want_ranges_join_with
64#define __glibcxx_want_ranges_repeat
65#define __glibcxx_want_ranges_slide
66#define __glibcxx_want_ranges_stride
67#define __glibcxx_want_ranges_to_container
68#define __glibcxx_want_ranges_zip
69#include <bits/version.h>
71#ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine
72# include <bits/elements_of.h>
76 * @defgroup ranges Ranges
78 * Components for dealing with ranges of elements.
81namespace std _GLIBCXX_VISIBILITY(default)
83_GLIBCXX_BEGIN_NAMESPACE_VERSION
86 // [range.access] customization point objects
87 // [range.req] range and view concepts
88 // [range.dangling] dangling iterator handling
89 // Defined in <bits/ranges_base.h>
91 // [view.interface] View interface
92 // [range.subrange] Sub-ranges
93 // Defined in <bits/ranges_util.h>
95 // C++20 24.6 [range.factories] Range factories
97 /// A view that contains no elements.
98 template<typename _Tp> requires is_object_v<_Tp>
100 : public view_interface<empty_view<_Tp>>
103 static constexpr _Tp* begin() noexcept { return nullptr; }
104 static constexpr _Tp* end() noexcept { return nullptr; }
105 static constexpr _Tp* data() noexcept { return nullptr; }
106 static constexpr size_t size() noexcept { return 0; }
107 static constexpr bool empty() noexcept { return true; }
110 template<typename _Tp>
111 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
115#if __cpp_lib_ranges >= 202207L // C++ >= 23
116 // P2494R2 Relaxing range adaptors to allow for move only types
117 template<typename _Tp>
118 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
120 template<typename _Tp>
121 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
124 template<__boxable _Tp>
125 struct __box : std::optional<_Tp>
127 using std::optional<_Tp>::optional;
131 noexcept(is_nothrow_default_constructible_v<_Tp>)
132 requires default_initializable<_Tp>
133 : std::optional<_Tp>{std::in_place}
136 __box(const __box&) = default;
137 __box(__box&&) = default;
139 using std::optional<_Tp>::operator=;
141 // _GLIBCXX_RESOLVE_LIB_DEFECTS
142 // 3477. Simplify constraints for semiregular-box
143 // 3572. copyable-box should be fully constexpr
145 operator=(const __box& __that)
146 noexcept(is_nothrow_copy_constructible_v<_Tp>)
147 requires (!copyable<_Tp>) && copy_constructible<_Tp>
149 if (this != std::__addressof(__that))
152 this->emplace(*__that);
160 operator=(__box&& __that)
161 noexcept(is_nothrow_move_constructible_v<_Tp>)
162 requires (!movable<_Tp>)
164 if (this != std::__addressof(__that))
167 this->emplace(std::move(*__that));
175 template<typename _Tp>
176 concept __boxable_copyable
177 = copy_constructible<_Tp>
178 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
179 && is_nothrow_copy_constructible_v<_Tp>));
180 template<typename _Tp>
181 concept __boxable_movable
182 = (!copy_constructible<_Tp>)
183 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
185 // For types which are already copyable (or since C++23, movable)
186 // this specialization of the box wrapper stores the object directly
187 // without going through std::optional. It provides just the subset of
188 // the primary template's API that we currently use.
189 template<__boxable _Tp>
190 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
194 [[no_unique_address]] _Tp _M_value = _Tp();
197 __box() requires default_initializable<_Tp> = default;
200 __box(const _Tp& __t)
201 noexcept(is_nothrow_copy_constructible_v<_Tp>)
202 requires copy_constructible<_Tp>
208 noexcept(is_nothrow_move_constructible_v<_Tp>)
209 : _M_value(std::move(__t))
212 template<typename... _Args>
213 requires constructible_from<_Tp, _Args...>
215 __box(in_place_t, _Args&&... __args)
216 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
217 : _M_value(std::forward<_Args>(__args)...)
220 __box(const __box&) = default;
221 __box(__box&&) = default;
222 __box& operator=(const __box&) requires copyable<_Tp> = default;
223 __box& operator=(__box&&) requires movable<_Tp> = default;
225 // When _Tp is nothrow_copy_constructible but not copy_assignable,
226 // copy assignment is implemented via destroy-then-copy-construct.
228 operator=(const __box& __that) noexcept
229 requires (!copyable<_Tp>) && copy_constructible<_Tp>
231 static_assert(is_nothrow_copy_constructible_v<_Tp>);
232 if (this != std::__addressof(__that))
235 std::construct_at(std::__addressof(_M_value), *__that);
240 // Likewise for move assignment.
242 operator=(__box&& __that) noexcept
243 requires (!movable<_Tp>)
245 static_assert(is_nothrow_move_constructible_v<_Tp>);
246 if (this != std::__addressof(__that))
249 std::construct_at(std::__addressof(_M_value), std::move(*__that));
255 has_value() const noexcept
259 operator*() & noexcept
263 operator*() const & noexcept
267 operator*() && noexcept
268 { return std::move(_M_value); }
270 constexpr const _Tp&&
271 operator*() const && noexcept
272 { return std::move(_M_value); }
275 operator->() noexcept
276 { return std::__addressof(_M_value); }
279 operator->() const noexcept
280 { return std::__addressof(_M_value); }
282 } // namespace __detail
284 /// A view that contains exactly one element.
285#if __cpp_lib_ranges >= 202207L // C++ >= 23
286 template<move_constructible _Tp>
288 template<copy_constructible _Tp>
290 requires is_object_v<_Tp>
291 class single_view : public view_interface<single_view<_Tp>>
294 single_view() requires default_initializable<_Tp> = default;
297 single_view(const _Tp& __t)
298 noexcept(is_nothrow_copy_constructible_v<_Tp>)
299 requires copy_constructible<_Tp>
304 single_view(_Tp&& __t)
305 noexcept(is_nothrow_move_constructible_v<_Tp>)
306 : _M_value(std::move(__t))
309 // _GLIBCXX_RESOLVE_LIB_DEFECTS
310 // 3428. single_view's in place constructor should be explicit
311 template<typename... _Args>
312 requires constructible_from<_Tp, _Args...>
314 single_view(in_place_t, _Args&&... __args)
315 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
316 : _M_value{in_place, std::forward<_Args>(__args)...}
324 begin() const noexcept
329 { return data() + 1; }
333 { return data() + 1; }
335 // _GLIBCXX_RESOLVE_LIB_DEFECTS
336 // 4035. single_view should provide empty
337 static constexpr bool
341 static constexpr size_t
347 { return _M_value.operator->(); }
350 data() const noexcept
351 { return _M_value.operator->(); }
354 [[no_unique_address]] __detail::__box<_Tp> _M_value;
357 template<typename _Tp>
358 single_view(_Tp) -> single_view<_Tp>;
362 template<typename _Wp>
363 constexpr auto __to_signed_like(_Wp __w) noexcept
365 if constexpr (!integral<_Wp>)
366 return iter_difference_t<_Wp>();
367 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
368 return iter_difference_t<_Wp>(__w);
369 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
370 return ptrdiff_t(__w);
371 else if constexpr (sizeof(long long) > sizeof(_Wp))
372 return (long long)(__w);
373#ifdef __SIZEOF_INT128__
374 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
375 return __int128(__w);
378 return __max_diff_type(__w);
381 template<typename _Wp>
382 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
384 template<typename _It>
385 concept __decrementable = incrementable<_It>
388 { --__i } -> same_as<_It&>;
389 { __i-- } -> same_as<_It>;
392 template<typename _It>
393 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
394 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
396 { __i += __n } -> same_as<_It&>;
397 { __i -= __n } -> same_as<_It&>;
401 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
404 template<typename _Winc>
405 struct __iota_view_iter_cat
408 template<incrementable _Winc>
409 struct __iota_view_iter_cat<_Winc>
410 { using iterator_category = input_iterator_tag; };
411 } // namespace __detail
413 template<weakly_incrementable _Winc,
414 semiregular _Bound = unreachable_sentinel_t>
415 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
417 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
422 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
428 using namespace __detail;
429 if constexpr (__advanceable<_Winc>)
430 return random_access_iterator_tag{};
431 else if constexpr (__decrementable<_Winc>)
432 return bidirectional_iterator_tag{};
433 else if constexpr (incrementable<_Winc>)
434 return forward_iterator_tag{};
436 return input_iterator_tag{};
440 using iterator_concept = decltype(_S_iter_concept());
441 // iterator_category defined in __iota_view_iter_cat
442 using value_type = _Winc;
443 using difference_type = __detail::__iota_diff_t<_Winc>;
445 _Iterator() requires default_initializable<_Winc> = default;
448 _Iterator(_Winc __value)
449 : _M_value(__value) { }
452 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
467 operator++(int) requires incrementable<_Winc>
475 operator--() requires __detail::__decrementable<_Winc>
482 operator--(int) requires __detail::__decrementable<_Winc>
490 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
492 using __detail::__is_integer_like;
493 using __detail::__is_signed_integer_like;
494 if constexpr (__is_integer_like<_Winc>
495 && !__is_signed_integer_like<_Winc>)
497 if (__n >= difference_type(0))
498 _M_value += static_cast<_Winc>(__n);
500 _M_value -= static_cast<_Winc>(-__n);
508 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
510 using __detail::__is_integer_like;
511 using __detail::__is_signed_integer_like;
512 if constexpr (__is_integer_like<_Winc>
513 && !__is_signed_integer_like<_Winc>)
515 if (__n >= difference_type(0))
516 _M_value -= static_cast<_Winc>(__n);
518 _M_value += static_cast<_Winc>(-__n);
526 operator[](difference_type __n) const
527 requires __detail::__advanceable<_Winc>
528 { return _Winc(_M_value + __n); }
530 friend constexpr bool
531 operator==(const _Iterator& __x, const _Iterator& __y)
532 requires equality_comparable<_Winc>
533 { return __x._M_value == __y._M_value; }
535 friend constexpr bool
536 operator<(const _Iterator& __x, const _Iterator& __y)
537 requires totally_ordered<_Winc>
538 { return __x._M_value < __y._M_value; }
540 friend constexpr bool
541 operator>(const _Iterator& __x, const _Iterator& __y)
542 requires totally_ordered<_Winc>
543 { return __y < __x; }
545 friend constexpr bool
546 operator<=(const _Iterator& __x, const _Iterator& __y)
547 requires totally_ordered<_Winc>
548 { return !(__y < __x); }
550 friend constexpr bool
551 operator>=(const _Iterator& __x, const _Iterator& __y)
552 requires totally_ordered<_Winc>
553 { return !(__x < __y); }
555#ifdef __cpp_lib_three_way_comparison
556 friend constexpr auto
557 operator<=>(const _Iterator& __x, const _Iterator& __y)
558 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
559 { return __x._M_value <=> __y._M_value; }
562 friend constexpr _Iterator
563 operator+(_Iterator __i, difference_type __n)
564 requires __detail::__advanceable<_Winc>
570 friend constexpr _Iterator
571 operator+(difference_type __n, _Iterator __i)
572 requires __detail::__advanceable<_Winc>
573 { return __i += __n; }
575 friend constexpr _Iterator
576 operator-(_Iterator __i, difference_type __n)
577 requires __detail::__advanceable<_Winc>
583 friend constexpr difference_type
584 operator-(const _Iterator& __x, const _Iterator& __y)
585 requires __detail::__advanceable<_Winc>
587 using __detail::__is_integer_like;
588 using __detail::__is_signed_integer_like;
589 using _Dt = difference_type;
590 if constexpr (__is_integer_like<_Winc>)
592 if constexpr (__is_signed_integer_like<_Winc>)
593 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
595 return (__y._M_value > __x._M_value)
596 ? _Dt(-_Dt(__y._M_value - __x._M_value))
597 : _Dt(__x._M_value - __y._M_value);
600 return __x._M_value - __y._M_value;
604 _Winc _M_value = _Winc();
614 _M_equal(const _Iterator& __x) const
615 { return __x._M_value == _M_bound; }
618 _M_distance_from(const _Iterator& __x) const
619 { return _M_bound - __x._M_value; }
621 _Bound _M_bound = _Bound();
624 _Sentinel() = default;
627 _Sentinel(_Bound __bound)
628 : _M_bound(__bound) { }
630 friend constexpr bool
631 operator==(const _Iterator& __x, const _Sentinel& __y)
632 { return __y._M_equal(__x); }
634 friend constexpr iter_difference_t<_Winc>
635 operator-(const _Iterator& __x, const _Sentinel& __y)
636 requires sized_sentinel_for<_Bound, _Winc>
637 { return -__y._M_distance_from(__x); }
639 friend constexpr iter_difference_t<_Winc>
640 operator-(const _Sentinel& __x, const _Iterator& __y)
641 requires sized_sentinel_for<_Bound, _Winc>
642 { return __x._M_distance_from(__y); }
647 _Winc _M_value = _Winc();
648 [[no_unique_address]] _Bound _M_bound = _Bound();
651 iota_view() requires default_initializable<_Winc> = default;
654 iota_view(_Winc __value)
659 iota_view(type_identity_t<_Winc> __value,
660 type_identity_t<_Bound> __bound)
661 : _M_value(__value), _M_bound(__bound)
663 if constexpr (totally_ordered_with<_Winc, _Bound>)
664 __glibcxx_assert( bool(__value <= __bound) );
668 iota_view(_Iterator __first, _Iterator __last)
669 requires same_as<_Winc, _Bound>
670 : iota_view(__first._M_value, __last._M_value)
674 iota_view(_Iterator __first, unreachable_sentinel_t __last)
675 requires same_as<_Bound, unreachable_sentinel_t>
676 : iota_view(__first._M_value, __last)
680 iota_view(_Iterator __first, _Sentinel __last)
681 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
682 : iota_view(__first._M_value, __last._M_bound)
686 begin() const { return _Iterator{_M_value}; }
691 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
692 return unreachable_sentinel;
694 return _Sentinel{_M_bound};
698 end() const requires same_as<_Winc, _Bound>
699 { return _Iterator{_M_bound}; }
701 // _GLIBCXX_RESOLVE_LIB_DEFECTS
702 // 4001. iota_view should provide empty
705 { return _M_value == _M_bound; }
709 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
710 || (integral<_Winc> && integral<_Bound>)
711 || sized_sentinel_for<_Bound, _Winc>
713 using __detail::__is_integer_like;
714 using __detail::__to_unsigned_like;
715 if constexpr (integral<_Winc> && integral<_Bound>)
717 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
718 return _Up(_M_bound) - _Up(_M_value);
720 else if constexpr (__is_integer_like<_Winc>)
721 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
723 return __to_unsigned_like(_M_bound - _M_value);
727 template<typename _Winc, typename _Bound>
728 requires (!__detail::__is_integer_like<_Winc>
729 || !__detail::__is_integer_like<_Bound>
730 || (__detail::__is_signed_integer_like<_Winc>
731 == __detail::__is_signed_integer_like<_Bound>))
732 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
734 template<typename _Winc, typename _Bound>
735 inline constexpr bool
736 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
740 template<typename _Tp>
741 inline constexpr empty_view<_Tp> empty{};
745 template<typename _Tp>
746 concept __can_single_view
747 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
748 } // namespace __detail
752 template<__detail::__can_single_view _Tp>
754 operator() [[nodiscard]] (_Tp&& __e) const
755 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
756 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
759 inline constexpr _Single single{};
763 template<typename... _Args>
764 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
765 } // namespace __detail
769 template<__detail::__can_iota_view _Tp>
771 operator() [[nodiscard]] (_Tp&& __e) const
772 { return iota_view(std::forward<_Tp>(__e)); }
774 template<typename _Tp, typename _Up>
775 requires __detail::__can_iota_view<_Tp, _Up>
777 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
778 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
781 inline constexpr _Iota iota{};
787 template<typename _Val, typename _CharT, typename _Traits>
788 concept __stream_extractable
789 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
790 } // namespace __detail
792 template<movable _Val, typename _CharT,
793 typename _Traits = char_traits<_CharT>>
794 requires default_initializable<_Val>
795 && __detail::__stream_extractable<_Val, _CharT, _Traits>
796 class basic_istream_view
797 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
801 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
802 : _M_stream(std::__addressof(__stream))
808 *_M_stream >> _M_object;
809 return _Iterator{this};
812 constexpr default_sentinel_t
814 { return default_sentinel; }
817 basic_istream<_CharT, _Traits>* _M_stream;
818 _Val _M_object = _Val();
823 using iterator_concept = input_iterator_tag;
824 using difference_type = ptrdiff_t;
825 using value_type = _Val;
828 _Iterator(basic_istream_view* __parent) noexcept
829 : _M_parent(__parent)
832 _Iterator(const _Iterator&) = delete;
833 _Iterator(_Iterator&&) = default;
834 _Iterator& operator=(const _Iterator&) = delete;
835 _Iterator& operator=(_Iterator&&) = default;
840 *_M_parent->_M_stream >> _M_parent->_M_object;
850 { return _M_parent->_M_object; }
853 operator==(const _Iterator& __x, default_sentinel_t)
854 { return __x._M_at_end(); }
857 basic_istream_view* _M_parent;
861 { return !*_M_parent->_M_stream; }
867 template<typename _Val>
868 using istream_view = basic_istream_view<_Val, char>;
870 template<typename _Val>
871 using wistream_view = basic_istream_view<_Val, wchar_t>;
877 template<typename _Tp, typename _Up>
878 concept __can_istream_view = requires (_Up __e) {
879 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
881 } // namespace __detail
883 template<typename _Tp>
886 template<typename _CharT, typename _Traits>
888 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
889 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
890 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
893 template<typename _Tp>
894 inline constexpr _Istream<_Tp> istream;
898 // C++20 24.7 [range.adaptors] Range adaptors
902 template<typename _Tp, int _Disc>
905 // Alias for a type that is conditionally present
906 // (and is an empty type otherwise).
907 // Data members using this alias should use [[no_unique_address]] so that
908 // they take no space when not needed.
909 // The optional template parameter _Disc is for discriminating two otherwise
910 // equivalent absent types so that even they can overlap.
911 template<bool _Present, typename _Tp, int _Disc = 0>
912 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
914 // Alias for a type that is conditionally const.
915 template<bool _Const, typename _Tp>
916 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
918} // namespace __detail
920// Shorthand for __detail::__maybe_const_t.
921using __detail::__maybe_const_t;
923namespace views::__adaptor
925 // True if the range adaptor _Adaptor can be applied with _Args.
926 template<typename _Adaptor, typename... _Args>
927 concept __adaptor_invocable
928 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
930 // True if the range adaptor non-closure _Adaptor can be partially applied
932 template<typename _Adaptor, typename... _Args>
933 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
934 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
935 && (constructible_from<decay_t<_Args>, _Args> && ...);
937 template<typename _Adaptor, typename... _Args>
940 template<typename _Lhs, typename _Rhs>
943 // The base class of every range adaptor closure.
945 // The derived class should define the optional static data member
946 // _S_has_simple_call_op to true if the behavior of this adaptor is
947 // independent of the constness/value category of the adaptor object.
948 template<typename _Derived>
949 struct _RangeAdaptorClosure
952 template<typename _Tp, typename _Up>
953 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
954 void __is_range_adaptor_closure_fn
955 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
957 template<typename _Tp>
958 concept __is_range_adaptor_closure
959 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
961#pragma GCC diagnostic push
962#pragma GCC diagnostic ignored "-Wdangling-reference"
963 // range | adaptor is equivalent to adaptor(range).
964 template<typename _Self, typename _Range>
965 requires __is_range_adaptor_closure<_Self>
966 && __adaptor_invocable<_Self, _Range>
968 operator|(_Range&& __r, _Self&& __self)
969 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
971 // Compose the adaptors __lhs and __rhs into a pipeline, returning
972 // another range adaptor closure object.
973 template<typename _Lhs, typename _Rhs>
974 requires __is_range_adaptor_closure<_Lhs>
975 && __is_range_adaptor_closure<_Rhs>
977 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
979 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
980 std::forward<_Rhs>(__rhs)};
982#pragma GCC diagnostic pop
984 // The base class of every range adaptor non-closure.
986 // The static data member _Derived::_S_arity must contain the total number of
987 // arguments that the adaptor takes, and the class _Derived must introduce
988 // _RangeAdaptor::operator() into the class scope via a using-declaration.
990 // The optional static data member _Derived::_S_has_simple_extra_args should
991 // be defined to true if the behavior of this adaptor is independent of the
992 // constness/value category of the extra arguments. This data member could
993 // also be defined as a variable template parameterized by the types of the
995 template<typename _Derived>
998 // Partially apply the arguments __args to the range adaptor _Derived,
999 // returning a range adaptor closure object.
1000 template<typename... _Args>
1001 requires __adaptor_partial_app_viable<_Derived, _Args...>
1003 operator()(_Args&&... __args) const
1005 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1009 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1010 // one that's not overloaded according to constness or value category of the
1012 template<typename _Adaptor>
1013 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1015 // True if the behavior of the range adaptor non-closure _Adaptor is
1016 // independent of the value category of its extra arguments _Args.
1017 template<typename _Adaptor, typename... _Args>
1018 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1019 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1021 // A range adaptor closure that represents partial application of
1022 // the range adaptor _Adaptor with arguments _Args.
1023 template<typename _Adaptor, typename... _Args>
1024 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1026 tuple<_Args...> _M_args;
1028 // First parameter is to ensure this constructor is never used
1029 // instead of the copy/move constructor.
1030 template<typename... _Ts>
1032 _Partial(int, _Ts&&... __args)
1033 : _M_args(std::forward<_Ts>(__args)...)
1036 // Invoke _Adaptor with arguments __r, _M_args... according to the
1037 // value category of this _Partial object.
1038#if __cpp_explicit_this_parameter
1039 template<typename _Self, typename _Range>
1040 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1042 operator()(this _Self&& __self, _Range&& __r)
1044 auto __forwarder = [&__r] (auto&&... __args) {
1045 return _Adaptor{}(std::forward<_Range>(__r),
1046 std::forward<decltype(__args)>(__args)...);
1048 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args);
1051 template<typename _Range>
1052 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1054 operator()(_Range&& __r) const &
1056 auto __forwarder = [&__r] (const auto&... __args) {
1057 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1059 return std::apply(__forwarder, _M_args);
1062 template<typename _Range>
1063 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1065 operator()(_Range&& __r) &&
1067 auto __forwarder = [&__r] (auto&... __args) {
1068 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
1070 return std::apply(__forwarder, _M_args);
1073 template<typename _Range>
1075 operator()(_Range&& __r) const && = delete;
1079 // A lightweight specialization of the above primary template for
1080 // the common case where _Adaptor accepts a single extra argument.
1081 template<typename _Adaptor, typename _Arg>
1082 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1086 template<typename _Tp>
1088 _Partial(int, _Tp&& __arg)
1089 : _M_arg(std::forward<_Tp>(__arg))
1092#if __cpp_explicit_this_parameter
1093 template<typename _Self, typename _Range>
1094 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1096 operator()(this _Self&& __self, _Range&& __r)
1098 return _Adaptor{}(std::forward<_Range>(__r),
1099 __like_t<_Self, _Partial>(__self)._M_arg);
1102 template<typename _Range>
1103 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1105 operator()(_Range&& __r) const &
1106 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1108 template<typename _Range>
1109 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1111 operator()(_Range&& __r) &&
1112 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
1114 template<typename _Range>
1116 operator()(_Range&& __r) const && = delete;
1120 // Partial specialization of the primary template for the case where the extra
1121 // arguments of the adaptor can always be safely and efficiently forwarded by
1122 // const reference. This lets us get away with a single operator() overload,
1123 // which makes overload resolution failure diagnostics more concise.
1124 template<typename _Adaptor, typename... _Args>
1125 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1126 && (is_trivially_copy_constructible_v<_Args> && ...)
1127 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1129 tuple<_Args...> _M_args;
1131 template<typename... _Ts>
1133 _Partial(int, _Ts&&... __args)
1134 : _M_args(std::forward<_Ts>(__args)...)
1137 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1138 // of the value category of this _Partial object.
1139 template<typename _Range>
1140 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1142 operator()(_Range&& __r) const
1144 auto __forwarder = [&__r] (const auto&... __args) {
1145 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1147 return std::apply(__forwarder, _M_args);
1150 static constexpr bool _S_has_simple_call_op = true;
1153 // A lightweight specialization of the above template for the common case
1154 // where _Adaptor accepts a single extra argument.
1155 template<typename _Adaptor, typename _Arg>
1156 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1157 && is_trivially_copy_constructible_v<_Arg>
1158 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1162 template<typename _Tp>
1164 _Partial(int, _Tp&& __arg)
1165 : _M_arg(std::forward<_Tp>(__arg))
1168 template<typename _Range>
1169 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1171 operator()(_Range&& __r) const
1172 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1174 static constexpr bool _S_has_simple_call_op = true;
1177 template<typename _Lhs, typename _Rhs, typename _Range>
1178 concept __pipe_invocable
1179 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1181 // A range adaptor closure that represents composition of the range
1182 // adaptor closures _Lhs and _Rhs.
1183 template<typename _Lhs, typename _Rhs>
1184 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1186 [[no_unique_address]] _Lhs _M_lhs;
1187 [[no_unique_address]] _Rhs _M_rhs;
1189 template<typename _Tp, typename _Up>
1191 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1192 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1195 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1196 // range adaptor closure object.
1197#if __cpp_explicit_this_parameter
1198 template<typename _Self, typename _Range>
1199 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1201 operator()(this _Self&& __self, _Range&& __r)
1203 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1204 (__like_t<_Self, _Pipe>(__self)._M_lhs
1205 (std::forward<_Range>(__r))));
1208 template<typename _Range>
1209 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1211 operator()(_Range&& __r) const &
1212 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1214 template<typename _Range>
1215 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1217 operator()(_Range&& __r) &&
1218 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1220 template<typename _Range>
1222 operator()(_Range&& __r) const && = delete;
1226 // A partial specialization of the above primary template for the case where
1227 // both adaptor operands have a simple operator(). This in turn lets us
1228 // implement composition using a single simple operator(), which makes
1229 // overload resolution failure diagnostics more concise.
1230 template<typename _Lhs, typename _Rhs>
1231 requires __closure_has_simple_call_op<_Lhs>
1232 && __closure_has_simple_call_op<_Rhs>
1233 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1235 [[no_unique_address]] _Lhs _M_lhs;
1236 [[no_unique_address]] _Rhs _M_rhs;
1238 template<typename _Tp, typename _Up>
1240 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1241 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1244 template<typename _Range>
1245 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1247 operator()(_Range&& __r) const
1248 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1250 static constexpr bool _S_has_simple_call_op = true;
1252} // namespace views::__adaptor
1254#if __cpp_lib_ranges >= 202202L
1255 // P2387R3 Pipe support for user-defined range adaptors
1256 template<typename _Derived>
1257 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1258 class range_adaptor_closure
1259 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1263 template<range _Range> requires is_object_v<_Range>
1264 class ref_view : public view_interface<ref_view<_Range>>
1269 static void _S_fun(_Range&); // not defined
1270 static void _S_fun(_Range&&) = delete;
1273 template<__detail::__different_from<ref_view> _Tp>
1274 requires convertible_to<_Tp, _Range&>
1275 && requires { _S_fun(declval<_Tp>()); }
1278 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1279 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1286 constexpr iterator_t<_Range>
1288 { return ranges::begin(*_M_r); }
1290 constexpr sentinel_t<_Range>
1292 { return ranges::end(*_M_r); }
1295 empty() const requires requires { ranges::empty(*_M_r); }
1296 { return ranges::empty(*_M_r); }
1299 size() const requires sized_range<_Range>
1300 { return ranges::size(*_M_r); }
1303 data() const requires contiguous_range<_Range>
1304 { return ranges::data(*_M_r); }
1307 template<typename _Range>
1308 ref_view(_Range&) -> ref_view<_Range>;
1310 template<typename _Tp>
1311 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1313 template<range _Range>
1314 requires movable<_Range>
1315 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1316 class owning_view : public view_interface<owning_view<_Range>>
1319 _Range _M_r = _Range();
1322 owning_view() requires default_initializable<_Range> = default;
1325 owning_view(_Range&& __t)
1326 noexcept(is_nothrow_move_constructible_v<_Range>)
1327 : _M_r(std::move(__t))
1330 owning_view(owning_view&&) = default;
1331 owning_view& operator=(owning_view&&) = default;
1337 constexpr const _Range&
1338 base() const& noexcept
1343 { return std::move(_M_r); }
1345 constexpr const _Range&&
1346 base() const&& noexcept
1347 { return std::move(_M_r); }
1349 constexpr iterator_t<_Range>
1351 { return ranges::begin(_M_r); }
1353 constexpr sentinel_t<_Range>
1355 { return ranges::end(_M_r); }
1358 begin() const requires range<const _Range>
1359 { return ranges::begin(_M_r); }
1362 end() const requires range<const _Range>
1363 { return ranges::end(_M_r); }
1366 empty() requires requires { ranges::empty(_M_r); }
1367 { return ranges::empty(_M_r); }
1370 empty() const requires requires { ranges::empty(_M_r); }
1371 { return ranges::empty(_M_r); }
1374 size() requires sized_range<_Range>
1375 { return ranges::size(_M_r); }
1378 size() const requires sized_range<const _Range>
1379 { return ranges::size(_M_r); }
1382 data() requires contiguous_range<_Range>
1383 { return ranges::data(_M_r); }
1386 data() const requires contiguous_range<const _Range>
1387 { return ranges::data(_M_r); }
1390 template<typename _Tp>
1391 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1392 = enable_borrowed_range<_Tp>;
1398 template<typename _Range>
1399 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1401 template<typename _Range>
1402 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1403 } // namespace __detail
1405 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1407 template<typename _Range>
1408 static constexpr bool
1411 if constexpr (view<decay_t<_Range>>)
1412 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1413 else if constexpr (__detail::__can_ref_view<_Range>)
1416 return noexcept(owning_view{std::declval<_Range>()});
1419 template<viewable_range _Range>
1420 requires view<decay_t<_Range>>
1421 || __detail::__can_ref_view<_Range>
1422 || __detail::__can_owning_view<_Range>
1424 operator() [[nodiscard]] (_Range&& __r) const
1425 noexcept(_S_noexcept<_Range>())
1427 if constexpr (view<decay_t<_Range>>)
1428 return std::forward<_Range>(__r);
1429 else if constexpr (__detail::__can_ref_view<_Range>)
1430 return ref_view{std::forward<_Range>(__r)};
1432 return owning_view{std::forward<_Range>(__r)};
1435 static constexpr bool _S_has_simple_call_op = true;
1438 inline constexpr _All all;
1440 template<viewable_range _Range>
1441 using all_t = decltype(all(std::declval<_Range>()));
1442 } // namespace views
1446 template<typename _Tp>
1447 struct __non_propagating_cache
1449 // When _Tp is not an object type (e.g. is a reference type), we make
1450 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1451 // users can easily conditionally declare data members with this type
1452 // (such as join_view::_M_inner).
1455 template<typename _Tp>
1456 requires is_object_v<_Tp>
1457 struct __non_propagating_cache<_Tp>
1458 : protected _Optional_base<_Tp>
1460 __non_propagating_cache() = default;
1463 __non_propagating_cache(const __non_propagating_cache&) noexcept
1467 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1468 { __other._M_reset(); }
1470 constexpr __non_propagating_cache&
1471 operator=(const __non_propagating_cache& __other) noexcept
1473 if (std::__addressof(__other) != this)
1478 constexpr __non_propagating_cache&
1479 operator=(__non_propagating_cache&& __other) noexcept
1486 constexpr __non_propagating_cache&
1487 operator=(_Tp __val)
1490 this->_M_payload._M_construct(std::move(__val));
1495 operator bool() const noexcept
1496 { return this->_M_is_engaged(); }
1499 operator*() noexcept
1500 { return this->_M_get(); }
1502 constexpr const _Tp&
1503 operator*() const noexcept
1504 { return this->_M_get(); }
1506 template<typename _Iter>
1508 _M_emplace_deref(const _Iter& __i)
1511 auto __f = [] (auto& __x) { return *__x; };
1512 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1513 return this->_M_get();
1517 template<range _Range>
1518 struct _CachedPosition
1521 _M_has_value() const
1524 constexpr iterator_t<_Range>
1525 _M_get(const _Range&) const
1527 __glibcxx_assert(false);
1528 __builtin_unreachable();
1532 _M_set(const _Range&, const iterator_t<_Range>&) const
1536 template<forward_range _Range>
1537 struct _CachedPosition<_Range>
1538 : protected __non_propagating_cache<iterator_t<_Range>>
1541 _M_has_value() const
1542 { return this->_M_is_engaged(); }
1544 constexpr iterator_t<_Range>
1545 _M_get(const _Range&) const
1547 __glibcxx_assert(_M_has_value());
1552 _M_set(const _Range&, const iterator_t<_Range>& __it)
1554 __glibcxx_assert(!_M_has_value());
1555 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1557 this->_M_payload._M_engaged = true;
1561 template<random_access_range _Range>
1562 requires (sizeof(range_difference_t<_Range>)
1563 <= sizeof(iterator_t<_Range>))
1564 struct _CachedPosition<_Range>
1567 range_difference_t<_Range> _M_offset = -1;
1570 _CachedPosition() = default;
1573 _CachedPosition(const _CachedPosition&) = default;
1576 _CachedPosition(_CachedPosition&& __other) noexcept
1577 { *this = std::move(__other); }
1579 constexpr _CachedPosition&
1580 operator=(const _CachedPosition&) = default;
1582 constexpr _CachedPosition&
1583 operator=(_CachedPosition&& __other) noexcept
1585 // Propagate the cached offset, but invalidate the source.
1586 _M_offset = __other._M_offset;
1587 __other._M_offset = -1;
1592 _M_has_value() const
1593 { return _M_offset >= 0; }
1595 constexpr iterator_t<_Range>
1596 _M_get(_Range& __r) const
1598 __glibcxx_assert(_M_has_value());
1599 return ranges::begin(__r) + _M_offset;
1603 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1605 __glibcxx_assert(!_M_has_value());
1606 _M_offset = __it - ranges::begin(__r);
1609 } // namespace __detail
1613 template<typename _Base>
1614 struct __filter_view_iter_cat
1617 template<forward_range _Base>
1618 struct __filter_view_iter_cat<_Base>
1624 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1625 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1626 return bidirectional_iterator_tag{};
1627 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1628 return forward_iterator_tag{};
1633 using iterator_category = decltype(_S_iter_cat());
1635 } // namespace __detail
1637 template<input_range _Vp,
1638 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1639 requires view<_Vp> && is_object_v<_Pred>
1640 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1645 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1648 static constexpr auto
1651 if constexpr (bidirectional_range<_Vp>)
1652 return bidirectional_iterator_tag{};
1653 else if constexpr (forward_range<_Vp>)
1654 return forward_iterator_tag{};
1656 return input_iterator_tag{};
1661 using _Vp_iter = iterator_t<_Vp>;
1663 _Vp_iter _M_current = _Vp_iter();
1664 filter_view* _M_parent = nullptr;
1667 using iterator_concept = decltype(_S_iter_concept());
1668 // iterator_category defined in __filter_view_iter_cat
1669 using value_type = range_value_t<_Vp>;
1670 using difference_type = range_difference_t<_Vp>;
1672 _Iterator() requires default_initializable<_Vp_iter> = default;
1675 _Iterator(filter_view* __parent, _Vp_iter __current)
1676 : _M_current(std::move(__current)),
1680 constexpr const _Vp_iter&
1681 base() const & noexcept
1682 { return _M_current; }
1686 { return std::move(_M_current); }
1688 constexpr range_reference_t<_Vp>
1690 { return *_M_current; }
1694 requires __detail::__has_arrow<_Vp_iter>
1695 && copyable<_Vp_iter>
1696 { return _M_current; }
1698 constexpr _Iterator&
1701 _M_current = ranges::find_if(std::move(++_M_current),
1702 ranges::end(_M_parent->_M_base),
1703 std::ref(*_M_parent->_M_pred));
1712 operator++(int) requires forward_range<_Vp>
1719 constexpr _Iterator&
1720 operator--() requires bidirectional_range<_Vp>
1724 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1729 operator--(int) requires bidirectional_range<_Vp>
1736 friend constexpr bool
1737 operator==(const _Iterator& __x, const _Iterator& __y)
1738 requires equality_comparable<_Vp_iter>
1739 { return __x._M_current == __y._M_current; }
1741 friend constexpr range_rvalue_reference_t<_Vp>
1742 iter_move(const _Iterator& __i)
1743 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1744 { return ranges::iter_move(__i._M_current); }
1746 friend constexpr void
1747 iter_swap(const _Iterator& __x, const _Iterator& __y)
1748 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1749 requires indirectly_swappable<_Vp_iter>
1750 { ranges::iter_swap(__x._M_current, __y._M_current); }
1756 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1759 __equal(const _Iterator& __i) const
1760 { return __i._M_current == _M_end; }
1763 _Sentinel() = default;
1766 _Sentinel(filter_view* __parent)
1767 : _M_end(ranges::end(__parent->_M_base))
1770 constexpr sentinel_t<_Vp>
1774 friend constexpr bool
1775 operator==(const _Iterator& __x, const _Sentinel& __y)
1776 { return __y.__equal(__x); }
1779 _Vp _M_base = _Vp();
1780 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1781 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1784 filter_view() requires (default_initializable<_Vp>
1785 && default_initializable<_Pred>)
1789 filter_view(_Vp __base, _Pred __pred)
1790 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1794 base() const& requires copy_constructible<_Vp>
1799 { return std::move(_M_base); }
1801 constexpr const _Pred&
1803 { return *_M_pred; }
1808 if (_M_cached_begin._M_has_value())
1809 return {this, _M_cached_begin._M_get(_M_base)};
1811 __glibcxx_assert(_M_pred.has_value());
1812 auto __it = ranges::find_if(ranges::begin(_M_base),
1813 ranges::end(_M_base),
1814 std::ref(*_M_pred));
1815 _M_cached_begin._M_set(_M_base, __it);
1816 return {this, std::move(__it)};
1822 if constexpr (common_range<_Vp>)
1823 return _Iterator{this, ranges::end(_M_base)};
1825 return _Sentinel{this};
1829 template<typename _Range, typename _Pred>
1830 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1836 template<typename _Range, typename _Pred>
1837 concept __can_filter_view
1838 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1839 } // namespace __detail
1841 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1843 template<viewable_range _Range, typename _Pred>
1844 requires __detail::__can_filter_view<_Range, _Pred>
1846 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1848 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1851 using _RangeAdaptor<_Filter>::operator();
1852 static constexpr int _S_arity = 2;
1853 static constexpr bool _S_has_simple_extra_args = true;
1856 inline constexpr _Filter filter;
1857 } // namespace views
1859#if __cpp_lib_ranges >= 202207L // C++ >= 23
1860 template<input_range _Vp, move_constructible _Fp>
1862 template<input_range _Vp, copy_constructible _Fp>
1864 requires view<_Vp> && is_object_v<_Fp>
1865 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1866 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1867 range_reference_t<_Vp>>>
1868 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1871 template<bool _Const>
1872 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1874 template<bool _Const>
1878 template<bool _Const>
1879 requires forward_range<_Base<_Const>>
1880 struct __iter_cat<_Const>
1886 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1887 // 3564. transform_view::iterator<true>::value_type and
1888 // iterator_category should use const F&
1889 using _Base = transform_view::_Base<_Const>;
1890 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1891 range_reference_t<_Base>>;
1892 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1893 // 3798. Rvalue reference and iterator_category
1894 if constexpr (is_reference_v<_Res>)
1897 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1898 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1899 return random_access_iterator_tag{};
1904 return input_iterator_tag{};
1907 using iterator_category = decltype(_S_iter_cat());
1910 template<bool _Const>
1913 template<bool _Const>
1914 struct _Iterator : __iter_cat<_Const>
1917 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1918 using _Base = transform_view::_Base<_Const>;
1923 if constexpr (random_access_range<_Base>)
1924 return random_access_iterator_tag{};
1925 else if constexpr (bidirectional_range<_Base>)
1926 return bidirectional_iterator_tag{};
1927 else if constexpr (forward_range<_Base>)
1928 return forward_iterator_tag{};
1930 return input_iterator_tag{};
1933 using _Base_iter = iterator_t<_Base>;
1935 _Base_iter _M_current = _Base_iter();
1936 _Parent* _M_parent = nullptr;
1939 using iterator_concept = decltype(_S_iter_concept());
1940 // iterator_category defined in __transform_view_iter_cat
1942 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1943 range_reference_t<_Base>>>;
1944 using difference_type = range_difference_t<_Base>;
1946 _Iterator() requires default_initializable<_Base_iter> = default;
1949 _Iterator(_Parent* __parent, _Base_iter __current)
1950 : _M_current(std::move(__current)),
1955 _Iterator(_Iterator<!_Const> __i)
1957 && convertible_to<iterator_t<_Vp>, _Base_iter>
1958 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1961 constexpr const _Base_iter&
1962 base() const & noexcept
1963 { return _M_current; }
1965 constexpr _Base_iter
1967 { return std::move(_M_current); }
1969 constexpr decltype(auto)
1971 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1972 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1974 constexpr _Iterator&
1986 operator++(int) requires forward_range<_Base>
1993 constexpr _Iterator&
1994 operator--() requires bidirectional_range<_Base>
2001 operator--(int) requires bidirectional_range<_Base>
2008 constexpr _Iterator&
2009 operator+=(difference_type __n) requires random_access_range<_Base>
2015 constexpr _Iterator&
2016 operator-=(difference_type __n) requires random_access_range<_Base>
2022 constexpr decltype(auto)
2023 operator[](difference_type __n) const
2024 requires random_access_range<_Base>
2025 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2027 friend constexpr bool
2028 operator==(const _Iterator& __x, const _Iterator& __y)
2029 requires equality_comparable<_Base_iter>
2030 { return __x._M_current == __y._M_current; }
2032 friend constexpr bool
2033 operator<(const _Iterator& __x, const _Iterator& __y)
2034 requires random_access_range<_Base>
2035 { return __x._M_current < __y._M_current; }
2037 friend constexpr bool
2038 operator>(const _Iterator& __x, const _Iterator& __y)
2039 requires random_access_range<_Base>
2040 { return __y < __x; }
2042 friend constexpr bool
2043 operator<=(const _Iterator& __x, const _Iterator& __y)
2044 requires random_access_range<_Base>
2045 { return !(__y < __x); }
2047 friend constexpr bool
2048 operator>=(const _Iterator& __x, const _Iterator& __y)
2049 requires random_access_range<_Base>
2050 { return !(__x < __y); }
2052#ifdef __cpp_lib_three_way_comparison
2053 friend constexpr auto
2054 operator<=>(const _Iterator& __x, const _Iterator& __y)
2055 requires random_access_range<_Base>
2056 && three_way_comparable<_Base_iter>
2057 { return __x._M_current <=> __y._M_current; }
2060 friend constexpr _Iterator
2061 operator+(_Iterator __i, difference_type __n)
2062 requires random_access_range<_Base>
2063 { return {__i._M_parent, __i._M_current + __n}; }
2065 friend constexpr _Iterator
2066 operator+(difference_type __n, _Iterator __i)
2067 requires random_access_range<_Base>
2068 { return {__i._M_parent, __i._M_current + __n}; }
2070 friend constexpr _Iterator
2071 operator-(_Iterator __i, difference_type __n)
2072 requires random_access_range<_Base>
2073 { return {__i._M_parent, __i._M_current - __n}; }
2075 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2076 // 3483. transform_view::iterator's difference is overconstrained
2077 friend constexpr difference_type
2078 operator-(const _Iterator& __x, const _Iterator& __y)
2079 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2080 { return __x._M_current - __y._M_current; }
2082 friend constexpr decltype(auto)
2083 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2085 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2086 return std::move(*__i);
2091 friend _Iterator<!_Const>;
2092 template<bool> friend struct _Sentinel;
2095 template<bool _Const>
2099 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2100 using _Base = transform_view::_Base<_Const>;
2102 template<bool _Const2>
2104 __distance_from(const _Iterator<_Const2>& __i) const
2105 { return _M_end - __i._M_current; }
2107 template<bool _Const2>
2109 __equal(const _Iterator<_Const2>& __i) const
2110 { return __i._M_current == _M_end; }
2112 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2115 _Sentinel() = default;
2118 _Sentinel(sentinel_t<_Base> __end)
2123 _Sentinel(_Sentinel<!_Const> __i)
2125 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2126 : _M_end(std::move(__i._M_end))
2129 constexpr sentinel_t<_Base>
2133 template<bool _Const2>
2134 requires sentinel_for<sentinel_t<_Base>,
2135 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2136 friend constexpr bool
2137 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2138 { return __y.__equal(__x); }
2140 template<bool _Const2,
2141 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2142 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2143 friend constexpr range_difference_t<_Base2>
2144 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2145 { return -__y.__distance_from(__x); }
2147 template<bool _Const2,
2148 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2149 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2150 friend constexpr range_difference_t<_Base2>
2151 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2152 { return __y.__distance_from(__x); }
2154 friend _Sentinel<!_Const>;
2157 _Vp _M_base = _Vp();
2158 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2161 transform_view() requires (default_initializable<_Vp>
2162 && default_initializable<_Fp>)
2166 transform_view(_Vp __base, _Fp __fun)
2167 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2171 base() const& requires copy_constructible<_Vp>
2172 { return _M_base ; }
2176 { return std::move(_M_base); }
2178 constexpr _Iterator<false>
2180 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2182 constexpr _Iterator<true>
2184 requires range<const _Vp>
2185 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2186 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2188 constexpr _Sentinel<false>
2190 { return _Sentinel<false>{ranges::end(_M_base)}; }
2192 constexpr _Iterator<false>
2193 end() requires common_range<_Vp>
2194 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2196 constexpr _Sentinel<true>
2198 requires range<const _Vp>
2199 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2200 { return _Sentinel<true>{ranges::end(_M_base)}; }
2202 constexpr _Iterator<true>
2204 requires common_range<const _Vp>
2205 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2206 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2209 size() requires sized_range<_Vp>
2210 { return ranges::size(_M_base); }
2213 size() const requires sized_range<const _Vp>
2214 { return ranges::size(_M_base); }
2217 template<typename _Range, typename _Fp>
2218 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2224 template<typename _Range, typename _Fp>
2225 concept __can_transform_view
2226 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2227 } // namespace __detail
2229 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2231 template<viewable_range _Range, typename _Fp>
2232 requires __detail::__can_transform_view<_Range, _Fp>
2234 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2236 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2239 using _RangeAdaptor<_Transform>::operator();
2240 static constexpr int _S_arity = 2;
2241 static constexpr bool _S_has_simple_extra_args = true;
2244 inline constexpr _Transform transform;
2245 } // namespace views
2248 class take_view : public view_interface<take_view<_Vp>>
2251 template<bool _Const>
2252 using _CI = counted_iterator<
2253 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2255 template<bool _Const>
2259 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2260 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2263 _Sentinel() = default;
2266 _Sentinel(sentinel_t<_Base> __end)
2271 _Sentinel(_Sentinel<!_Const> __s)
2272 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2273 : _M_end(std::move(__s._M_end))
2276 constexpr sentinel_t<_Base>
2280 friend constexpr bool
2281 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2282 { return __y.count() == 0 || __y.base() == __x._M_end; }
2284 template<bool _OtherConst = !_Const,
2285 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2286 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2287 friend constexpr bool
2288 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2289 { return __y.count() == 0 || __y.base() == __x._M_end; }
2291 friend _Sentinel<!_Const>;
2294 _Vp _M_base = _Vp();
2295 range_difference_t<_Vp> _M_count = 0;
2298 take_view() requires default_initializable<_Vp> = default;
2301 take_view(_Vp __base, range_difference_t<_Vp> __count)
2302 : _M_base(std::move(__base)), _M_count(std::move(__count))
2306 base() const& requires copy_constructible<_Vp>
2311 { return std::move(_M_base); }
2314 begin() requires (!__detail::__simple_view<_Vp>)
2316 if constexpr (sized_range<_Vp>)
2318 if constexpr (random_access_range<_Vp>)
2319 return ranges::begin(_M_base);
2323 return counted_iterator(ranges::begin(_M_base), __sz);
2327 return counted_iterator(ranges::begin(_M_base), _M_count);
2331 begin() const requires range<const _Vp>
2333 if constexpr (sized_range<const _Vp>)
2335 if constexpr (random_access_range<const _Vp>)
2336 return ranges::begin(_M_base);
2340 return counted_iterator(ranges::begin(_M_base), __sz);
2344 return counted_iterator(ranges::begin(_M_base), _M_count);
2348 end() requires (!__detail::__simple_view<_Vp>)
2350 if constexpr (sized_range<_Vp>)
2352 if constexpr (random_access_range<_Vp>)
2353 return ranges::begin(_M_base) + size();
2355 return default_sentinel;
2358 return _Sentinel<false>{ranges::end(_M_base)};
2362 end() const requires range<const _Vp>
2364 if constexpr (sized_range<const _Vp>)
2366 if constexpr (random_access_range<const _Vp>)
2367 return ranges::begin(_M_base) + size();
2369 return default_sentinel;
2372 return _Sentinel<true>{ranges::end(_M_base)};
2376 size() requires sized_range<_Vp>
2378 auto __n = ranges::size(_M_base);
2379 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2383 size() const requires sized_range<const _Vp>
2385 auto __n = ranges::size(_M_base);
2386 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2390 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2391 // 3447. Deduction guides for take_view and drop_view have different
2393 template<typename _Range>
2394 take_view(_Range&&, range_difference_t<_Range>)
2395 -> take_view<views::all_t<_Range>>;
2397 template<typename _Tp>
2398 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2399 = enable_borrowed_range<_Tp>;
2405 template<typename _Range>
2406 inline constexpr bool __is_empty_view = false;
2408 template<typename _Tp>
2409 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2411 template<typename _Range>
2412 inline constexpr bool __is_basic_string_view = false;
2414 template<typename _CharT, typename _Traits>
2415 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2418 using ranges::__detail::__is_subrange;
2420 template<typename _Range>
2421 inline constexpr bool __is_iota_view = false;
2423 template<typename _Winc, typename _Bound>
2424 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2426 template<typename _Range>
2427 inline constexpr bool __is_repeat_view = false;
2429 template<typename _Range>
2431 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2433 template<typename _Range, typename _Dp>
2434 concept __can_take_view
2435 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2436 } // namespace __detail
2438 struct _Take : __adaptor::_RangeAdaptor<_Take>
2440 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2441 requires __detail::__can_take_view<_Range, _Dp>
2443 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2445 using _Tp = remove_cvref_t<_Range>;
2446 if constexpr (__detail::__is_empty_view<_Tp>)
2448 else if constexpr (random_access_range<_Tp>
2450 && (std::__detail::__is_span<_Tp>
2451 || __detail::__is_basic_string_view<_Tp>
2452 || __detail::__is_subrange<_Tp>
2453 || __detail::__is_iota_view<_Tp>))
2455 __n = std::min<_Dp>(ranges::distance(__r), __n);
2456 auto __begin = ranges::begin(__r);
2457 auto __end = __begin + __n;
2458 if constexpr (std::__detail::__is_span<_Tp>)
2459 return span<typename _Tp::element_type>(__begin, __end);
2460 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2461 return _Tp(__begin, __end);
2462 else if constexpr (__detail::__is_subrange<_Tp>)
2463 return subrange<iterator_t<_Tp>>(__begin, __end);
2465 return iota_view(*__begin, *__end);
2467 else if constexpr (__detail::__is_repeat_view<_Tp>)
2468 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2470 return take_view(std::forward<_Range>(__r), __n);
2473 using _RangeAdaptor<_Take>::operator();
2474 static constexpr int _S_arity = 2;
2475 // The count argument of views::take is not always simple -- it can be
2476 // e.g. a move-only class that's implicitly convertible to the difference
2477 // type. But an integer-like count argument is surely simple.
2478 template<typename _Tp>
2479 static constexpr bool _S_has_simple_extra_args
2480 = ranges::__detail::__is_integer_like<_Tp>;
2483 inline constexpr _Take take;
2484 } // namespace views
2486 template<view _Vp, typename _Pred>
2487 requires input_range<_Vp> && is_object_v<_Pred>
2488 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2489 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2491 template<bool _Const>
2495 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2497 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2498 const _Pred* _M_pred = nullptr;
2501 _Sentinel() = default;
2504 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2505 : _M_end(__end), _M_pred(__pred)
2509 _Sentinel(_Sentinel<!_Const> __s)
2510 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2511 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2514 constexpr sentinel_t<_Base>
2515 base() const { return _M_end; }
2517 friend constexpr bool
2518 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2519 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2521 template<bool _OtherConst = !_Const,
2522 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2523 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2524 friend constexpr bool
2525 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2526 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2528 friend _Sentinel<!_Const>;
2531 _Vp _M_base = _Vp();
2532 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2535 take_while_view() requires (default_initializable<_Vp>
2536 && default_initializable<_Pred>)
2540 take_while_view(_Vp __base, _Pred __pred)
2541 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2545 base() const& requires copy_constructible<_Vp>
2550 { return std::move(_M_base); }
2552 constexpr const _Pred&
2554 { return *_M_pred; }
2557 begin() requires (!__detail::__simple_view<_Vp>)
2558 { return ranges::begin(_M_base); }
2561 begin() const requires range<const _Vp>
2562 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2563 { return ranges::begin(_M_base); }
2566 end() requires (!__detail::__simple_view<_Vp>)
2567 { return _Sentinel<false>(ranges::end(_M_base),
2568 std::__addressof(*_M_pred)); }
2571 end() const requires range<const _Vp>
2572 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2573 { return _Sentinel<true>(ranges::end(_M_base),
2574 std::__addressof(*_M_pred)); }
2577 template<typename _Range, typename _Pred>
2578 take_while_view(_Range&&, _Pred)
2579 -> take_while_view<views::all_t<_Range>, _Pred>;
2585 template<typename _Range, typename _Pred>
2586 concept __can_take_while_view
2587 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2588 } // namespace __detail
2590 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2592 template<viewable_range _Range, typename _Pred>
2593 requires __detail::__can_take_while_view<_Range, _Pred>
2595 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2597 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2600 using _RangeAdaptor<_TakeWhile>::operator();
2601 static constexpr int _S_arity = 2;
2602 static constexpr bool _S_has_simple_extra_args = true;
2605 inline constexpr _TakeWhile take_while;
2606 } // namespace views
2609 class drop_view : public view_interface<drop_view<_Vp>>
2612 _Vp _M_base = _Vp();
2613 range_difference_t<_Vp> _M_count = 0;
2615 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2616 // both random_access_range and sized_range. Otherwise, cache its result.
2617 static constexpr bool _S_needs_cached_begin
2618 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2619 [[no_unique_address]]
2620 __detail::__maybe_present_t<_S_needs_cached_begin,
2621 __detail::_CachedPosition<_Vp>>
2625 drop_view() requires default_initializable<_Vp> = default;
2628 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2629 : _M_base(std::move(__base)), _M_count(__count)
2630 { __glibcxx_assert(__count >= 0); }
2633 base() const& requires copy_constructible<_Vp>
2638 { return std::move(_M_base); }
2640 // This overload is disabled for simple views with constant-time begin().
2643 requires (!(__detail::__simple_view<_Vp>
2644 && random_access_range<const _Vp>
2645 && sized_range<const _Vp>))
2647 if constexpr (_S_needs_cached_begin)
2648 if (_M_cached_begin._M_has_value())
2649 return _M_cached_begin._M_get(_M_base);
2651 auto __it = ranges::next(ranges::begin(_M_base),
2652 _M_count, ranges::end(_M_base));
2653 if constexpr (_S_needs_cached_begin)
2654 _M_cached_begin._M_set(_M_base, __it);
2658 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2659 // 3482. drop_view's const begin should additionally require sized_range
2662 requires random_access_range<const _Vp> && sized_range<const _Vp>
2664 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2669 end() requires (!__detail::__simple_view<_Vp>)
2670 { return ranges::end(_M_base); }
2673 end() const requires range<const _Vp>
2674 { return ranges::end(_M_base); }
2677 size() requires sized_range<_Vp>
2679 const auto __s = ranges::size(_M_base);
2680 const auto __c = static_cast<decltype(__s)>(_M_count);
2681 return __s < __c ? 0 : __s - __c;
2685 size() const requires sized_range<const _Vp>
2687 const auto __s = ranges::size(_M_base);
2688 const auto __c = static_cast<decltype(__s)>(_M_count);
2689 return __s < __c ? 0 : __s - __c;
2693 template<typename _Range>
2694 drop_view(_Range&&, range_difference_t<_Range>)
2695 -> drop_view<views::all_t<_Range>>;
2697 template<typename _Tp>
2698 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2699 = enable_borrowed_range<_Tp>;
2705 template<typename _Range>
2707 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2709 template<typename _Range, typename _Dp>
2710 concept __can_drop_view
2711 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2712 } // namespace __detail
2714 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2716 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2717 requires __detail::__can_drop_view<_Range, _Dp>
2719 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2721 using _Tp = remove_cvref_t<_Range>;
2722 if constexpr (__detail::__is_empty_view<_Tp>)
2724 else if constexpr (random_access_range<_Tp>
2726 && (std::__detail::__is_span<_Tp>
2727 || __detail::__is_basic_string_view<_Tp>
2728 || __detail::__is_iota_view<_Tp>
2729 || __detail::__is_subrange<_Tp>))
2731 __n = std::min<_Dp>(ranges::distance(__r), __n);
2732 auto __begin = ranges::begin(__r) + __n;
2733 auto __end = ranges::end(__r);
2734 if constexpr (std::__detail::__is_span<_Tp>)
2735 return span<typename _Tp::element_type>(__begin, __end);
2736 else if constexpr (__detail::__is_subrange<_Tp>)
2738 if constexpr (_Tp::_S_store_size)
2740 using ranges::__detail::__to_unsigned_like;
2741 auto __m = ranges::distance(__r) - __n;
2742 return _Tp(__begin, __end, __to_unsigned_like(__m));
2745 return _Tp(__begin, __end);
2748 return _Tp(__begin, __end);
2750 else if constexpr (__detail::__is_repeat_view<_Tp>)
2751 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2753 return drop_view(std::forward<_Range>(__r), __n);
2756 using _RangeAdaptor<_Drop>::operator();
2757 static constexpr int _S_arity = 2;
2758 template<typename _Tp>
2759 static constexpr bool _S_has_simple_extra_args
2760 = _Take::_S_has_simple_extra_args<_Tp>;
2763 inline constexpr _Drop drop;
2764 } // namespace views
2766 template<view _Vp, typename _Pred>
2767 requires input_range<_Vp> && is_object_v<_Pred>
2768 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2769 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2772 _Vp _M_base = _Vp();
2773 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2774 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2777 drop_while_view() requires (default_initializable<_Vp>
2778 && default_initializable<_Pred>)
2782 drop_while_view(_Vp __base, _Pred __pred)
2783 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2787 base() const& requires copy_constructible<_Vp>
2792 { return std::move(_M_base); }
2794 constexpr const _Pred&
2796 { return *_M_pred; }
2801 if (_M_cached_begin._M_has_value())
2802 return _M_cached_begin._M_get(_M_base);
2804 __glibcxx_assert(_M_pred.has_value());
2805 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2806 ranges::end(_M_base),
2807 std::cref(*_M_pred));
2808 _M_cached_begin._M_set(_M_base, __it);
2814 { return ranges::end(_M_base); }
2817 template<typename _Range, typename _Pred>
2818 drop_while_view(_Range&&, _Pred)
2819 -> drop_while_view<views::all_t<_Range>, _Pred>;
2821 template<typename _Tp, typename _Pred>
2822 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2823 = enable_borrowed_range<_Tp>;
2829 template<typename _Range, typename _Pred>
2830 concept __can_drop_while_view
2831 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2832 } // namespace __detail
2834 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2836 template<viewable_range _Range, typename _Pred>
2837 requires __detail::__can_drop_while_view<_Range, _Pred>
2839 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2841 return drop_while_view(std::forward<_Range>(__r),
2842 std::forward<_Pred>(__p));
2845 using _RangeAdaptor<_DropWhile>::operator();
2846 static constexpr int _S_arity = 2;
2847 static constexpr bool _S_has_simple_extra_args = true;
2850 inline constexpr _DropWhile drop_while;
2851 } // namespace views
2855 template<typename _Tp>
2857 __as_lvalue(_Tp&& __t)
2858 { return static_cast<_Tp&>(__t); }
2859 } // namespace __detail
2861 template<input_range _Vp>
2862 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2863 class join_view : public view_interface<join_view<_Vp>>
2866 using _InnerRange = range_reference_t<_Vp>;
2868 template<bool _Const>
2869 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2871 template<bool _Const>
2872 using _Outer_iter = iterator_t<_Base<_Const>>;
2874 template<bool _Const>
2875 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2877 template<bool _Const>
2878 static constexpr bool _S_ref_is_glvalue
2879 = is_reference_v<range_reference_t<_Base<_Const>>>;
2881 template<bool _Const>
2885 template<bool _Const>
2886 requires _S_ref_is_glvalue<_Const>
2887 && forward_range<_Base<_Const>>
2888 && forward_range<range_reference_t<_Base<_Const>>>
2889 struct __iter_cat<_Const>
2892 static constexpr auto
2895 using _Outer_iter = join_view::_Outer_iter<_Const>;
2896 using _Inner_iter = join_view::_Inner_iter<_Const>;
2897 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2898 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2899 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2900 && derived_from<_InnerCat, bidirectional_iterator_tag>
2901 && common_range<range_reference_t<_Base<_Const>>>)
2902 return bidirectional_iterator_tag{};
2903 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2904 && derived_from<_InnerCat, forward_iterator_tag>)
2905 return forward_iterator_tag{};
2907 return input_iterator_tag{};
2910 using iterator_category = decltype(_S_iter_cat());
2913 template<bool _Const>
2916 template<bool _Const>
2917 struct _Iterator : __iter_cat<_Const>
2920 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2921 using _Base = join_view::_Base<_Const>;
2925 static constexpr bool _S_ref_is_glvalue
2926 = join_view::_S_ref_is_glvalue<_Const>;
2931 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2932 if constexpr (_S_ref_is_glvalue)
2935 return _M_parent->_M_inner._M_emplace_deref(__x);
2938 _Outer_iter& __outer = _M_get_outer();
2939 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2941 auto&& __inner = __update_inner(__outer);
2942 _M_inner = ranges::begin(__inner);
2943 if (_M_inner != ranges::end(__inner))
2947 if constexpr (_S_ref_is_glvalue)
2951 static constexpr auto
2954 if constexpr (_S_ref_is_glvalue
2955 && bidirectional_range<_Base>
2956 && bidirectional_range<range_reference_t<_Base>>
2957 && common_range<range_reference_t<_Base>>)
2958 return bidirectional_iterator_tag{};
2959 else if constexpr (_S_ref_is_glvalue
2960 && forward_range<_Base>
2961 && forward_range<range_reference_t<_Base>>)
2962 return forward_iterator_tag{};
2964 return input_iterator_tag{};
2967 using _Outer_iter = join_view::_Outer_iter<_Const>;
2968 using _Inner_iter = join_view::_Inner_iter<_Const>;
2970 constexpr _Outer_iter&
2973 if constexpr (forward_range<_Base>)
2976 return *_M_parent->_M_outer;
2979 constexpr const _Outer_iter&
2980 _M_get_outer() const
2982 if constexpr (forward_range<_Base>)
2985 return *_M_parent->_M_outer;
2989 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
2990 : _M_outer(std::move(__outer)), _M_parent(__parent)
2994 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
2995 : _M_parent(__parent)
2998 [[no_unique_address]]
2999 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
3000 optional<_Inner_iter> _M_inner;
3001 _Parent* _M_parent = nullptr;
3004 using iterator_concept = decltype(_S_iter_concept());
3005 // iterator_category defined in __join_view_iter_cat
3006 using value_type = range_value_t<range_reference_t<_Base>>;
3007 using difference_type
3008 = common_type_t<range_difference_t<_Base>,
3009 range_difference_t<range_reference_t<_Base>>>;
3011 _Iterator() = default;
3014 _Iterator(_Iterator<!_Const> __i)
3016 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3017 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3018 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3019 _M_parent(__i._M_parent)
3022 constexpr decltype(auto)
3024 { return **_M_inner; }
3026 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3027 // 3500. join_view::iterator::operator->() is bogus
3028 constexpr _Inner_iter
3030 requires __detail::__has_arrow<_Inner_iter>
3031 && copyable<_Inner_iter>
3032 { return *_M_inner; }
3034 constexpr _Iterator&
3037 auto&& __inner_range = [this] () -> auto&& {
3038 if constexpr (_S_ref_is_glvalue)
3039 return *_M_get_outer();
3041 return *_M_parent->_M_inner;
3043 if (++*_M_inner == ranges::end(__inner_range))
3057 requires _S_ref_is_glvalue && forward_range<_Base>
3058 && forward_range<range_reference_t<_Base>>
3065 constexpr _Iterator&
3067 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3068 && bidirectional_range<range_reference_t<_Base>>
3069 && common_range<range_reference_t<_Base>>
3071 if (_M_outer == ranges::end(_M_parent->_M_base))
3072 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3073 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3074 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3081 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3082 && bidirectional_range<range_reference_t<_Base>>
3083 && common_range<range_reference_t<_Base>>
3090 friend constexpr bool
3091 operator==(const _Iterator& __x, const _Iterator& __y)
3092 requires _S_ref_is_glvalue
3093 && forward_range<_Base>
3094 && equality_comparable<_Inner_iter>
3096 return (__x._M_outer == __y._M_outer
3097 && __x._M_inner == __y._M_inner);
3100 friend constexpr decltype(auto)
3101 iter_move(const _Iterator& __i)
3102 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
3103 { return ranges::iter_move(*__i._M_inner); }
3105 friend constexpr void
3106 iter_swap(const _Iterator& __x, const _Iterator& __y)
3107 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3108 requires indirectly_swappable<_Inner_iter>
3109 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3111 friend _Iterator<!_Const>;
3112 template<bool> friend struct _Sentinel;
3115 template<bool _Const>
3119 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3120 using _Base = join_view::_Base<_Const>;
3122 template<bool _Const2>
3124 __equal(const _Iterator<_Const2>& __i) const
3125 { return __i._M_get_outer() == _M_end; }
3127 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3130 _Sentinel() = default;
3133 _Sentinel(_Parent* __parent)
3134 : _M_end(ranges::end(__parent->_M_base))
3138 _Sentinel(_Sentinel<!_Const> __s)
3139 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3140 : _M_end(std::move(__s._M_end))
3143 template<bool _Const2>
3144 requires sentinel_for<sentinel_t<_Base>,
3145 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3146 friend constexpr bool
3147 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3148 { return __y.__equal(__x); }
3150 friend _Sentinel<!_Const>;
3153 _Vp _M_base = _Vp();
3154 [[no_unique_address]]
3155 __detail::__maybe_present_t<!forward_range<_Vp>,
3156 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3157 [[no_unique_address]]
3158 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3161 join_view() requires default_initializable<_Vp> = default;
3164 join_view(_Vp __base)
3165 : _M_base(std::move(__base))
3169 base() const& requires copy_constructible<_Vp>
3174 { return std::move(_M_base); }
3179 if constexpr (forward_range<_Vp>)
3181 constexpr bool __use_const
3182 = (__detail::__simple_view<_Vp>
3183 && is_reference_v<range_reference_t<_Vp>>);
3184 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3188 _M_outer = ranges::begin(_M_base);
3189 return _Iterator<false>{this};
3195 requires forward_range<const _Vp>
3196 && is_reference_v<range_reference_t<const _Vp>>
3197 && input_range<range_reference_t<const _Vp>>
3199 return _Iterator<true>{this, ranges::begin(_M_base)};
3205 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3206 && forward_range<_InnerRange>
3207 && common_range<_Vp> && common_range<_InnerRange>)
3208 return _Iterator<__detail::__simple_view<_Vp>>{this,
3209 ranges::end(_M_base)};
3211 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3216 requires forward_range<const _Vp>
3217 && is_reference_v<range_reference_t<const _Vp>>
3218 && input_range<range_reference_t<const _Vp>>
3220 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3221 && forward_range<range_reference_t<const _Vp>>
3222 && common_range<const _Vp>
3223 && common_range<range_reference_t<const _Vp>>)
3224 return _Iterator<true>{this, ranges::end(_M_base)};
3226 return _Sentinel<true>{this};
3230 template<typename _Range>
3231 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3237 template<typename _Range>
3238 concept __can_join_view
3239 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3240 } // namespace __detail
3242 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3244 template<viewable_range _Range>
3245 requires __detail::__can_join_view<_Range>
3247 operator() [[nodiscard]] (_Range&& __r) const
3249 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3250 // 3474. Nesting join_views is broken because of CTAD
3251 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3254 static constexpr bool _S_has_simple_call_op = true;
3257 inline constexpr _Join join;
3258 } // namespace views
3263 struct __require_constant;
3265 template<typename _Range>
3266 concept __tiny_range = sized_range<_Range>
3268 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3269 && (remove_reference_t<_Range>::size() <= 1);
3271 template<typename _Base>
3272 struct __lazy_split_view_outer_iter_cat
3275 template<forward_range _Base>
3276 struct __lazy_split_view_outer_iter_cat<_Base>
3277 { using iterator_category = input_iterator_tag; };
3279 template<typename _Base>
3280 struct __lazy_split_view_inner_iter_cat
3283 template<forward_range _Base>
3284 struct __lazy_split_view_inner_iter_cat<_Base>
3287 static constexpr auto
3290 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3291 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3292 return forward_iterator_tag{};
3297 using iterator_category = decltype(_S_iter_cat());
3301 template<input_range _Vp, forward_range _Pattern>
3302 requires view<_Vp> && view<_Pattern>
3303 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3305 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3306 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3309 template<bool _Const>
3310 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3312 template<bool _Const>
3315 template<bool _Const>
3317 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3320 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3321 using _Base = lazy_split_view::_Base<_Const>;
3325 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3327 // [range.lazy.split.outer] p1
3328 // Many of the following specifications refer to the notional member
3329 // current of outer-iterator. current is equivalent to current_ if
3330 // V models forward_range, and parent_->current_ otherwise.
3332 __current() noexcept
3334 if constexpr (forward_range<_Vp>)
3337 return *_M_parent->_M_current;
3341 __current() const noexcept
3343 if constexpr (forward_range<_Vp>)
3346 return *_M_parent->_M_current;
3349 _Parent* _M_parent = nullptr;
3351 [[no_unique_address]]
3352 __detail::__maybe_present_t<forward_range<_Vp>,
3353 iterator_t<_Base>> _M_current;
3354 bool _M_trailing_empty = false;
3357 using iterator_concept = __conditional_t<forward_range<_Base>,
3358 forward_iterator_tag,
3359 input_iterator_tag>;
3360 // iterator_category defined in __lazy_split_view_outer_iter_cat
3361 using difference_type = range_difference_t<_Base>;
3363 struct value_type : view_interface<value_type>
3366 _OuterIter _M_i = _OuterIter();
3368 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3369 // 4013. lazy_split_view::outer-iterator::value_type should not
3370 // provide default constructor
3372 value_type(_OuterIter __i)
3373 : _M_i(std::move(__i))
3379 constexpr _InnerIter<_Const>
3381 { return _InnerIter<_Const>{_M_i}; }
3383 constexpr default_sentinel_t
3384 end() const noexcept
3385 { return default_sentinel; }
3388 _OuterIter() = default;
3391 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3392 : _M_parent(__parent)
3396 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3397 requires forward_range<_Base>
3398 : _M_parent(__parent),
3399 _M_current(std::move(__current))
3403 _OuterIter(_OuterIter<!_Const> __i)
3405 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3406 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3407 _M_trailing_empty(__i._M_trailing_empty)
3410 constexpr value_type
3412 { return value_type{*this}; }
3414 constexpr _OuterIter&
3417 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3418 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3419 const auto __end = ranges::end(_M_parent->_M_base);
3420 if (__current() == __end)
3422 _M_trailing_empty = false;
3425 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3426 if (__pbegin == __pend)
3428 else if constexpr (__detail::__tiny_range<_Pattern>)
3430 __current() = ranges::find(std::move(__current()), __end,
3432 if (__current() != __end)
3435 if (__current() == __end)
3436 _M_trailing_empty = true;
3443 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3447 if (__current() == __end)
3448 _M_trailing_empty = true;
3451 } while (++__current() != __end);
3455 constexpr decltype(auto)
3458 if constexpr (forward_range<_Base>)
3468 friend constexpr bool
3469 operator==(const _OuterIter& __x, const _OuterIter& __y)
3470 requires forward_range<_Base>
3472 return __x._M_current == __y._M_current
3473 && __x._M_trailing_empty == __y._M_trailing_empty;
3476 friend constexpr bool
3477 operator==(const _OuterIter& __x, default_sentinel_t)
3478 { return __x.__at_end(); };
3480 friend _OuterIter<!_Const>;
3481 friend _InnerIter<_Const>;
3484 template<bool _Const>
3486 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3489 using _Base = lazy_split_view::_Base<_Const>;
3494 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3495 auto __end = ranges::end(_M_i._M_parent->_M_base);
3496 if constexpr (__detail::__tiny_range<_Pattern>)
3498 const auto& __cur = _M_i_current();
3501 if (__pcur == __pend)
3502 return _M_incremented;
3503 return *__cur == *__pcur;
3507 auto __cur = _M_i_current();
3510 if (__pcur == __pend)
3511 return _M_incremented;
3514 if (*__cur != *__pcur)
3516 if (++__pcur == __pend)
3518 } while (++__cur != __end);
3524 _M_i_current() noexcept
3525 { return _M_i.__current(); }
3528 _M_i_current() const noexcept
3529 { return _M_i.__current(); }
3531 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3532 bool _M_incremented = false;
3535 using iterator_concept
3536 = typename _OuterIter<_Const>::iterator_concept;
3537 // iterator_category defined in __lazy_split_view_inner_iter_cat
3538 using value_type = range_value_t<_Base>;
3539 using difference_type = range_difference_t<_Base>;
3541 _InnerIter() = default;
3544 _InnerIter(_OuterIter<_Const> __i)
3545 : _M_i(std::move(__i))
3548 constexpr const iterator_t<_Base>&
3549 base() const& noexcept
3550 { return _M_i_current(); }
3552 constexpr iterator_t<_Base>
3553 base() && requires forward_range<_Vp>
3554 { return std::move(_M_i_current()); }
3556 constexpr decltype(auto)
3558 { return *_M_i_current(); }
3560 constexpr _InnerIter&
3563 _M_incremented = true;
3564 if constexpr (!forward_range<_Base>)
3565 if constexpr (_Pattern::size() == 0)
3571 constexpr decltype(auto)
3574 if constexpr (forward_range<_Base>)
3584 friend constexpr bool
3585 operator==(const _InnerIter& __x, const _InnerIter& __y)
3586 requires forward_range<_Base>
3587 { return __x._M_i == __y._M_i; }
3589 friend constexpr bool
3590 operator==(const _InnerIter& __x, default_sentinel_t)
3591 { return __x.__at_end(); }
3593 friend constexpr decltype(auto)
3594 iter_move(const _InnerIter& __i)
3595 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3596 { return ranges::iter_move(__i._M_i_current()); }
3598 friend constexpr void
3599 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3600 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3601 __y._M_i_current())))
3602 requires indirectly_swappable<iterator_t<_Base>>
3603 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3606 _Vp _M_base = _Vp();
3607 _Pattern _M_pattern = _Pattern();
3608 [[no_unique_address]]
3609 __detail::__maybe_present_t<!forward_range<_Vp>,
3610 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3614 lazy_split_view() requires (default_initializable<_Vp>
3615 && default_initializable<_Pattern>)
3619 lazy_split_view(_Vp __base, _Pattern __pattern)
3620 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3623 template<input_range _Range>
3624 requires constructible_from<_Vp, views::all_t<_Range>>
3625 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3627 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3628 : _M_base(views::all(std::forward<_Range>(__r))),
3629 _M_pattern(views::single(std::move(__e)))
3633 base() const& requires copy_constructible<_Vp>
3638 { return std::move(_M_base); }
3643 if constexpr (forward_range<_Vp>)
3645 constexpr bool __simple
3646 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3647 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3651 _M_current = ranges::begin(_M_base);
3652 return _OuterIter<false>{this};
3657 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3659 return _OuterIter<true>{this, ranges::begin(_M_base)};
3663 end() requires forward_range<_Vp> && common_range<_Vp>
3665 constexpr bool __simple
3666 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3667 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3673 if constexpr (forward_range<_Vp>
3674 && forward_range<const _Vp>
3675 && common_range<const _Vp>)
3676 return _OuterIter<true>{this, ranges::end(_M_base)};
3678 return default_sentinel;
3682 template<typename _Range, typename _Pattern>
3683 lazy_split_view(_Range&&, _Pattern&&)
3684 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3686 template<input_range _Range>
3687 lazy_split_view(_Range&&, range_value_t<_Range>)
3688 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3694 template<typename _Range, typename _Pattern>
3695 concept __can_lazy_split_view
3696 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3697 } // namespace __detail
3699 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3701 template<viewable_range _Range, typename _Pattern>
3702 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3704 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3706 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3709 using _RangeAdaptor<_LazySplit>::operator();
3710 static constexpr int _S_arity = 2;
3711 // The pattern argument of views::lazy_split is not always simple -- it can be
3712 // a non-view range, the value category of which affects whether the call
3713 // is well-formed. But a scalar or a view pattern argument is surely
3715 template<typename _Pattern>
3716 static constexpr bool _S_has_simple_extra_args
3717 = is_scalar_v<_Pattern> || (view<_Pattern>
3718 && copy_constructible<_Pattern>);
3721 inline constexpr _LazySplit lazy_split;
3722 } // namespace views
3724 template<forward_range _Vp, forward_range _Pattern>
3725 requires view<_Vp> && view<_Pattern>
3726 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3728 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3731 _Vp _M_base = _Vp();
3732 _Pattern _M_pattern = _Pattern();
3733 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3739 split_view() requires (default_initializable<_Vp>
3740 && default_initializable<_Pattern>)
3744 split_view(_Vp __base, _Pattern __pattern)
3745 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3748 template<forward_range _Range>
3749 requires constructible_from<_Vp, views::all_t<_Range>>
3750 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3752 split_view(_Range&& __r, range_value_t<_Range> __e)
3753 : _M_base(views::all(std::forward<_Range>(__r))),
3754 _M_pattern(views::single(std::move(__e)))
3758 base() const& requires copy_constructible<_Vp>
3763 { return std::move(_M_base); }
3768 if (!_M_cached_begin)
3769 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3770 return {this, ranges::begin(_M_base), *_M_cached_begin};
3776 if constexpr (common_range<_Vp>)
3777 return _Iterator{this, ranges::end(_M_base), {}};
3779 return _Sentinel{this};
3782 constexpr subrange<iterator_t<_Vp>>
3783 _M_find_next(iterator_t<_Vp> __it)
3785 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3786 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3798 split_view* _M_parent = nullptr;
3799 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3800 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3801 bool _M_trailing_empty = false;
3803 friend struct _Sentinel;
3806 using iterator_concept = forward_iterator_tag;
3807 using iterator_category = input_iterator_tag;
3808 using value_type = subrange<iterator_t<_Vp>>;
3809 using difference_type = range_difference_t<_Vp>;
3811 _Iterator() = default;
3814 _Iterator(split_view* __parent,
3815 iterator_t<_Vp> __current,
3816 subrange<iterator_t<_Vp>> __next)
3817 : _M_parent(__parent),
3818 _M_cur(std::move(__current)),
3819 _M_next(std::move(__next))
3822 constexpr iterator_t<_Vp>
3826 constexpr value_type
3828 { return {_M_cur, _M_next.begin()}; }
3830 constexpr _Iterator&
3833 _M_cur = _M_next.begin();
3834 if (_M_cur != ranges::end(_M_parent->_M_base))
3836 _M_cur = _M_next.end();
3837 if (_M_cur == ranges::end(_M_parent->_M_base))
3839 _M_trailing_empty = true;
3840 _M_next = {_M_cur, _M_cur};
3843 _M_next = _M_parent->_M_find_next(_M_cur);
3846 _M_trailing_empty = false;
3858 friend constexpr bool
3859 operator==(const _Iterator& __x, const _Iterator& __y)
3861 return __x._M_cur == __y._M_cur
3862 && __x._M_trailing_empty == __y._M_trailing_empty;
3869 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3872 _M_equal(const _Iterator& __x) const
3873 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3876 _Sentinel() = default;
3879 _Sentinel(split_view* __parent)
3880 : _M_end(ranges::end(__parent->_M_base))
3883 friend constexpr bool
3884 operator==(const _Iterator& __x, const _Sentinel& __y)
3885 { return __y._M_equal(__x); }
3889 template<typename _Range, typename _Pattern>
3890 split_view(_Range&&, _Pattern&&)
3891 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3893 template<forward_range _Range>
3894 split_view(_Range&&, range_value_t<_Range>)
3895 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3901 template<typename _Range, typename _Pattern>
3902 concept __can_split_view
3903 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3904 } // namespace __detail
3906 struct _Split : __adaptor::_RangeAdaptor<_Split>
3908 template<viewable_range _Range, typename _Pattern>
3909 requires __detail::__can_split_view<_Range, _Pattern>
3911 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3913 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3916 using _RangeAdaptor<_Split>::operator();
3917 static constexpr int _S_arity = 2;
3918 template<typename _Pattern>
3919 static constexpr bool _S_has_simple_extra_args
3920 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3923 inline constexpr _Split split;
3924 } // namespace views
3930 template<input_or_output_iterator _Iter>
3932 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3934 if constexpr (contiguous_iterator<_Iter>)
3935 return span(std::__to_address(__i), __n);
3936 else if constexpr (random_access_iterator<_Iter>)
3937 return subrange(__i, __i + __n);
3939 return subrange(counted_iterator(std::move(__i), __n),
3944 inline constexpr _Counted counted{};
3945 } // namespace views
3948 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3949 class common_view : public view_interface<common_view<_Vp>>
3952 _Vp _M_base = _Vp();
3955 common_view() requires default_initializable<_Vp> = default;
3958 common_view(_Vp __r)
3959 : _M_base(std::move(__r))
3963 base() const& requires copy_constructible<_Vp>
3968 { return std::move(_M_base); }
3970 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3971 // 4012. common_view::begin/end are missing the simple-view check
3973 begin() requires (!__detail::__simple_view<_Vp>)
3975 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3976 return ranges::begin(_M_base);
3978 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3979 (ranges::begin(_M_base));
3983 begin() const requires range<const _Vp>
3985 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
3986 return ranges::begin(_M_base);
3988 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
3989 (ranges::begin(_M_base));
3993 end() requires (!__detail::__simple_view<_Vp>)
3995 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3996 return ranges::begin(_M_base) + ranges::size(_M_base);
3998 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
3999 (ranges::end(_M_base));
4003 end() const requires range<const _Vp>
4005 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4006 return ranges::begin(_M_base) + ranges::size(_M_base);
4008 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4009 (ranges::end(_M_base));
4013 size() requires sized_range<_Vp>
4014 { return ranges::size(_M_base); }
4017 size() const requires sized_range<const _Vp>
4018 { return ranges::size(_M_base); }
4021 template<typename _Range>
4022 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4024 template<typename _Tp>
4025 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4026 = enable_borrowed_range<_Tp>;
4032 template<typename _Range>
4033 concept __already_common = common_range<_Range>
4034 && requires { views::all(std::declval<_Range>()); };
4036 template<typename _Range>
4037 concept __can_common_view
4038 = requires { common_view{std::declval<_Range>()}; };
4039 } // namespace __detail
4041 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4043 template<viewable_range _Range>
4044 requires __detail::__already_common<_Range>
4045 || __detail::__can_common_view<_Range>
4047 operator() [[nodiscard]] (_Range&& __r) const
4049 if constexpr (__detail::__already_common<_Range>)
4050 return views::all(std::forward<_Range>(__r));
4052 return common_view{std::forward<_Range>(__r)};
4055 static constexpr bool _S_has_simple_call_op = true;
4058 inline constexpr _Common common;
4059 } // namespace views
4062 requires bidirectional_range<_Vp>
4063 class reverse_view : public view_interface<reverse_view<_Vp>>
4066 static constexpr bool _S_needs_cached_begin
4067 = !common_range<_Vp> && !(random_access_range<_Vp>
4068 && sized_sentinel_for<sentinel_t<_Vp>,
4071 _Vp _M_base = _Vp();
4072 [[no_unique_address]]
4073 __detail::__maybe_present_t<_S_needs_cached_begin,
4074 __detail::_CachedPosition<_Vp>>
4078 reverse_view() requires default_initializable<_Vp> = default;
4081 reverse_view(_Vp __r)
4082 : _M_base(std::move(__r))
4086 base() const& requires copy_constructible<_Vp>
4091 { return std::move(_M_base); }
4093 constexpr reverse_iterator<iterator_t<_Vp>>
4096 if constexpr (_S_needs_cached_begin)
4097 if (_M_cached_begin._M_has_value())
4098 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4100 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4101 if constexpr (_S_needs_cached_begin)
4102 _M_cached_begin._M_set(_M_base, __it);
4103 return std::make_reverse_iterator(std::move(__it));
4107 begin() requires common_range<_Vp>
4108 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4111 begin() const requires common_range<const _Vp>
4112 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4114 constexpr reverse_iterator<iterator_t<_Vp>>
4116 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4119 end() const requires common_range<const _Vp>
4120 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4123 size() requires sized_range<_Vp>
4124 { return ranges::size(_M_base); }
4127 size() const requires sized_range<const _Vp>
4128 { return ranges::size(_M_base); }
4131 template<typename _Range>
4132 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4134 template<typename _Tp>
4135 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4136 = enable_borrowed_range<_Tp>;
4143 inline constexpr bool __is_reversible_subrange = false;
4145 template<typename _Iter, subrange_kind _Kind>
4146 inline constexpr bool
4147 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4148 reverse_iterator<_Iter>,
4152 inline constexpr bool __is_reverse_view = false;
4154 template<typename _Vp>
4155 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4157 template<typename _Range>
4158 concept __can_reverse_view
4159 = requires { reverse_view{std::declval<_Range>()}; };
4160 } // namespace __detail
4162 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4164 template<viewable_range _Range>
4165 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4166 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4167 || __detail::__can_reverse_view<_Range>
4169 operator() [[nodiscard]] (_Range&& __r) const
4171 using _Tp = remove_cvref_t<_Range>;
4172 if constexpr (__detail::__is_reverse_view<_Tp>)
4173 return std::forward<_Range>(__r).base();
4174 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4176 using _Iter = decltype(ranges::begin(__r).base());
4177 if constexpr (sized_range<_Tp>)
4178 return subrange<_Iter, _Iter, subrange_kind::sized>
4179 {__r.end().base(), __r.begin().base(), __r.size()};
4181 return subrange<_Iter, _Iter, subrange_kind::unsized>
4182 {__r.end().base(), __r.begin().base()};
4185 return reverse_view{std::forward<_Range>(__r)};
4188 static constexpr bool _S_has_simple_call_op = true;
4191 inline constexpr _Reverse reverse;
4192 } // namespace views
4196#if __cpp_lib_tuple_like // >= C++23
4197 template<typename _Tp, size_t _Nm>
4198 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4200 template<typename _Tp, size_t _Nm>
4201 concept __has_tuple_element = requires(_Tp __t)
4203 typename tuple_size<_Tp>::type;
4204 requires _Nm < tuple_size_v<_Tp>;
4205 typename tuple_element_t<_Nm, _Tp>;
4206 { std::get<_Nm>(__t) }
4207 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4211 template<typename _Tp, size_t _Nm>
4212 concept __returnable_element
4213 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4216 template<input_range _Vp, size_t _Nm>
4218 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4219 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4221 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4222 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4225 elements_view() requires default_initializable<_Vp> = default;
4228 elements_view(_Vp __base)
4229 : _M_base(std::move(__base))
4233 base() const& requires copy_constructible<_Vp>
4238 { return std::move(_M_base); }
4241 begin() requires (!__detail::__simple_view<_Vp>)
4242 { return _Iterator<false>(ranges::begin(_M_base)); }
4245 begin() const requires range<const _Vp>
4246 { return _Iterator<true>(ranges::begin(_M_base)); }
4249 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4250 { return _Sentinel<false>{ranges::end(_M_base)}; }
4253 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4254 { return _Iterator<false>{ranges::end(_M_base)}; }
4257 end() const requires range<const _Vp>
4258 { return _Sentinel<true>{ranges::end(_M_base)}; }
4261 end() const requires common_range<const _Vp>
4262 { return _Iterator<true>{ranges::end(_M_base)}; }
4265 size() requires sized_range<_Vp>
4266 { return ranges::size(_M_base); }
4269 size() const requires sized_range<const _Vp>
4270 { return ranges::size(_M_base); }
4273 template<bool _Const>
4274 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4276 template<bool _Const>
4280 template<bool _Const>
4281 requires forward_range<_Base<_Const>>
4282 struct __iter_cat<_Const>
4285 static auto _S_iter_cat()
4287 using _Base = elements_view::_Base<_Const>;
4288 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4289 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4290 if constexpr (!is_lvalue_reference_v<_Res>)
4291 return input_iterator_tag{};
4292 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4293 return random_access_iterator_tag{};
4298 using iterator_category = decltype(_S_iter_cat());
4301 template<bool _Const>
4304 template<bool _Const>
4305 struct _Iterator : __iter_cat<_Const>
4308 using _Base = elements_view::_Base<_Const>;
4310 iterator_t<_Base> _M_current = iterator_t<_Base>();
4312 static constexpr decltype(auto)
4313 _S_get_element(const iterator_t<_Base>& __i)
4315 if constexpr (is_reference_v<range_reference_t<_Base>>)
4316 return std::get<_Nm>(*__i);
4319 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4320 return static_cast<_Et>(std::get<_Nm>(*__i));
4327 if constexpr (random_access_range<_Base>)
4328 return random_access_iterator_tag{};
4329 else if constexpr (bidirectional_range<_Base>)
4330 return bidirectional_iterator_tag{};
4331 else if constexpr (forward_range<_Base>)
4332 return forward_iterator_tag{};
4334 return input_iterator_tag{};
4337 friend _Iterator<!_Const>;
4340 using iterator_concept = decltype(_S_iter_concept());
4341 // iterator_category defined in elements_view::__iter_cat
4343 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4344 using difference_type = range_difference_t<_Base>;
4346 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4349 _Iterator(iterator_t<_Base> __current)
4350 : _M_current(std::move(__current))
4354 _Iterator(_Iterator<!_Const> __i)
4355 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4356 : _M_current(std::move(__i._M_current))
4359 constexpr const iterator_t<_Base>&
4360 base() const& noexcept
4361 { return _M_current; }
4363 constexpr iterator_t<_Base>
4365 { return std::move(_M_current); }
4367 constexpr decltype(auto)
4369 { return _S_get_element(_M_current); }
4371 constexpr _Iterator&
4383 operator++(int) requires forward_range<_Base>
4390 constexpr _Iterator&
4391 operator--() requires bidirectional_range<_Base>
4398 operator--(int) requires bidirectional_range<_Base>
4405 constexpr _Iterator&
4406 operator+=(difference_type __n)
4407 requires random_access_range<_Base>
4413 constexpr _Iterator&
4414 operator-=(difference_type __n)
4415 requires random_access_range<_Base>
4421 constexpr decltype(auto)
4422 operator[](difference_type __n) const
4423 requires random_access_range<_Base>
4424 { return _S_get_element(_M_current + __n); }
4426 friend constexpr bool
4427 operator==(const _Iterator& __x, const _Iterator& __y)
4428 requires equality_comparable<iterator_t<_Base>>
4429 { return __x._M_current == __y._M_current; }
4431 friend constexpr bool
4432 operator<(const _Iterator& __x, const _Iterator& __y)
4433 requires random_access_range<_Base>
4434 { return __x._M_current < __y._M_current; }
4436 friend constexpr bool
4437 operator>(const _Iterator& __x, const _Iterator& __y)
4438 requires random_access_range<_Base>
4439 { return __y._M_current < __x._M_current; }
4441 friend constexpr bool
4442 operator<=(const _Iterator& __x, const _Iterator& __y)
4443 requires random_access_range<_Base>
4444 { return !(__y._M_current > __x._M_current); }
4446 friend constexpr bool
4447 operator>=(const _Iterator& __x, const _Iterator& __y)
4448 requires random_access_range<_Base>
4449 { return !(__x._M_current > __y._M_current); }
4451#ifdef __cpp_lib_three_way_comparison
4452 friend constexpr auto
4453 operator<=>(const _Iterator& __x, const _Iterator& __y)
4454 requires random_access_range<_Base>
4455 && three_way_comparable<iterator_t<_Base>>
4456 { return __x._M_current <=> __y._M_current; }
4459 friend constexpr _Iterator
4460 operator+(const _Iterator& __x, difference_type __y)
4461 requires random_access_range<_Base>
4462 { return _Iterator{__x} += __y; }
4464 friend constexpr _Iterator
4465 operator+(difference_type __x, const _Iterator& __y)
4466 requires random_access_range<_Base>
4467 { return __y + __x; }
4469 friend constexpr _Iterator
4470 operator-(const _Iterator& __x, difference_type __y)
4471 requires random_access_range<_Base>
4472 { return _Iterator{__x} -= __y; }
4474 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4475 // 3483. transform_view::iterator's difference is overconstrained
4476 friend constexpr difference_type
4477 operator-(const _Iterator& __x, const _Iterator& __y)
4478 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4479 { return __x._M_current - __y._M_current; }
4481 template <bool> friend struct _Sentinel;
4484 template<bool _Const>
4488 template<bool _Const2>
4490 _M_equal(const _Iterator<_Const2>& __x) const
4491 { return __x._M_current == _M_end; }
4493 template<bool _Const2>
4495 _M_distance_from(const _Iterator<_Const2>& __i) const
4496 { return _M_end - __i._M_current; }
4498 using _Base = elements_view::_Base<_Const>;
4499 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4502 _Sentinel() = default;
4505 _Sentinel(sentinel_t<_Base> __end)
4506 : _M_end(std::move(__end))
4510 _Sentinel(_Sentinel<!_Const> __other)
4512 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4513 : _M_end(std::move(__other._M_end))
4516 constexpr sentinel_t<_Base>
4520 template<bool _Const2>
4521 requires sentinel_for<sentinel_t<_Base>,
4522 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4523 friend constexpr bool
4524 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4525 { return __y._M_equal(__x); }
4527 template<bool _Const2,
4528 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4529 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4530 friend constexpr range_difference_t<_Base2>
4531 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4532 { return -__y._M_distance_from(__x); }
4534 template<bool _Const2,
4535 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4536 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4537 friend constexpr range_difference_t<_Base2>
4538 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4539 { return __x._M_distance_from(__y); }
4541 friend _Sentinel<!_Const>;
4544 _Vp _M_base = _Vp();
4547 template<typename _Tp, size_t _Nm>
4548 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4549 = enable_borrowed_range<_Tp>;
4551 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4552 // 3563. keys_view example is broken
4553 template<typename _Range>
4554 using keys_view = elements_view<_Range, 0>;
4556 template<typename _Range>
4557 using values_view = elements_view<_Range, 1>;
4563 template<size_t _Nm, typename _Range>
4564 concept __can_elements_view
4565 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4566 } // namespace __detail
4568 template<size_t _Nm>
4569 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4571 template<viewable_range _Range>
4572 requires __detail::__can_elements_view<_Nm, _Range>
4574 operator() [[nodiscard]] (_Range&& __r) const
4576 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4579 static constexpr bool _S_has_simple_call_op = true;
4582 template<size_t _Nm>
4583 inline constexpr _Elements<_Nm> elements;
4584 inline constexpr auto keys = elements<0>;
4585 inline constexpr auto values = elements<1>;
4586 } // namespace views
4588#ifdef __cpp_lib_ranges_zip // C++ >= 23
4591 template<typename... _Rs>
4592 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4593 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4594 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4596 template<typename _Fp, typename _Tuple>
4598 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4600 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4601 return tuple<invoke_result_t<_Fp&, _Ts>...>
4602 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4603 }, std::forward<_Tuple>(__tuple));
4606 template<typename _Fp, typename _Tuple>
4608 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4610 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4611 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4612 }, std::forward<_Tuple>(__tuple));
4614 } // namespace __detail
4616 template<input_range... _Vs>
4617 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4618 class zip_view : public view_interface<zip_view<_Vs...>>
4620 tuple<_Vs...> _M_views;
4622 template<bool> class _Iterator;
4623 template<bool> class _Sentinel;
4626 zip_view() = default;
4629 zip_view(_Vs... __views)
4630 : _M_views(std::move(__views)...)
4634 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4635 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4638 begin() const requires (range<const _Vs> && ...)
4639 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4642 end() requires (!(__detail::__simple_view<_Vs> && ...))
4644 if constexpr (!__detail::__zip_is_common<_Vs...>)
4645 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4646 else if constexpr ((random_access_range<_Vs> && ...))
4647 return begin() + iter_difference_t<_Iterator<false>>(size());
4649 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4653 end() const requires (range<const _Vs> && ...)
4655 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4656 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4657 else if constexpr ((random_access_range<const _Vs> && ...))
4658 return begin() + iter_difference_t<_Iterator<true>>(size());
4660 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4664 size() requires (sized_range<_Vs> && ...)
4666 return std::apply([](auto... sizes) {
4667 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4668 return ranges::min({_CT(sizes)...});
4669 }, __detail::__tuple_transform(ranges::size, _M_views));
4673 size() const requires (sized_range<const _Vs> && ...)
4675 return std::apply([](auto... sizes) {
4676 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4677 return ranges::min({_CT(sizes)...});
4678 }, __detail::__tuple_transform(ranges::size, _M_views));
4682 template<typename... _Rs>
4683 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4685 template<typename... _Views>
4686 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4687 = (enable_borrowed_range<_Views> && ...);
4691 template<bool _Const, typename... _Vs>
4692 concept __all_random_access
4693 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4695 template<bool _Const, typename... _Vs>
4696 concept __all_bidirectional
4697 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4699 template<bool _Const, typename... _Vs>
4700 concept __all_forward
4701 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4703 template<bool _Const, typename... _Views>
4704 struct __zip_view_iter_cat
4707 template<bool _Const, typename... _Views>
4708 requires __all_forward<_Const, _Views...>
4709 struct __zip_view_iter_cat<_Const, _Views...>
4710 { using iterator_category = input_iterator_tag; };
4711 } // namespace __detail
4713 template<input_range... _Vs>
4714 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4715 template<bool _Const>
4716 class zip_view<_Vs...>::_Iterator
4717 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4719#ifdef __clang__ // LLVM-61763 workaround
4722 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4725 _Iterator(decltype(_M_current) __current)
4726 : _M_current(std::move(__current))
4732 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4733 return random_access_iterator_tag{};
4734 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4735 return bidirectional_iterator_tag{};
4736 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4737 return forward_iterator_tag{};
4739 return input_iterator_tag{};
4742#ifndef __clang__ // LLVM-61763 workaround
4743 template<move_constructible _Fp, input_range... _Ws>
4744 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4745 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4746 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4747 friend class zip_transform_view;
4751 // iterator_category defined in __zip_view_iter_cat
4752 using iterator_concept = decltype(_S_iter_concept());
4754 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4755 using difference_type
4756 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4758 _Iterator() = default;
4761 _Iterator(_Iterator<!_Const> __i)
4763 && (convertible_to<iterator_t<_Vs>,
4764 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4765 : _M_current(std::move(__i._M_current))
4771 auto __f = [](auto& __i) -> decltype(auto) {
4774 return __detail::__tuple_transform(__f, _M_current);
4777 constexpr _Iterator&
4780 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4790 requires __detail::__all_forward<_Const, _Vs...>
4797 constexpr _Iterator&
4799 requires __detail::__all_bidirectional<_Const, _Vs...>
4801 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4807 requires __detail::__all_bidirectional<_Const, _Vs...>
4814 constexpr _Iterator&
4815 operator+=(difference_type __x)
4816 requires __detail::__all_random_access<_Const, _Vs...>
4818 auto __f = [&]<typename _It>(_It& __i) {
4819 __i += iter_difference_t<_It>(__x);
4821 __detail::__tuple_for_each(__f, _M_current);
4825 constexpr _Iterator&
4826 operator-=(difference_type __x)
4827 requires __detail::__all_random_access<_Const, _Vs...>
4829 auto __f = [&]<typename _It>(_It& __i) {
4830 __i -= iter_difference_t<_It>(__x);
4832 __detail::__tuple_for_each(__f, _M_current);
4837 operator[](difference_type __n) const
4838 requires __detail::__all_random_access<_Const, _Vs...>
4840 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4841 return __i[iter_difference_t<_It>(__n)];
4843 return __detail::__tuple_transform(__f, _M_current);
4846 friend constexpr bool
4847 operator==(const _Iterator& __x, const _Iterator& __y)
4848 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4850 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4851 return __x._M_current == __y._M_current;
4853 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4854 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4855 }(make_index_sequence<sizeof...(_Vs)>{});
4858 friend constexpr auto
4859 operator<=>(const _Iterator& __x, const _Iterator& __y)
4860 requires __detail::__all_random_access<_Const, _Vs...>
4861 { return __x._M_current <=> __y._M_current; }
4863 friend constexpr _Iterator
4864 operator+(const _Iterator& __i, difference_type __n)
4865 requires __detail::__all_random_access<_Const, _Vs...>
4872 friend constexpr _Iterator
4873 operator+(difference_type __n, const _Iterator& __i)
4874 requires __detail::__all_random_access<_Const, _Vs...>
4881 friend constexpr _Iterator
4882 operator-(const _Iterator& __i, difference_type __n)
4883 requires __detail::__all_random_access<_Const, _Vs...>
4890 friend constexpr difference_type
4891 operator-(const _Iterator& __x, const _Iterator& __y)
4892 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4893 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4895 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4896 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4897 - std::get<_Is>(__y._M_current))...},
4899 [](difference_type __i) {
4900 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4902 }(make_index_sequence<sizeof...(_Vs)>{});
4905 friend constexpr auto
4906 iter_move(const _Iterator& __i)
4907 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4909 friend constexpr void
4910 iter_swap(const _Iterator& __l, const _Iterator& __r)
4911 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4913 [&]<size_t... _Is>(index_sequence<_Is...>) {
4914 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4915 }(make_index_sequence<sizeof...(_Vs)>{});
4918 friend class zip_view;
4921 template<input_range... _Vs>
4922 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4923 template<bool _Const>
4924 class zip_view<_Vs...>::_Sentinel
4926 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4929 _Sentinel(decltype(_M_end) __end)
4933 friend class zip_view;
4936 _Sentinel() = default;
4939 _Sentinel(_Sentinel<!_Const> __i)
4941 && (convertible_to<sentinel_t<_Vs>,
4942 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4943 : _M_end(std::move(__i._M_end))
4946 template<bool _OtherConst>
4947 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4948 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4949 friend constexpr bool
4950 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4952 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4953 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4954 }(make_index_sequence<sizeof...(_Vs)>{});
4957 template<bool _OtherConst>
4958 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4959 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4960 friend constexpr auto
4961 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4964 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4965 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4966 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4969 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4971 }(make_index_sequence<sizeof...(_Vs)>{});
4974 template<bool _OtherConst>
4975 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4976 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4977 friend constexpr auto
4978 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
4979 { return -(__x - __y); }
4986 template<typename... _Ts>
4987 concept __can_zip_view
4988 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
4993 template<typename... _Ts>
4994 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
4996 operator() [[nodiscard]] (_Ts&&... __ts) const
4998 if constexpr (sizeof...(_Ts) == 0)
4999 return views::empty<tuple<>>;
5001 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
5005 inline constexpr _Zip zip;
5010 template<typename _Range, bool _Const>
5011 using __range_iter_cat
5012 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5015 template<move_constructible _Fp, input_range... _Vs>
5016 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5017 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5018 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5019 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5021 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5022 zip_view<_Vs...> _M_zip;
5024 using _InnerView = zip_view<_Vs...>;
5026 template<bool _Const>
5027 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5029 template<bool _Const>
5030 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5032 template<bool _Const>
5033 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5035 template<bool _Const>
5039 template<bool _Const>
5040 requires forward_range<_Base<_Const>>
5041 struct __iter_cat<_Const>
5047 using __detail::__maybe_const_t;
5048 using __detail::__range_iter_cat;
5049 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5050 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5051 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5052 // 3798. Rvalue reference and iterator_category
5053 if constexpr (!is_reference_v<_Res>)
5054 return input_iterator_tag{};
5055 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5056 random_access_iterator_tag> && ...))
5057 return random_access_iterator_tag{};
5058 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5059 bidirectional_iterator_tag> && ...))
5060 return bidirectional_iterator_tag{};
5061 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5062 forward_iterator_tag> && ...))
5063 return forward_iterator_tag{};
5065 return input_iterator_tag{};
5068 using iterator_category = decltype(_S_iter_cat());
5071 template<bool> class _Iterator;
5072 template<bool> class _Sentinel;
5075 zip_transform_view() = default;
5078 zip_transform_view(_Fp __fun, _Vs... __views)
5079 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5084 { return _Iterator<false>(*this, _M_zip.begin()); }
5088 requires range<const _InnerView>
5089 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5090 { return _Iterator<true>(*this, _M_zip.begin()); }
5095 if constexpr (common_range<_InnerView>)
5096 return _Iterator<false>(*this, _M_zip.end());
5098 return _Sentinel<false>(_M_zip.end());
5103 requires range<const _InnerView>
5104 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5106 if constexpr (common_range<const _InnerView>)
5107 return _Iterator<true>(*this, _M_zip.end());
5109 return _Sentinel<true>(_M_zip.end());
5113 size() requires sized_range<_InnerView>
5114 { return _M_zip.size(); }
5117 size() const requires sized_range<const _InnerView>
5118 { return _M_zip.size(); }
5121 template<class _Fp, class... Rs>
5122 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5124 template<move_constructible _Fp, input_range... _Vs>
5125 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5126 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5127 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5128 template<bool _Const>
5129 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5131 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5133 _Parent* _M_parent = nullptr;
5134 __ziperator<_Const> _M_inner;
5137 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5138 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5141 friend class zip_transform_view;
5144 // iterator_category defined in zip_transform_view::__iter_cat
5145 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5147 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5148 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5149 using difference_type = range_difference_t<_Base<_Const>>;
5151 _Iterator() = default;
5154 _Iterator(_Iterator<!_Const> __i)
5155 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5156 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5159 constexpr decltype(auto)
5162 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5163 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5164 }, _M_inner._M_current);
5167 constexpr _Iterator&
5179 operator++(int) requires forward_range<_Base<_Const>>
5186 constexpr _Iterator&
5187 operator--() requires bidirectional_range<_Base<_Const>>
5194 operator--(int) requires bidirectional_range<_Base<_Const>>
5201 constexpr _Iterator&
5202 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5208 constexpr _Iterator&
5209 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5215 constexpr decltype(auto)
5216 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5218 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5219 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5220 }, _M_inner._M_current);
5223 friend constexpr bool
5224 operator==(const _Iterator& __x, const _Iterator& __y)
5225 requires equality_comparable<__ziperator<_Const>>
5226 { return __x._M_inner == __y._M_inner; }
5228 friend constexpr auto
5229 operator<=>(const _Iterator& __x, const _Iterator& __y)
5230 requires random_access_range<_Base<_Const>>
5231 { return __x._M_inner <=> __y._M_inner; }
5233 friend constexpr _Iterator
5234 operator+(const _Iterator& __i, difference_type __n)
5235 requires random_access_range<_Base<_Const>>
5236 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5238 friend constexpr _Iterator
5239 operator+(difference_type __n, const _Iterator& __i)
5240 requires random_access_range<_Base<_Const>>
5241 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5243 friend constexpr _Iterator
5244 operator-(const _Iterator& __i, difference_type __n)
5245 requires random_access_range<_Base<_Const>>
5246 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5248 friend constexpr difference_type
5249 operator-(const _Iterator& __x, const _Iterator& __y)
5250 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5251 { return __x._M_inner - __y._M_inner; }
5254 template<move_constructible _Fp, input_range... _Vs>
5255 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5256 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5257 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5258 template<bool _Const>
5259 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5261 __zentinel<_Const> _M_inner;
5264 _Sentinel(__zentinel<_Const> __inner)
5268 friend class zip_transform_view;
5271 _Sentinel() = default;
5274 _Sentinel(_Sentinel<!_Const> __i)
5275 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5276 : _M_inner(std::move(__i._M_inner))
5279 template<bool _OtherConst>
5280 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5281 friend constexpr bool
5282 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5283 { return __x._M_inner == __y._M_inner; }
5285 template<bool _OtherConst>
5286 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5287 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5288 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5289 { return __x._M_inner - __y._M_inner; }
5291 template<bool _OtherConst>
5292 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5293 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5294 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5295 { return __x._M_inner - __y._M_inner; }
5302 template<typename _Fp, typename... _Ts>
5303 concept __can_zip_transform_view
5304 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5307 struct _ZipTransform
5309 template<typename _Fp, typename... _Ts>
5310 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5312 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5314 if constexpr (sizeof...(_Ts) == 0)
5315 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5317 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5321 inline constexpr _ZipTransform zip_transform;
5324 template<forward_range _Vp, size_t _Nm>
5325 requires view<_Vp> && (_Nm > 0)
5326 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5328 _Vp _M_base = _Vp();
5330 template<bool> class _Iterator;
5331 template<bool> class _Sentinel;
5333 struct __as_sentinel
5337 adjacent_view() requires default_initializable<_Vp> = default;
5340 adjacent_view(_Vp __base)
5341 : _M_base(std::move(__base))
5344 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5345 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5347 base() const & requires copy_constructible<_Vp>
5352 { return std::move(_M_base); }
5355 begin() requires (!__detail::__simple_view<_Vp>)
5356 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5359 begin() const requires range<const _Vp>
5360 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5363 end() requires (!__detail::__simple_view<_Vp>)
5365 if constexpr (common_range<_Vp>)
5366 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5368 return _Sentinel<false>(ranges::end(_M_base));
5372 end() const requires range<const _Vp>
5374 if constexpr (common_range<const _Vp>)
5375 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5377 return _Sentinel<true>(ranges::end(_M_base));
5381 size() requires sized_range<_Vp>
5383 using _ST = decltype(ranges::size(_M_base));
5384 using _CT = common_type_t<_ST, size_t>;
5385 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5386 __sz -= std::min<_CT>(__sz, _Nm - 1);
5387 return static_cast<_ST>(__sz);
5391 size() const requires sized_range<const _Vp>
5393 using _ST = decltype(ranges::size(_M_base));
5394 using _CT = common_type_t<_ST, size_t>;
5395 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5396 __sz -= std::min<_CT>(__sz, _Nm - 1);
5397 return static_cast<_ST>(__sz);
5401 template<typename _Vp, size_t _Nm>
5402 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5403 = enable_borrowed_range<_Vp>;
5407 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5408 template<typename _Tp, size_t _Nm>
5409 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5411 // For a functor F that is callable with N arguments, the expression
5412 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5413 template<typename _Fp, size_t _Nm>
5416 template<typename... _Ts>
5417 static invoke_result_t<_Fp, _Ts...>
5418 __tuple_apply(const tuple<_Ts...>&); // not defined
5420 template<typename _Tp>
5421 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5422 operator()(_Tp&&); // not defined
5426 template<forward_range _Vp, size_t _Nm>
5427 requires view<_Vp> && (_Nm > 0)
5428 template<bool _Const>
5429 class adjacent_view<_Vp, _Nm>::_Iterator
5431#ifdef __clang__ // LLVM-61763 workaround
5434 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5435 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5438 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5440 for (auto& __i : _M_current)
5443 ranges::advance(__first, 1, __last);
5448 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5450 if constexpr (!bidirectional_range<_Base>)
5451 for (auto& __it : _M_current)
5454 for (size_t __i = 0; __i < _Nm; ++__i)
5456 _M_current[_Nm - 1 - __i] = __last;
5457 ranges::advance(__last, -1, __first);
5464 if constexpr (random_access_range<_Base>)
5465 return random_access_iterator_tag{};
5466 else if constexpr (bidirectional_range<_Base>)
5467 return bidirectional_iterator_tag{};
5469 return forward_iterator_tag{};
5472 friend class adjacent_view;
5474#ifndef __clang__ // LLVM-61763 workaround
5475 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5476 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5477 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5478 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5479 range_reference_t<_Wp>>>
5480 friend class adjacent_transform_view;
5484 using iterator_category = input_iterator_tag;
5485 using iterator_concept = decltype(_S_iter_concept());
5486 using value_type = conditional_t<_Nm == 2,
5487 pair<range_value_t<_Base>, range_value_t<_Base>>,
5488 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5489 using difference_type = range_difference_t<_Base>;
5491 _Iterator() = default;
5494 _Iterator(_Iterator<!_Const> __i)
5495 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5497 for (size_t __j = 0; __j < _Nm; ++__j)
5498 _M_current[__j] = std::move(__i._M_current[__j]);
5504 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5505 return __detail::__tuple_transform(__f, _M_current);
5508 constexpr _Iterator&
5511 for (auto& __i : _M_current)
5524 constexpr _Iterator&
5525 operator--() requires bidirectional_range<_Base>
5527 for (auto& __i : _M_current)
5533 operator--(int) requires bidirectional_range<_Base>
5540 constexpr _Iterator&
5541 operator+=(difference_type __x)
5542 requires random_access_range<_Base>
5544 for (auto& __i : _M_current)
5549 constexpr _Iterator&
5550 operator-=(difference_type __x)
5551 requires random_access_range<_Base>
5553 for (auto& __i : _M_current)
5559 operator[](difference_type __n) const
5560 requires random_access_range<_Base>
5562 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5563 return __detail::__tuple_transform(__f, _M_current);
5566 friend constexpr bool
5567 operator==(const _Iterator& __x, const _Iterator& __y)
5568 { return __x._M_current.back() == __y._M_current.back(); }
5570 friend constexpr bool
5571 operator<(const _Iterator& __x, const _Iterator& __y)
5572 requires random_access_range<_Base>
5573 { return __x._M_current.back() < __y._M_current.back(); }
5575 friend constexpr bool
5576 operator>(const _Iterator& __x, const _Iterator& __y)
5577 requires random_access_range<_Base>
5578 { return __y < __x; }
5580 friend constexpr bool
5581 operator<=(const _Iterator& __x, const _Iterator& __y)
5582 requires random_access_range<_Base>
5583 { return !(__y < __x); }
5585 friend constexpr bool
5586 operator>=(const _Iterator& __x, const _Iterator& __y)
5587 requires random_access_range<_Base>
5588 { return !(__x < __y); }
5590 friend constexpr auto
5591 operator<=>(const _Iterator& __x, const _Iterator& __y)
5592 requires random_access_range<_Base>
5593 && three_way_comparable<iterator_t<_Base>>
5594 { return __x._M_current.back() <=> __y._M_current.back(); }
5596 friend constexpr _Iterator
5597 operator+(const _Iterator& __i, difference_type __n)
5598 requires random_access_range<_Base>
5605 friend constexpr _Iterator
5606 operator+(difference_type __n, const _Iterator& __i)
5607 requires random_access_range<_Base>
5614 friend constexpr _Iterator
5615 operator-(const _Iterator& __i, difference_type __n)
5616 requires random_access_range<_Base>
5623 friend constexpr difference_type
5624 operator-(const _Iterator& __x, const _Iterator& __y)
5625 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5626 { return __x._M_current.back() - __y._M_current.back(); }
5628 friend constexpr auto
5629 iter_move(const _Iterator& __i)
5630 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5632 friend constexpr void
5633 iter_swap(const _Iterator& __l, const _Iterator& __r)
5634 requires indirectly_swappable<iterator_t<_Base>>
5636 for (size_t __i = 0; __i < _Nm; __i++)
5637 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5641 template<forward_range _Vp, size_t _Nm>
5642 requires view<_Vp> && (_Nm > 0)
5643 template<bool _Const>
5644 class adjacent_view<_Vp, _Nm>::_Sentinel
5646 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5648 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5651 _Sentinel(sentinel_t<_Base> __end)
5655 friend class adjacent_view;
5658 _Sentinel() = default;
5661 _Sentinel(_Sentinel<!_Const> __i)
5662 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5663 : _M_end(std::move(__i._M_end))
5666 template<bool _OtherConst>
5667 requires sentinel_for<sentinel_t<_Base>,
5668 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5669 friend constexpr bool
5670 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5671 { return __x._M_current.back() == __y._M_end; }
5673 template<bool _OtherConst>
5674 requires sized_sentinel_for<sentinel_t<_Base>,
5675 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5676 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5677 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5678 { return __x._M_current.back() - __y._M_end; }
5680 template<bool _OtherConst>
5681 requires sized_sentinel_for<sentinel_t<_Base>,
5682 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5683 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5684 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5685 { return __y._M_end - __x._M_current.back(); }
5692 template<size_t _Nm, typename _Range>
5693 concept __can_adjacent_view
5694 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5697 template<size_t _Nm>
5698 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5700 template<viewable_range _Range>
5701 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5703 operator() [[nodiscard]] (_Range&& __r) const
5705 if constexpr (_Nm == 0)
5706 return views::empty<tuple<>>;
5708 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5712 template<size_t _Nm>
5713 inline constexpr _Adjacent<_Nm> adjacent;
5715 inline constexpr auto pairwise = adjacent<2>;
5718 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5719 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5720 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5721 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5722 range_reference_t<_Vp>>>
5723 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5725 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5726 adjacent_view<_Vp, _Nm> _M_inner;
5728 using _InnerView = adjacent_view<_Vp, _Nm>;
5730 template<bool _Const>
5731 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5733 template<bool _Const>
5734 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5736 template<bool> class _Iterator;
5737 template<bool> class _Sentinel;
5740 adjacent_transform_view() = default;
5743 adjacent_transform_view(_Vp __base, _Fp __fun)
5744 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5747 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5748 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5749 // 3947. Unexpected constraints on adjacent_transform_view::base()
5751 base() const & requires copy_constructible<_Vp>
5752 { return _M_inner.base(); }
5756 { return std::move(_M_inner.base()); }
5760 { return _Iterator<false>(*this, _M_inner.begin()); }
5764 requires range<const _InnerView>
5765 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5766 range_reference_t<const _Vp>>
5767 { return _Iterator<true>(*this, _M_inner.begin()); }
5772 if constexpr (common_range<_InnerView>)
5773 return _Iterator<false>(*this, _M_inner.end());
5775 return _Sentinel<false>(_M_inner.end());
5780 requires range<const _InnerView>
5781 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5782 range_reference_t<const _Vp>>
5784 if constexpr (common_range<const _InnerView>)
5785 return _Iterator<true>(*this, _M_inner.end());
5787 return _Sentinel<true>(_M_inner.end());
5791 size() requires sized_range<_InnerView>
5792 { return _M_inner.size(); }
5795 size() const requires sized_range<const _InnerView>
5796 { return _M_inner.size(); }
5799 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5800 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5801 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5802 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5803 range_reference_t<_Vp>>>
5804 template<bool _Const>
5805 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5807 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5808 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5810 _Parent* _M_parent = nullptr;
5811 _InnerIter<_Const> _M_inner;
5814 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5815 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5821 using __detail::__maybe_const_t;
5822 using __detail::__unarize;
5823 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5824 range_reference_t<_Base>>;
5825 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5826 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5827 // 3798. Rvalue reference and iterator_category
5828 if constexpr (!is_reference_v<_Res>)
5829 return input_iterator_tag{};
5830 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5831 return random_access_iterator_tag{};
5832 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5833 return bidirectional_iterator_tag{};
5834 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5835 return forward_iterator_tag{};
5837 return input_iterator_tag{};
5840 friend class adjacent_transform_view;
5843 using iterator_category = decltype(_S_iter_cat());
5844 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5846 = remove_cvref_t<invoke_result_t
5847 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5848 range_reference_t<_Base>>>;
5849 using difference_type = range_difference_t<_Base>;
5851 _Iterator() = default;
5854 _Iterator(_Iterator<!_Const> __i)
5855 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5856 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5859 constexpr decltype(auto)
5862 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5863 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5864 }, _M_inner._M_current);
5867 constexpr _Iterator&
5882 constexpr _Iterator&
5883 operator--() requires bidirectional_range<_Base>
5890 operator--(int) requires bidirectional_range<_Base>
5897 constexpr _Iterator&
5898 operator+=(difference_type __x) requires random_access_range<_Base>
5904 constexpr _Iterator&
5905 operator-=(difference_type __x) requires random_access_range<_Base>
5911 constexpr decltype(auto)
5912 operator[](difference_type __n) const requires random_access_range<_Base>
5914 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5915 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5916 }, _M_inner._M_current);
5919 friend constexpr bool
5920 operator==(const _Iterator& __x, const _Iterator& __y)
5921 { return __x._M_inner == __y._M_inner; }
5923 friend constexpr bool
5924 operator<(const _Iterator& __x, const _Iterator& __y)
5925 requires random_access_range<_Base>
5926 { return __x._M_inner < __y._M_inner; }
5928 friend constexpr bool
5929 operator>(const _Iterator& __x, const _Iterator& __y)
5930 requires random_access_range<_Base>
5931 { return __x._M_inner > __y._M_inner; }
5933 friend constexpr bool
5934 operator<=(const _Iterator& __x, const _Iterator& __y)
5935 requires random_access_range<_Base>
5936 { return __x._M_inner <= __y._M_inner; }
5938 friend constexpr bool
5939 operator>=(const _Iterator& __x, const _Iterator& __y)
5940 requires random_access_range<_Base>
5941 { return __x._M_inner >= __y._M_inner; }
5943 friend constexpr auto
5944 operator<=>(const _Iterator& __x, const _Iterator& __y)
5945 requires random_access_range<_Base> &&
5946 three_way_comparable<_InnerIter<_Const>>
5947 { return __x._M_inner <=> __y._M_inner; }
5949 friend constexpr _Iterator
5950 operator+(const _Iterator& __i, difference_type __n)
5951 requires random_access_range<_Base>
5952 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5954 friend constexpr _Iterator
5955 operator+(difference_type __n, const _Iterator& __i)
5956 requires random_access_range<_Base>
5957 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5959 friend constexpr _Iterator
5960 operator-(const _Iterator& __i, difference_type __n)
5961 requires random_access_range<_Base>
5962 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5964 friend constexpr difference_type
5965 operator-(const _Iterator& __x, const _Iterator& __y)
5966 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5967 { return __x._M_inner - __y._M_inner; }
5970 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5971 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5972 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5973 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5974 range_reference_t<_Vp>>>
5975 template<bool _Const>
5976 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
5978 _InnerSent<_Const> _M_inner;
5981 _Sentinel(_InnerSent<_Const> __inner)
5985 friend class adjacent_transform_view;
5988 _Sentinel() = default;
5991 _Sentinel(_Sentinel<!_Const> __i)
5992 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
5993 : _M_inner(std::move(__i._M_inner))
5996 template<bool _OtherConst>
5997 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
5998 friend constexpr bool
5999 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6000 { return __x._M_inner == __y._M_inner; }
6002 template<bool _OtherConst>
6003 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6004 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6005 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6006 { return __x._M_inner - __y._M_inner; }
6008 template<bool _OtherConst>
6009 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6010 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6011 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6012 { return __x._M_inner - __y._M_inner; }
6019 template<size_t _Nm, typename _Range, typename _Fp>
6020 concept __can_adjacent_transform_view
6021 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6022 (std::declval<_Range>(), std::declval<_Fp>()); };
6025 template<size_t _Nm>
6026 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6028 template<viewable_range _Range, typename _Fp>
6029 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6031 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6033 if constexpr (_Nm == 0)
6034 return zip_transform(std::forward<_Fp>(__f));
6036 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6037 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6040 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6041 static constexpr int _S_arity = 2;
6042 static constexpr bool _S_has_simple_extra_args = true;
6045 template<size_t _Nm>
6046 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6048 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6050#endif // __cpp_lib_ranges_zip
6052#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6055 template<typename _Tp>
6056 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6058 _Tp __r = __num / __denom;
6059 if (__num % __denom)
6066 requires input_range<_Vp>
6067 class chunk_view : public view_interface<chunk_view<_Vp>>
6070 range_difference_t<_Vp> _M_n;
6071 range_difference_t<_Vp> _M_remainder = 0;
6072 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6079 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6080 : _M_base(std::move(__base)), _M_n(__n)
6081 { __glibcxx_assert(__n >= 0); }
6084 base() const & requires copy_constructible<_Vp>
6089 { return std::move(_M_base); }
6091 constexpr _OuterIter
6094 _M_current = ranges::begin(_M_base);
6095 _M_remainder = _M_n;
6096 return _OuterIter(*this);
6099 constexpr default_sentinel_t
6100 end() const noexcept
6101 { return default_sentinel; }
6104 size() requires sized_range<_Vp>
6106 return __detail::__to_unsigned_like(__detail::__div_ceil
6107 (ranges::distance(_M_base), _M_n));
6111 size() const requires sized_range<const _Vp>
6113 return __detail::__to_unsigned_like(__detail::__div_ceil
6114 (ranges::distance(_M_base), _M_n));
6118 template<typename _Range>
6119 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6122 requires input_range<_Vp>
6123 class chunk_view<_Vp>::_OuterIter
6125 chunk_view* _M_parent;
6128 _OuterIter(chunk_view& __parent) noexcept
6129 : _M_parent(std::__addressof(__parent))
6135 using iterator_concept = input_iterator_tag;
6136 using difference_type = range_difference_t<_Vp>;
6140 _OuterIter(_OuterIter&&) = default;
6141 _OuterIter& operator=(_OuterIter&&) = default;
6143 constexpr value_type
6146 __glibcxx_assert(*this != default_sentinel);
6147 return value_type(*_M_parent);
6150 constexpr _OuterIter&
6153 __glibcxx_assert(*this != default_sentinel);
6154 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6155 ranges::end(_M_parent->_M_base));
6156 _M_parent->_M_remainder = _M_parent->_M_n;
6164 friend constexpr bool
6165 operator==(const _OuterIter& __x, default_sentinel_t)
6167 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6168 && __x._M_parent->_M_remainder != 0;
6171 friend constexpr difference_type
6172 operator-(default_sentinel_t, const _OuterIter& __x)
6173 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6175 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6177 if (__dist < __x._M_parent->_M_remainder)
6178 return __dist == 0 ? 0 : 1;
6180 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6181 __x._M_parent->_M_n);
6184 friend constexpr difference_type
6185 operator-(const _OuterIter& __x, default_sentinel_t __y)
6186 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6187 { return -(__y - __x); }
6191 requires input_range<_Vp>
6192 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6195 chunk_view* _M_parent;
6198 value_type(chunk_view& __parent) noexcept
6199 : _M_parent(std::__addressof(__parent))
6205 constexpr _InnerIter
6206 begin() const noexcept
6207 { return _InnerIter(*_M_parent); }
6209 constexpr default_sentinel_t
6210 end() const noexcept
6211 { return default_sentinel; }
6215 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6217 return __detail::__to_unsigned_like
6218 (ranges::min(_M_parent->_M_remainder,
6219 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6224 requires input_range<_Vp>
6225 class chunk_view<_Vp>::_InnerIter
6227 chunk_view* _M_parent;
6230 _InnerIter(chunk_view& __parent) noexcept
6231 : _M_parent(std::__addressof(__parent))
6234 friend _OuterIter::value_type;
6237 using iterator_concept = input_iterator_tag;
6238 using difference_type = range_difference_t<_Vp>;
6239 using value_type = range_value_t<_Vp>;
6241 _InnerIter(_InnerIter&&) = default;
6242 _InnerIter& operator=(_InnerIter&&) = default;
6244 constexpr const iterator_t<_Vp>&
6246 { return *_M_parent->_M_current; }
6248 constexpr range_reference_t<_Vp>
6251 __glibcxx_assert(*this != default_sentinel);
6252 return **_M_parent->_M_current;
6255 constexpr _InnerIter&
6258 __glibcxx_assert(*this != default_sentinel);
6259 ++*_M_parent->_M_current;
6260 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6261 _M_parent->_M_remainder = 0;
6263 --_M_parent->_M_remainder;
6271 friend constexpr bool
6272 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6273 { return __x._M_parent->_M_remainder == 0; }
6275 friend constexpr difference_type
6276 operator-(default_sentinel_t, const _InnerIter& __x)
6277 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6279 return ranges::min(__x._M_parent->_M_remainder,
6280 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6283 friend constexpr difference_type
6284 operator-(const _InnerIter& __x, default_sentinel_t __y)
6285 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6286 { return -(__y - __x); }
6288 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6289 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6290 friend constexpr range_rvalue_reference_t<_Vp>
6291 iter_move(const _InnerIter& __i)
6292 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6293 { return ranges::iter_move(*__i._M_parent->_M_current); }
6295 friend constexpr void
6296 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6297 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6298 *__x._M_parent->_M_current)))
6299 requires indirectly_swappable<iterator_t<_Vp>>
6300 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6304 requires forward_range<_Vp>
6305 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6308 range_difference_t<_Vp> _M_n;
6309 template<bool> class _Iterator;
6313 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6314 : _M_base(std::move(__base)), _M_n(__n)
6315 { __glibcxx_assert(__n > 0); }
6318 base() const & requires copy_constructible<_Vp>
6323 { return std::move(_M_base); }
6326 begin() requires (!__detail::__simple_view<_Vp>)
6327 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6330 begin() const requires forward_range<const _Vp>
6331 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6334 end() requires (!__detail::__simple_view<_Vp>)
6336 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6338 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6339 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6341 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6342 return _Iterator<false>(this, ranges::end(_M_base));
6344 return default_sentinel;
6348 end() const requires forward_range<const _Vp>
6350 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6352 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6353 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6355 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6356 return _Iterator<true>(this, ranges::end(_M_base));
6358 return default_sentinel;
6362 size() requires sized_range<_Vp>
6364 return __detail::__to_unsigned_like(__detail::__div_ceil
6365 (ranges::distance(_M_base), _M_n));
6369 size() const requires sized_range<const _Vp>
6371 return __detail::__to_unsigned_like(__detail::__div_ceil
6372 (ranges::distance(_M_base), _M_n));
6376 template<typename _Vp>
6377 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6378 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6381 requires forward_range<_Vp>
6382 template<bool _Const>
6383 class chunk_view<_Vp>::_Iterator
6385 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6386 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6388 iterator_t<_Base> _M_current = iterator_t<_Base>();
6389 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6390 range_difference_t<_Base> _M_n = 0;
6391 range_difference_t<_Base> _M_missing = 0;
6394 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6395 range_difference_t<_Base> __missing = 0)
6396 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6397 _M_n(__parent->_M_n), _M_missing(__missing)
6403 if constexpr (random_access_range<_Base>)
6404 return random_access_iterator_tag{};
6405 else if constexpr (bidirectional_range<_Base>)
6406 return bidirectional_iterator_tag{};
6408 return forward_iterator_tag{};
6414 using iterator_category = input_iterator_tag;
6415 using iterator_concept = decltype(_S_iter_cat());
6416 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6417 using difference_type = range_difference_t<_Base>;
6419 _Iterator() = default;
6421 constexpr _Iterator(_Iterator<!_Const> __i)
6423 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6424 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6425 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6426 _M_n(__i._M_n), _M_missing(__i._M_missing)
6429 constexpr iterator_t<_Base>
6431 { return _M_current; }
6433 constexpr value_type
6436 __glibcxx_assert(_M_current != _M_end);
6437 return views::take(subrange(_M_current, _M_end), _M_n);
6440 constexpr _Iterator&
6443 __glibcxx_assert(_M_current != _M_end);
6444 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6456 constexpr _Iterator&
6457 operator--() requires bidirectional_range<_Base>
6459 ranges::advance(_M_current, _M_missing - _M_n);
6465 operator--(int) requires bidirectional_range<_Base>
6472 constexpr _Iterator&
6473 operator+=(difference_type __x)
6474 requires random_access_range<_Base>
6478 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6479 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6483 ranges::advance(_M_current, _M_n * __x + _M_missing);
6489 constexpr _Iterator&
6490 operator-=(difference_type __x)
6491 requires random_access_range<_Base>
6492 { return *this += -__x; }
6494 constexpr value_type
6495 operator[](difference_type __n) const
6496 requires random_access_range<_Base>
6497 { return *(*this + __n); }
6499 friend constexpr bool
6500 operator==(const _Iterator& __x, const _Iterator& __y)
6501 { return __x._M_current == __y._M_current; }
6503 friend constexpr bool
6504 operator==(const _Iterator& __x, default_sentinel_t)
6505 { return __x._M_current == __x._M_end; }
6507 friend constexpr bool
6508 operator<(const _Iterator& __x, const _Iterator& __y)
6509 requires random_access_range<_Base>
6510 { return __x._M_current > __y._M_current; }
6512 friend constexpr bool
6513 operator>(const _Iterator& __x, const _Iterator& __y)
6514 requires random_access_range<_Base>
6515 { return __y < __x; }
6517 friend constexpr bool
6518 operator<=(const _Iterator& __x, const _Iterator& __y)
6519 requires random_access_range<_Base>
6520 { return !(__y < __x); }
6522 friend constexpr bool
6523 operator>=(const _Iterator& __x, const _Iterator& __y)
6524 requires random_access_range<_Base>
6525 { return !(__x < __y); }
6527 friend constexpr auto
6528 operator<=>(const _Iterator& __x, const _Iterator& __y)
6529 requires random_access_range<_Base>
6530 && three_way_comparable<iterator_t<_Base>>
6531 { return __x._M_current <=> __y._M_current; }
6533 friend constexpr _Iterator
6534 operator+(const _Iterator& __i, difference_type __n)
6535 requires random_access_range<_Base>
6542 friend constexpr _Iterator
6543 operator+(difference_type __n, const _Iterator& __i)
6544 requires random_access_range<_Base>
6551 friend constexpr _Iterator
6552 operator-(const _Iterator& __i, difference_type __n)
6553 requires random_access_range<_Base>
6560 friend constexpr difference_type
6561 operator-(const _Iterator& __x, const _Iterator& __y)
6562 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6564 return (__x._M_current - __y._M_current
6565 + __x._M_missing - __y._M_missing) / __x._M_n;
6568 friend constexpr difference_type
6569 operator-(default_sentinel_t __y, const _Iterator& __x)
6570 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6571 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6573 friend constexpr difference_type
6574 operator-(const _Iterator& __x, default_sentinel_t __y)
6575 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6576 { return -(__y - __x); }
6583 template<typename _Range, typename _Dp>
6584 concept __can_chunk_view
6585 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6588 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6590 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6591 requires __detail::__can_chunk_view<_Range, _Dp>
6593 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6594 { return chunk_view(std::forward<_Range>(__r), __n); }
6596 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6597 static constexpr int _S_arity = 2;
6598 static constexpr bool _S_has_simple_extra_args = true;
6601 inline constexpr _Chunk chunk;
6603#endif // __cpp_lib_ranges_chunk
6605#ifdef __cpp_lib_ranges_slide // C++ >= 23
6608 template<typename _Vp>
6609 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6611 template<typename _Vp>
6612 concept __slide_caches_last
6613 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6615 template<typename _Vp>
6616 concept __slide_caches_first
6617 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6620 template<forward_range _Vp>
6622 class slide_view : public view_interface<slide_view<_Vp>>
6625 range_difference_t<_Vp> _M_n;
6626 [[no_unique_address]]
6627 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6628 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6629 [[no_unique_address]]
6630 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6631 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6633 template<bool> class _Iterator;
6638 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6639 : _M_base(std::move(__base)), _M_n(__n)
6640 { __glibcxx_assert(__n > 0); }
6642 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6643 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6645 base() const & requires copy_constructible<_Vp>
6650 { return std::move(_M_base); }
6653 begin() requires (!(__detail::__simple_view<_Vp>
6654 && __detail::__slide_caches_nothing<const _Vp>))
6656 if constexpr (__detail::__slide_caches_first<_Vp>)
6658 iterator_t<_Vp> __it;
6659 if (_M_cached_begin._M_has_value())
6660 __it = _M_cached_begin._M_get(_M_base);
6663 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6664 _M_cached_begin._M_set(_M_base, __it);
6666 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6669 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6673 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6674 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6677 end() requires (!(__detail::__simple_view<_Vp>
6678 && __detail::__slide_caches_nothing<const _Vp>))
6680 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6681 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6683 else if constexpr (__detail::__slide_caches_last<_Vp>)
6685 iterator_t<_Vp> __it;
6686 if (_M_cached_end._M_has_value())
6687 __it = _M_cached_end._M_get(_M_base);
6690 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6691 _M_cached_end._M_set(_M_base, __it);
6693 return _Iterator<false>(std::move(__it), _M_n);
6695 else if constexpr (common_range<_Vp>)
6696 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6698 return _Sentinel(ranges::end(_M_base));
6702 end() const requires __detail::__slide_caches_nothing<const _Vp>
6703 { return begin() + range_difference_t<const _Vp>(size()); }
6706 size() requires sized_range<_Vp>
6708 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6711 return __detail::__to_unsigned_like(__sz);
6715 size() const requires sized_range<const _Vp>
6717 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6720 return __detail::__to_unsigned_like(__sz);
6724 template<typename _Range>
6725 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6727 template<typename _Vp>
6728 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6729 = enable_borrowed_range<_Vp>;
6731 template<forward_range _Vp>
6733 template<bool _Const>
6734 class slide_view<_Vp>::_Iterator
6736 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6737 static constexpr bool _S_last_elt_present
6738 = __detail::__slide_caches_first<_Base>;
6740 iterator_t<_Base> _M_current = iterator_t<_Base>();
6741 [[no_unique_address]]
6742 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6743 _M_last_elt = decltype(_M_last_elt)();
6744 range_difference_t<_Base> _M_n = 0;
6747 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6748 requires (!_S_last_elt_present)
6749 : _M_current(__current), _M_n(__n)
6753 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6754 range_difference_t<_Base> __n)
6755 requires _S_last_elt_present
6756 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6762 if constexpr (random_access_range<_Base>)
6763 return random_access_iterator_tag{};
6764 else if constexpr (bidirectional_range<_Base>)
6765 return bidirectional_iterator_tag{};
6767 return forward_iterator_tag{};
6771 friend slide_view::_Sentinel;
6774 using iterator_category = input_iterator_tag;
6775 using iterator_concept = decltype(_S_iter_concept());
6776 using value_type = decltype(views::counted(_M_current, _M_n));
6777 using difference_type = range_difference_t<_Base>;
6779 _Iterator() = default;
6782 _Iterator(_Iterator<!_Const> __i)
6783 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6784 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6789 { return views::counted(_M_current, _M_n); }
6791 constexpr _Iterator&
6795 if constexpr (_S_last_elt_present)
6808 constexpr _Iterator&
6809 operator--() requires bidirectional_range<_Base>
6812 if constexpr (_S_last_elt_present)
6818 operator--(int) requires bidirectional_range<_Base>
6825 constexpr _Iterator&
6826 operator+=(difference_type __x)
6827 requires random_access_range<_Base>
6830 if constexpr (_S_last_elt_present)
6835 constexpr _Iterator&
6836 operator-=(difference_type __x)
6837 requires random_access_range<_Base>
6840 if constexpr (_S_last_elt_present)
6846 operator[](difference_type __n) const
6847 requires random_access_range<_Base>
6848 { return views::counted(_M_current + __n, _M_n); }
6850 friend constexpr bool
6851 operator==(const _Iterator& __x, const _Iterator& __y)
6853 if constexpr (_S_last_elt_present)
6854 return __x._M_last_elt == __y._M_last_elt;
6856 return __x._M_current == __y._M_current;
6859 friend constexpr bool
6860 operator<(const _Iterator& __x, const _Iterator& __y)
6861 requires random_access_range<_Base>
6862 { return __x._M_current < __y._M_current; }
6864 friend constexpr bool
6865 operator>(const _Iterator& __x, const _Iterator& __y)
6866 requires random_access_range<_Base>
6867 { return __y < __x; }
6869 friend constexpr bool
6870 operator<=(const _Iterator& __x, const _Iterator& __y)
6871 requires random_access_range<_Base>
6872 { return !(__y < __x); }
6874 friend constexpr bool
6875 operator>=(const _Iterator& __x, const _Iterator& __y)
6876 requires random_access_range<_Base>
6877 { return !(__x < __y); }
6879 friend constexpr auto
6880 operator<=>(const _Iterator& __x, const _Iterator& __y)
6881 requires random_access_range<_Base>
6882 && three_way_comparable<iterator_t<_Base>>
6883 { return __x._M_current <=> __y._M_current; }
6885 friend constexpr _Iterator
6886 operator+(const _Iterator& __i, difference_type __n)
6887 requires random_access_range<_Base>
6894 friend constexpr _Iterator
6895 operator+(difference_type __n, const _Iterator& __i)
6896 requires random_access_range<_Base>
6903 friend constexpr _Iterator
6904 operator-(const _Iterator& __i, difference_type __n)
6905 requires random_access_range<_Base>
6912 friend constexpr difference_type
6913 operator-(const _Iterator& __x, const _Iterator& __y)
6914 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6916 if constexpr (_S_last_elt_present)
6917 return __x._M_last_elt - __y._M_last_elt;
6919 return __x._M_current - __y._M_current;
6923 template<forward_range _Vp>
6925 class slide_view<_Vp>::_Sentinel
6927 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6930 _Sentinel(sentinel_t<_Vp> __end)
6937 _Sentinel() = default;
6939 friend constexpr bool
6940 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6941 { return __x._M_last_elt == __y._M_end; }
6943 friend constexpr range_difference_t<_Vp>
6944 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6945 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6946 { return __x._M_last_elt - __y._M_end; }
6948 friend constexpr range_difference_t<_Vp>
6949 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6950 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6951 { return __y._M_end -__x._M_last_elt; }
6958 template<typename _Range, typename _Dp>
6959 concept __can_slide_view
6960 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6963 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6965 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6966 requires __detail::__can_slide_view<_Range, _Dp>
6968 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6969 { return slide_view(std::forward<_Range>(__r), __n); }
6971 using __adaptor::_RangeAdaptor<_Slide>::operator();
6972 static constexpr int _S_arity = 2;
6973 static constexpr bool _S_has_simple_extra_args = true;
6976 inline constexpr _Slide slide;
6978#endif // __cpp_lib_ranges_slide
6980#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
6981 template<forward_range _Vp,
6982 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
6983 requires view<_Vp> && is_object_v<_Pred>
6984 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
6986 _Vp _M_base = _Vp();
6987 __detail::__box<_Pred> _M_pred;
6988 __detail::_CachedPosition<_Vp> _M_cached_begin;
6990 constexpr iterator_t<_Vp>
6991 _M_find_next(iterator_t<_Vp> __current)
6993 __glibcxx_assert(_M_pred.has_value());
6994 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
6995 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
6997 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
6998 return ranges::next(__it, 1, ranges::end(_M_base));
7001 constexpr iterator_t<_Vp>
7002 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
7004 __glibcxx_assert(_M_pred.has_value());
7005 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7006 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
7008 auto __rbegin = std::make_reverse_iterator(__current);
7009 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
7010 __glibcxx_assert(__rbegin != __rend);
7011 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7012 return ranges::prev(__it, 1, ranges::begin(_M_base));
7018 chunk_by_view() requires (default_initializable<_Vp>
7019 && default_initializable<_Pred>)
7023 chunk_by_view(_Vp __base, _Pred __pred)
7024 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7028 base() const & requires copy_constructible<_Vp>
7033 { return std::move(_M_base); }
7035 constexpr const _Pred&
7037 { return *_M_pred; }
7042 __glibcxx_assert(_M_pred.has_value());
7043 iterator_t<_Vp> __it;
7044 if (_M_cached_begin._M_has_value())
7045 __it = _M_cached_begin._M_get(_M_base);
7048 __it = _M_find_next(ranges::begin(_M_base));
7049 _M_cached_begin._M_set(_M_base, __it);
7051 return _Iterator(*this, ranges::begin(_M_base), __it);
7057 if constexpr (common_range<_Vp>)
7058 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7060 return default_sentinel;
7064 template<typename _Range, typename _Pred>
7065 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7067 template<forward_range _Vp,
7068 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7069 requires view<_Vp> && is_object_v<_Pred>
7070 class chunk_by_view<_Vp, _Pred>::_Iterator
7072 chunk_by_view* _M_parent = nullptr;
7073 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7074 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7077 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7078 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7084 if constexpr (bidirectional_range<_Vp>)
7085 return bidirectional_iterator_tag{};
7087 return forward_iterator_tag{};
7090 friend chunk_by_view;
7093 using value_type = subrange<iterator_t<_Vp>>;
7094 using difference_type = range_difference_t<_Vp>;
7095 using iterator_category = input_iterator_tag;
7096 using iterator_concept = decltype(_S_iter_concept());
7098 _Iterator() = default;
7100 constexpr value_type
7103 __glibcxx_assert(_M_current != _M_next);
7104 return ranges::subrange(_M_current, _M_next);
7107 constexpr _Iterator&
7110 __glibcxx_assert(_M_current != _M_next);
7111 _M_current = _M_next;
7112 _M_next = _M_parent->_M_find_next(_M_current);
7124 constexpr _Iterator&
7125 operator--() requires bidirectional_range<_Vp>
7127 _M_next = _M_current;
7128 _M_current = _M_parent->_M_find_prev(_M_next);
7133 operator--(int) requires bidirectional_range<_Vp>
7140 friend constexpr bool
7141 operator==(const _Iterator& __x, const _Iterator& __y)
7142 { return __x._M_current == __y._M_current; }
7144 friend constexpr bool
7145 operator==(const _Iterator& __x, default_sentinel_t)
7146 { return __x._M_current == __x._M_next; }
7153 template<typename _Range, typename _Pred>
7154 concept __can_chunk_by_view
7155 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7158 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7160 template<viewable_range _Range, typename _Pred>
7161 requires __detail::__can_chunk_by_view<_Range, _Pred>
7163 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7164 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7166 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7167 static constexpr int _S_arity = 2;
7168 static constexpr bool _S_has_simple_extra_args = true;
7171 inline constexpr _ChunkBy chunk_by;
7173#endif // __cpp_lib_ranges_chunk_by
7175#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7178 template<typename _Range, typename _Pattern>
7179 concept __compatible_joinable_ranges
7180 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7181 && common_reference_with<range_reference_t<_Range>,
7182 range_reference_t<_Pattern>>
7183 && common_reference_with<range_rvalue_reference_t<_Range>,
7184 range_rvalue_reference_t<_Pattern>>;
7186 template<typename _Range>
7187 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7190 template<input_range _Vp, forward_range _Pattern>
7191 requires view<_Vp> && view<_Pattern>
7192 && input_range<range_reference_t<_Vp>>
7193 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7194 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7196 using _InnerRange = range_reference_t<_Vp>;
7198 _Vp _M_base = _Vp();
7199 [[no_unique_address]]
7200 __detail::__maybe_present_t<!forward_range<_Vp>,
7201 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7202 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7203 _Pattern _M_pattern = _Pattern();
7205 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7206 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7207 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7209 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7210 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7211 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7213 template<bool _Const>
7214 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7216 template<bool _Const>
7220 template<bool _Const>
7221 requires _S_ref_is_glvalue<_Const>
7222 && forward_range<_Base<_Const>>
7223 && forward_range<_InnerBase<_Const>>
7224 struct __iter_cat<_Const>
7230 using _OuterIter = join_with_view::_OuterIter<_Const>;
7231 using _InnerIter = join_with_view::_InnerIter<_Const>;
7232 using _PatternIter = join_with_view::_PatternIter<_Const>;
7233 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7234 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7235 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7236 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7237 // 3798. Rvalue reference and iterator_category
7238 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7239 iter_reference_t<_PatternIter>>>)
7240 return input_iterator_tag{};
7241 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7242 && derived_from<_InnerCat, bidirectional_iterator_tag>
7243 && derived_from<_PatternCat, bidirectional_iterator_tag>
7244 && common_range<_InnerBase<_Const>>
7245 && common_range<_PatternBase<_Const>>)
7246 return bidirectional_iterator_tag{};
7247 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7248 && derived_from<_InnerCat, forward_iterator_tag>
7249 && derived_from<_PatternCat, forward_iterator_tag>)
7250 return forward_iterator_tag{};
7252 return input_iterator_tag{};
7255 using iterator_category = decltype(_S_iter_cat());
7258 template<bool> struct _Iterator;
7259 template<bool> struct _Sentinel;
7262 join_with_view() requires (default_initializable<_Vp>
7263 && default_initializable<_Pattern>)
7267 join_with_view(_Vp __base, _Pattern __pattern)
7268 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7271 template<input_range _Range>
7272 requires constructible_from<_Vp, views::all_t<_Range>>
7273 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7275 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7276 : _M_base(views::all(std::forward<_Range>(__r))),
7277 _M_pattern(views::single(std::move(__e)))
7281 base() const& requires copy_constructible<_Vp>
7286 { return std::move(_M_base); }
7291 if constexpr (forward_range<_Vp>)
7293 constexpr bool __use_const = is_reference_v<_InnerRange>
7294 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7295 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7299 _M_outer_it = ranges::begin(_M_base);
7300 return _Iterator<false>{*this};
7306 requires forward_range<const _Vp>
7307 && forward_range<const _Pattern>
7308 && is_reference_v<range_reference_t<const _Vp>>
7309 && input_range<range_reference_t<const _Vp>>
7310 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7315 constexpr bool __use_const
7316 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7317 if constexpr (is_reference_v<_InnerRange>
7318 && forward_range<_Vp> && common_range<_Vp>
7319 && forward_range<_InnerRange> && common_range<_InnerRange>)
7320 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7322 return _Sentinel<__use_const>{*this};
7327 requires forward_range<const _Vp>
7328 && forward_range<const _Pattern>
7329 && is_reference_v<range_reference_t<const _Vp>>
7330 && input_range<range_reference_t<const _Vp>>
7332 using _InnerConstRange = range_reference_t<const _Vp>;
7333 if constexpr (forward_range<_InnerConstRange>
7334 && common_range<const _Vp>
7335 && common_range<_InnerConstRange>)
7336 return _Iterator<true>{*this, ranges::end(_M_base)};
7338 return _Sentinel<true>{*this};
7342 template<typename _Range, typename _Pattern>
7343 join_with_view(_Range&&, _Pattern&&)
7344 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7346 template<input_range _Range>
7347 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7348 -> join_with_view<views::all_t<_Range>,
7349 single_view<range_value_t<range_reference_t<_Range>>>>;
7351 template<input_range _Vp, forward_range _Pattern>
7352 requires view<_Vp> && view<_Pattern>
7353 && input_range<range_reference_t<_Vp>>
7354 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7355 template<bool _Const>
7356 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7358 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7359 using _Base = join_with_view::_Base<_Const>;
7360 using _InnerBase = join_with_view::_InnerBase<_Const>;
7361 using _PatternBase = join_with_view::_PatternBase<_Const>;
7363 using _OuterIter = join_with_view::_OuterIter<_Const>;
7364 using _InnerIter = join_with_view::_InnerIter<_Const>;
7365 using _PatternIter = join_with_view::_PatternIter<_Const>;
7367 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7369 _Parent* _M_parent = nullptr;
7370 [[no_unique_address]]
7371 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7372 variant<_PatternIter, _InnerIter> _M_inner_it;
7374 constexpr _OuterIter&
7377 if constexpr (forward_range<_Base>)
7380 return *_M_parent->_M_outer_it;
7383 constexpr const _OuterIter&
7384 _M_get_outer() const
7386 if constexpr (forward_range<_Base>)
7389 return *_M_parent->_M_outer_it;
7393 _Iterator(_Parent& __parent, _OuterIter __outer)
7394 requires forward_range<_Base>
7395 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7397 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7399 auto&& __inner = _M_update_inner();
7400 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7406 _Iterator(_Parent& __parent)
7407 requires (!forward_range<_Base>)
7408 : _M_parent(std::__addressof(__parent))
7410 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7412 auto&& __inner = _M_update_inner();
7413 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7421 _OuterIter& __outer = _M_get_outer();
7422 if constexpr (_S_ref_is_glvalue)
7423 return __detail::__as_lvalue(*__outer);
7425 return _M_parent->_M_inner._M_emplace_deref(__outer);
7431 if constexpr (_S_ref_is_glvalue)
7432 return __detail::__as_lvalue(*_M_get_outer());
7434 return *_M_parent->_M_inner;
7442 if (_M_inner_it.index() == 0)
7444 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7447 auto&& __inner = _M_update_inner();
7448 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7452 auto&& __inner = _M_get_inner();
7453 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7456 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7458 if constexpr (_S_ref_is_glvalue)
7459 _M_inner_it.template emplace<0>();
7463 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7471 if constexpr (_S_ref_is_glvalue
7472 && bidirectional_range<_Base>
7473 && __detail::__bidirectional_common<_InnerBase>
7474 && __detail::__bidirectional_common<_PatternBase>)
7475 return bidirectional_iterator_tag{};
7476 else if constexpr (_S_ref_is_glvalue
7477 && forward_range<_Base>
7478 && forward_range<_InnerBase>)
7479 return forward_iterator_tag{};
7481 return input_iterator_tag{};
7484 friend join_with_view;
7487 using iterator_concept = decltype(_S_iter_concept());
7488 // iterator_category defined in join_with_view::__iter_cat
7489 using value_type = common_type_t<iter_value_t<_InnerIter>,
7490 iter_value_t<_PatternIter>>;
7491 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7492 iter_difference_t<_InnerIter>,
7493 iter_difference_t<_PatternIter>>;
7495 _Iterator() = default;
7498 _Iterator(_Iterator<!_Const> __i)
7500 && convertible_to<iterator_t<_Vp>, _OuterIter>
7501 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7502 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7503 : _M_parent(__i._M_parent),
7504 _M_outer_it(std::move(__i._M_outer_it))
7506 if (__i._M_inner_it.index() == 0)
7507 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7509 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7512 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7513 iter_reference_t<_PatternIter>>
7516 if (_M_inner_it.index() == 0)
7517 return *std::get<0>(_M_inner_it);
7519 return *std::get<1>(_M_inner_it);
7522 constexpr _Iterator&
7525 if (_M_inner_it.index() == 0)
7526 ++std::get<0>(_M_inner_it);
7528 ++std::get<1>(_M_inner_it);
7539 requires _S_ref_is_glvalue
7540 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7542 _Iterator __tmp = *this;
7547 constexpr _Iterator&
7549 requires _S_ref_is_glvalue
7550 && bidirectional_range<_Base>
7551 && __detail::__bidirectional_common<_InnerBase>
7552 && __detail::__bidirectional_common<_PatternBase>
7554 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7556 auto&& __inner = *--_M_outer_it;
7557 _M_inner_it.template emplace<1>(ranges::end(__inner));
7562 if (_M_inner_it.index() == 0)
7564 auto& __it = std::get<0>(_M_inner_it);
7565 if (__it == ranges::begin(_M_parent->_M_pattern))
7567 auto&& __inner = *--_M_outer_it;
7568 _M_inner_it.template emplace<1>(ranges::end(__inner));
7575 auto& __it = std::get<1>(_M_inner_it);
7576 auto&& __inner = *_M_outer_it;
7577 if (__it == ranges::begin(__inner))
7578 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7584 if (_M_inner_it.index() == 0)
7585 --std::get<0>(_M_inner_it);
7587 --std::get<1>(_M_inner_it);
7593 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7594 && __detail::__bidirectional_common<_InnerBase>
7595 && __detail::__bidirectional_common<_PatternBase>
7597 _Iterator __tmp = *this;
7602 friend constexpr bool
7603 operator==(const _Iterator& __x, const _Iterator& __y)
7604 requires _S_ref_is_glvalue
7605 && forward_range<_Base> && equality_comparable<_InnerIter>
7606 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7608 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7609 iter_rvalue_reference_t<_PatternIter>>
7610 iter_move(const _Iterator& __x)
7612 if (__x._M_inner_it.index() == 0)
7613 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7615 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7618 friend constexpr void
7619 iter_swap(const _Iterator& __x, const _Iterator& __y)
7620 requires indirectly_swappable<_InnerIter, _PatternIter>
7622 if (__x._M_inner_it.index() == 0)
7624 if (__y._M_inner_it.index() == 0)
7625 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7627 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7631 if (__y._M_inner_it.index() == 0)
7632 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7634 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7639 template<input_range _Vp, forward_range _Pattern>
7640 requires view<_Vp> && view<_Pattern>
7641 && input_range<range_reference_t<_Vp>>
7642 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7643 template<bool _Const>
7644 class join_with_view<_Vp, _Pattern>::_Sentinel
7646 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7647 using _Base = join_with_view::_Base<_Const>;
7649 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7652 _Sentinel(_Parent& __parent)
7653 : _M_end(ranges::end(__parent._M_base))
7656 friend join_with_view;
7659 _Sentinel() = default;
7662 _Sentinel(_Sentinel<!_Const> __s)
7663 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7664 : _M_end(std::move(__s._M_end))
7667 template<bool _OtherConst>
7668 requires sentinel_for<sentinel_t<_Base>,
7669 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7670 friend constexpr bool
7671 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7672 { return __x._M_get_outer() == __y._M_end; }
7679 template<typename _Range, typename _Pattern>
7680 concept __can_join_with_view
7681 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7682 } // namespace __detail
7684 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7686 template<viewable_range _Range, typename _Pattern>
7687 requires __detail::__can_join_with_view<_Range, _Pattern>
7689 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7691 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7694 using _RangeAdaptor<_JoinWith>::operator();
7695 static constexpr int _S_arity = 2;
7696 template<typename _Pattern>
7697 static constexpr bool _S_has_simple_extra_args
7698 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7701 inline constexpr _JoinWith join_with;
7702 } // namespace views
7703#endif // __cpp_lib_ranges_join_with
7705#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7706 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7707 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7708 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7709 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7711 __detail::__box<_Tp> _M_value;
7712 [[no_unique_address]] _Bound _M_bound = _Bound();
7716 template<typename _Range>
7717 friend constexpr auto
7718 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7720 template<typename _Range>
7721 friend constexpr auto
7722 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7725 repeat_view() requires default_initializable<_Tp> = default;
7728 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7729 requires copy_constructible<_Tp>
7730 : _M_value(__value), _M_bound(__bound)
7732 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7733 __glibcxx_assert(__bound >= 0);
7737 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7738 : _M_value(std::move(__value)), _M_bound(__bound)
7741 template<typename... _Args, typename... _BoundArgs>
7742 requires constructible_from<_Tp, _Args...>
7743 && constructible_from<_Bound, _BoundArgs...>
7745 repeat_view(piecewise_construct_t,
7746 tuple<_Args...> __args,
7747 tuple<_BoundArgs...> __bound_args = tuple<>{})
7748 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7749 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7754 { return _Iterator(std::__addressof(*_M_value)); }
7757 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7758 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7760 constexpr unreachable_sentinel_t
7761 end() const noexcept
7762 { return unreachable_sentinel; }
7765 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7766 { return __detail::__to_unsigned_like(_M_bound); }
7769 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7770 // 4053. Unary call to std::views::repeat does not decay the argument
7771 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7772 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7774 template<move_constructible _Tp, semiregular _Bound>
7775 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7776 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7777 class repeat_view<_Tp, _Bound>::_Iterator
7780 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7782 const _Tp* _M_value = nullptr;
7783 __index_type _M_current = __index_type();
7786 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7787 : _M_value(__value), _M_current(__bound)
7789 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7790 __glibcxx_assert(__bound >= 0);
7796 using iterator_concept = random_access_iterator_tag;
7797 using iterator_category = random_access_iterator_tag;
7798 using value_type = _Tp;
7799 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7801 __detail::__iota_diff_t<__index_type>>;
7803 _Iterator() = default;
7805 constexpr const _Tp&
7806 operator*() const noexcept
7807 { return *_M_value; }
7809 constexpr _Iterator&
7824 constexpr _Iterator&
7827 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7828 __glibcxx_assert(_M_current > 0);
7841 constexpr _Iterator&
7842 operator+=(difference_type __n)
7844 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7845 __glibcxx_assert(_M_current + __n >= 0);
7850 constexpr _Iterator&
7851 operator-=(difference_type __n)
7853 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7854 __glibcxx_assert(_M_current - __n >= 0);
7859 constexpr const _Tp&
7860 operator[](difference_type __n) const noexcept
7861 { return *(*this + __n); }
7863 friend constexpr bool
7864 operator==(const _Iterator& __x, const _Iterator& __y)
7865 { return __x._M_current == __y._M_current; }
7867 friend constexpr auto
7868 operator<=>(const _Iterator& __x, const _Iterator& __y)
7869 { return __x._M_current <=> __y._M_current; }
7871 friend constexpr _Iterator
7872 operator+(_Iterator __i, difference_type __n)
7878 friend constexpr _Iterator
7879 operator+(difference_type __n, _Iterator __i)
7880 { return __i + __n; }
7882 friend constexpr _Iterator
7883 operator-(_Iterator __i, difference_type __n)
7889 friend constexpr difference_type
7890 operator-(const _Iterator& __x, const _Iterator& __y)
7892 return (static_cast<difference_type>(__x._M_current)
7893 - static_cast<difference_type>(__y._M_current));
7901 template<typename _Tp, typename _Bound>
7902 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7904 template<typename _Tp>
7905 concept __can_repeat_view
7906 = requires { repeat_view(std::declval<_Tp>()); };
7908 template<typename _Tp, typename _Bound>
7909 concept __can_bounded_repeat_view
7910 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7915 template<typename _Tp>
7916 requires __detail::__can_repeat_view<_Tp>
7918 operator() [[nodiscard]] (_Tp&& __value) const
7920 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7921 // 4054. Repeating a repeat_view should repeat the view
7922 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7925 template<typename _Tp, typename _Bound>
7926 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7928 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7929 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7932 inline constexpr _Repeat repeat;
7936 template<typename _Range>
7938 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7940 using _Tp = remove_cvref_t<_Range>;
7941 static_assert(__is_repeat_view<_Tp>);
7942 if constexpr (sized_range<_Tp>)
7943 return views::repeat(*std::forward<_Range>(__r)._M_value,
7944 std::min(ranges::distance(__r), __n));
7946 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7949 template<typename _Range>
7951 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7953 using _Tp = remove_cvref_t<_Range>;
7954 static_assert(__is_repeat_view<_Tp>);
7955 if constexpr (sized_range<_Tp>)
7957 auto __sz = ranges::distance(__r);
7958 return views::repeat(*std::forward<_Range>(__r)._M_value,
7959 __sz - std::min(__sz, __n));
7966#endif // __cpp_lib_ranges_repeat
7968#ifdef __cpp_lib_ranges_stride // C++ >= 23
7969 template<input_range _Vp>
7971 class stride_view : public view_interface<stride_view<_Vp>>
7974 range_difference_t<_Vp> _M_stride;
7976 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7978 template<bool _Const>
7982 template<bool _Const>
7983 requires forward_range<_Base<_Const>>
7984 struct __iter_cat<_Const>
7990 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
7991 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
7992 return random_access_iterator_tag{};
7997 using iterator_category = decltype(_S_iter_cat());
8000 template<bool> class _Iterator;
8004 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8005 : _M_base(std::move(__base)), _M_stride(__stride)
8006 { __glibcxx_assert(__stride > 0); }
8009 base() const& requires copy_constructible<_Vp>
8014 { return std::move(_M_base); }
8016 constexpr range_difference_t<_Vp>
8017 stride() const noexcept
8018 { return _M_stride; }
8021 begin() requires (!__detail::__simple_view<_Vp>)
8022 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8025 begin() const requires range<const _Vp>
8026 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8029 end() requires (!__detail::__simple_view<_Vp>)
8031 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8033 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8034 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8036 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8037 return _Iterator<false>(this, ranges::end(_M_base));
8039 return default_sentinel;
8043 end() const requires range<const _Vp>
8045 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8046 && forward_range<const _Vp>)
8048 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8049 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8051 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8052 return _Iterator<true>(this, ranges::end(_M_base));
8054 return default_sentinel;
8058 size() requires sized_range<_Vp>
8060 return __detail::__to_unsigned_like
8061 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8065 size() const requires sized_range<const _Vp>
8067 return __detail::__to_unsigned_like
8068 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8072 template<typename _Range>
8073 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8075 template<typename _Vp>
8076 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8077 = enable_borrowed_range<_Vp>;
8079 template<input_range _Vp>
8081 template<bool _Const>
8082 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8084 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8085 using _Base = stride_view::_Base<_Const>;
8087 iterator_t<_Base> _M_current = iterator_t<_Base>();
8088 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8089 range_difference_t<_Base> _M_stride = 0;
8090 range_difference_t<_Base> _M_missing = 0;
8093 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8094 range_difference_t<_Base> __missing = 0)
8095 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8096 _M_stride(__parent->_M_stride), _M_missing(__missing)
8102 if constexpr (random_access_range<_Base>)
8103 return random_access_iterator_tag{};
8104 else if constexpr (bidirectional_range<_Base>)
8105 return bidirectional_iterator_tag{};
8106 else if constexpr (forward_range<_Base>)
8107 return forward_iterator_tag{};
8109 return input_iterator_tag{};
8115 using difference_type = range_difference_t<_Base>;
8116 using value_type = range_value_t<_Base>;
8117 using iterator_concept = decltype(_S_iter_concept());
8118 // iterator_category defined in stride_view::__iter_cat
8120 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8123 _Iterator(_Iterator<!_Const> __other)
8125 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8126 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8127 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8128 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8131 constexpr iterator_t<_Base>
8133 { return std::move(_M_current); }
8135 constexpr const iterator_t<_Base>&
8136 base() const & noexcept
8137 { return _M_current; }
8139 constexpr decltype(auto)
8141 { return *_M_current; }
8143 constexpr _Iterator&
8146 __glibcxx_assert(_M_current != _M_end);
8147 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8156 operator++(int) requires forward_range<_Base>
8163 constexpr _Iterator&
8164 operator--() requires bidirectional_range<_Base>
8166 ranges::advance(_M_current, _M_missing - _M_stride);
8172 operator--(int) requires bidirectional_range<_Base>
8179 constexpr _Iterator&
8180 operator+=(difference_type __n) requires random_access_range<_Base>
8184 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8185 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8189 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8195 constexpr _Iterator&
8196 operator-=(difference_type __n) requires random_access_range<_Base>
8197 { return *this += -__n; }
8199 constexpr decltype(auto) operator[](difference_type __n) const
8200 requires random_access_range<_Base>
8201 { return *(*this + __n); }
8203 friend constexpr bool
8204 operator==(const _Iterator& __x, default_sentinel_t)
8205 { return __x._M_current == __x._M_end; }
8207 friend constexpr bool
8208 operator==(const _Iterator& __x, const _Iterator& __y)
8209 requires equality_comparable<iterator_t<_Base>>
8210 { return __x._M_current == __y._M_current; }
8212 friend constexpr bool
8213 operator<(const _Iterator& __x, const _Iterator& __y)
8214 requires random_access_range<_Base>
8215 { return __x._M_current < __y._M_current; }
8217 friend constexpr bool
8218 operator>(const _Iterator& __x, const _Iterator& __y)
8219 requires random_access_range<_Base>
8220 { return __y._M_current < __x._M_current; }
8222 friend constexpr bool
8223 operator<=(const _Iterator& __x, const _Iterator& __y)
8224 requires random_access_range<_Base>
8225 { return !(__y._M_current < __x._M_current); }
8227 friend constexpr bool
8228 operator>=(const _Iterator& __x, const _Iterator& __y)
8229 requires random_access_range<_Base>
8230 { return !(__x._M_current < __y._M_current); }
8232 friend constexpr auto
8233 operator<=>(const _Iterator& __x, const _Iterator& __y)
8234 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8235 { return __x._M_current <=> __y._M_current; }
8237 friend constexpr _Iterator
8238 operator+(const _Iterator& __i, difference_type __n)
8239 requires random_access_range<_Base>
8246 friend constexpr _Iterator
8247 operator+(difference_type __n, const _Iterator& __i)
8248 requires random_access_range<_Base>
8249 { return __i + __n; }
8251 friend constexpr _Iterator
8252 operator-(const _Iterator& __i, difference_type __n)
8253 requires random_access_range<_Base>
8260 friend constexpr difference_type
8261 operator-(const _Iterator& __x, const _Iterator& __y)
8262 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8264 auto __n = __x._M_current - __y._M_current;
8265 if constexpr (forward_range<_Base>)
8266 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8268 return -__detail::__div_ceil(-__n, __x._M_stride);
8270 return __detail::__div_ceil(__n, __x._M_stride);
8273 friend constexpr difference_type
8274 operator-(default_sentinel_t __y, const _Iterator& __x)
8275 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8276 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8278 friend constexpr difference_type
8279 operator-(const _Iterator& __x, default_sentinel_t __y)
8280 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8281 { return -(__y - __x); }
8283 friend constexpr range_rvalue_reference_t<_Base>
8284 iter_move(const _Iterator& __i)
8285 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8286 { return ranges::iter_move(__i._M_current); }
8288 friend constexpr void
8289 iter_swap(const _Iterator& __x, const _Iterator& __y)
8290 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8291 requires indirectly_swappable<iterator_t<_Base>>
8292 { ranges::iter_swap(__x._M_current, __y._M_current); }
8299 template<typename _Range, typename _Dp>
8300 concept __can_stride_view
8301 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8304 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8306 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8307 requires __detail::__can_stride_view<_Range, _Dp>
8309 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8310 { return stride_view(std::forward<_Range>(__r), __n); }
8312 using __adaptor::_RangeAdaptor<_Stride>::operator();
8313 static constexpr int _S_arity = 2;
8314 static constexpr bool _S_has_simple_extra_args = true;
8317 inline constexpr _Stride stride;
8319#endif // __cpp_lib_ranges_stride
8321#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8324 template<bool _Const, typename _First, typename... _Vs>
8325 concept __cartesian_product_is_random_access
8326 = (random_access_range<__maybe_const_t<_Const, _First>>
8328 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8329 && sized_range<__maybe_const_t<_Const, _Vs>>));
8331 template<typename _Range>
8332 concept __cartesian_product_common_arg
8333 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8335 template<bool _Const, typename _First, typename... _Vs>
8336 concept __cartesian_product_is_bidirectional
8337 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8339 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8340 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8342 template<typename _First, typename... _Vs>
8343 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8345 template<typename... _Vs>
8346 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8348 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8349 concept __cartesian_is_sized_sentinel
8350 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8351 iterator_t<__maybe_const_t<_Const, _First>>>
8353 && (sized_range<__maybe_const_t<_Const, _Vs>>
8354 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8355 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8357 template<__cartesian_product_common_arg _Range>
8359 __cartesian_common_arg_end(_Range& __r)
8361 if constexpr (common_range<_Range>)
8362 return ranges::end(__r);
8364 return ranges::begin(__r) + ranges::distance(__r);
8366 } // namespace __detail
8368 template<input_range _First, forward_range... _Vs>
8369 requires (view<_First> && ... && view<_Vs>)
8370 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8372 tuple<_First, _Vs...> _M_bases;
8374 template<bool> class _Iterator;
8377 _S_difference_type()
8379 // TODO: Implement the recommended practice of using the smallest
8380 // sufficiently wide type according to the maximum sizes of the
8381 // underlying ranges?
8382 return common_type_t<ptrdiff_t,
8383 range_difference_t<_First>,
8384 range_difference_t<_Vs>...>{};
8388 cartesian_product_view() = default;
8391 cartesian_product_view(_First __first, _Vs... __rest)
8392 : _M_bases(std::move(__first), std::move(__rest)...)
8395 constexpr _Iterator<false>
8396 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8397 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8399 constexpr _Iterator<true>
8400 begin() const requires (range<const _First> && ... && range<const _Vs>)
8401 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8403 constexpr _Iterator<false>
8404 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8405 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8407 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8408 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8409 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8410 auto& __first = std::get<0>(_M_bases);
8411 return _Ret{(__empty_tail
8412 ? ranges::begin(__first)
8413 : __detail::__cartesian_common_arg_end(__first)),
8414 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8415 }(make_index_sequence<sizeof...(_Vs)>{});
8417 return _Iterator<false>{*this, std::move(__its)};
8420 constexpr _Iterator<true>
8421 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8423 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8424 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8425 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8426 auto& __first = std::get<0>(_M_bases);
8427 return _Ret{(__empty_tail
8428 ? ranges::begin(__first)
8429 : __detail::__cartesian_common_arg_end(__first)),
8430 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8431 }(make_index_sequence<sizeof...(_Vs)>{});
8433 return _Iterator<true>{*this, std::move(__its)};
8436 constexpr default_sentinel_t
8437 end() const noexcept
8438 { return default_sentinel; }
8441 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8443 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8444 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8445 auto __size = static_cast<_ST>(1);
8446#ifdef _GLIBCXX_ASSERTIONS
8447 if constexpr (integral<_ST>)
8450 = (__builtin_mul_overflow(__size,
8451 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8454 __glibcxx_assert(!__overflow);
8458 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8460 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8464 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8466 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8467 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8468 auto __size = static_cast<_ST>(1);
8469#ifdef _GLIBCXX_ASSERTIONS
8470 if constexpr (integral<_ST>)
8473 = (__builtin_mul_overflow(__size,
8474 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8477 __glibcxx_assert(!__overflow);
8481 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8483 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8487 template<typename... _Vs>
8488 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8490 template<input_range _First, forward_range... _Vs>
8491 requires (view<_First> && ... && view<_Vs>)
8492 template<bool _Const>
8493 class cartesian_product_view<_First, _Vs...>::_Iterator
8495 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8496 _Parent* _M_parent = nullptr;
8497 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8498 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8501 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8502 : _M_parent(std::__addressof(__parent)),
8503 _M_current(std::move(__current))
8509 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8510 return random_access_iterator_tag{};
8511 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8512 return bidirectional_iterator_tag{};
8513 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8514 return forward_iterator_tag{};
8516 return input_iterator_tag{};
8519 friend cartesian_product_view;
8522 using iterator_category = input_iterator_tag;
8523 using iterator_concept = decltype(_S_iter_concept());
8525 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8526 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8528 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8529 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8530 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8532 _Iterator() = default;
8535 _Iterator(_Iterator<!_Const> __i)
8537 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8538 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8539 : _M_parent(std::__addressof(__i._M_parent)),
8540 _M_current(std::move(__i._M_current))
8546 auto __f = [](auto& __i) -> decltype(auto) {
8549 return __detail::__tuple_transform(__f, _M_current);
8552 constexpr _Iterator&
8564 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8571 constexpr _Iterator&
8573 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8581 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8588 constexpr _Iterator&
8589 operator+=(difference_type __x)
8590 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8596 constexpr _Iterator&
8597 operator-=(difference_type __x)
8598 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8599 { return *this += -__x; }
8602 operator[](difference_type __n) const
8603 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8604 { return *((*this) + __n); }
8606 friend constexpr bool
8607 operator==(const _Iterator& __x, const _Iterator& __y)
8608 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8609 { return __x._M_current == __y._M_current; }
8611 friend constexpr bool
8612 operator==(const _Iterator& __x, default_sentinel_t)
8614 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8615 return ((std::get<_Is>(__x._M_current)
8616 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8618 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8621 friend constexpr auto
8622 operator<=>(const _Iterator& __x, const _Iterator& __y)
8623 requires __detail::__all_random_access<_Const, _First, _Vs...>
8624 { return __x._M_current <=> __y._M_current; }
8626 friend constexpr _Iterator
8627 operator+(_Iterator __x, difference_type __y)
8628 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8629 { return __x += __y; }
8631 friend constexpr _Iterator
8632 operator+(difference_type __x, _Iterator __y)
8633 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8634 { return __y += __x; }
8636 friend constexpr _Iterator
8637 operator-(_Iterator __x, difference_type __y)
8638 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8639 { return __x -= __y; }
8641 friend constexpr difference_type
8642 operator-(const _Iterator& __x, const _Iterator& __y)
8643 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8644 { return __x._M_distance_from(__y._M_current); }
8646 friend constexpr difference_type
8647 operator-(const _Iterator& __i, default_sentinel_t)
8648 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8650 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8651 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8652 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8653 }(make_index_sequence<sizeof...(_Vs)>{});
8654 return __i._M_distance_from(__end_tuple);
8657 friend constexpr difference_type
8658 operator-(default_sentinel_t, const _Iterator& __i)
8659 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8660 { return -(__i - default_sentinel); }
8662 friend constexpr auto
8663 iter_move(const _Iterator& __i)
8664 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8666 friend constexpr void
8667 iter_swap(const _Iterator& __l, const _Iterator& __r)
8668 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8670 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8672 [&]<size_t... _Is>(index_sequence<_Is...>) {
8673 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8674 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8678 template<size_t _Nm = sizeof...(_Vs)>
8682 auto& __it = std::get<_Nm>(_M_current);
8684 if constexpr (_Nm > 0)
8685 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8687 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8692 template<size_t _Nm = sizeof...(_Vs)>
8696 auto& __it = std::get<_Nm>(_M_current);
8697 if constexpr (_Nm > 0)
8698 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8700 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8706 template<size_t _Nm = sizeof...(_Vs)>
8708 _M_advance(difference_type __x)
8709 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8717 // Constant time iterator advancement.
8718 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8719 auto& __it = std::get<_Nm>(_M_current);
8720 if constexpr (_Nm == 0)
8722#ifdef _GLIBCXX_ASSERTIONS
8723 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8725 auto __size = ranges::ssize(__r);
8726 auto __begin = ranges::begin(__r);
8727 auto __offset = __it - __begin;
8728 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8735 auto __size = ranges::ssize(__r);
8736 auto __begin = ranges::begin(__r);
8737 auto __offset = __it - __begin;
8739 __x = __offset / __size;
8743 __offset = __size + __offset;
8746 __it = __begin + __offset;
8747 _M_advance<_Nm - 1>(__x);
8752 template<typename _Tuple>
8753 constexpr difference_type
8754 _M_distance_from(const _Tuple& __t) const
8756 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8757 auto __sum = static_cast<difference_type>(0);
8758#ifdef _GLIBCXX_ASSERTIONS
8759 if constexpr (integral<difference_type>)
8762 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8764 __glibcxx_assert(!__overflow);
8768 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8770 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8773 template<size_t _Nm, typename _Tuple>
8774 constexpr difference_type
8775 _M_scaled_distance(const _Tuple& __t) const
8777 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8778 - std::get<_Nm>(__t));
8779#ifdef _GLIBCXX_ASSERTIONS
8780 if constexpr (integral<difference_type>)
8782 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8783 __glibcxx_assert(!__overflow);
8787 __dist *= _M_scaled_size<_Nm+1>();
8791 template<size_t _Nm>
8792 constexpr difference_type
8793 _M_scaled_size() const
8795 if constexpr (_Nm <= sizeof...(_Vs))
8797 auto __size = static_cast<difference_type>(ranges::size
8798 (std::get<_Nm>(_M_parent->_M_bases)));
8799#ifdef _GLIBCXX_ASSERTIONS
8800 if constexpr (integral<difference_type>)
8802 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8803 __glibcxx_assert(!__overflow);
8807 __size *= _M_scaled_size<_Nm+1>();
8811 return static_cast<difference_type>(1);
8819 template<typename... _Ts>
8820 concept __can_cartesian_product_view
8821 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8824 struct _CartesianProduct
8826 template<typename... _Ts>
8827 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8829 operator() [[nodiscard]] (_Ts&&... __ts) const
8831 if constexpr (sizeof...(_Ts) == 0)
8832 return views::single(tuple{});
8834 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8838 inline constexpr _CartesianProduct cartesian_product;
8840#endif // __cpp_lib_ranges_cartesian_product
8842#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8843 template<input_range _Vp>
8845 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8847 _Vp _M_base = _Vp();
8850 as_rvalue_view() requires default_initializable<_Vp> = default;
8853 as_rvalue_view(_Vp __base)
8854 : _M_base(std::move(__base))
8858 base() const& requires copy_constructible<_Vp>
8863 { return std::move(_M_base); }
8866 begin() requires (!__detail::__simple_view<_Vp>)
8867 { return move_iterator(ranges::begin(_M_base)); }
8870 begin() const requires range<const _Vp>
8871 { return move_iterator(ranges::begin(_M_base)); }
8874 end() requires (!__detail::__simple_view<_Vp>)
8876 if constexpr (common_range<_Vp>)
8877 return move_iterator(ranges::end(_M_base));
8879 return move_sentinel(ranges::end(_M_base));
8883 end() const requires range<const _Vp>
8885 if constexpr (common_range<const _Vp>)
8886 return move_iterator(ranges::end(_M_base));
8888 return move_sentinel(ranges::end(_M_base));
8892 size() requires sized_range<_Vp>
8893 { return ranges::size(_M_base); }
8896 size() const requires sized_range<const _Vp>
8897 { return ranges::size(_M_base); }
8900 template<typename _Range>
8901 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8903 template<typename _Tp>
8904 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8905 = enable_borrowed_range<_Tp>;
8911 template<typename _Tp>
8912 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8915 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8917 template<viewable_range _Range>
8918 requires __detail::__can_as_rvalue_view<_Range>
8920 operator() [[nodiscard]] (_Range&& __r) const
8922 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8923 range_reference_t<_Range>>)
8924 return views::all(std::forward<_Range>(__r));
8926 return as_rvalue_view(std::forward<_Range>(__r));
8930 inline constexpr _AsRvalue as_rvalue;
8932#endif // __cpp_lib_as_rvalue
8934#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8937 template<typename _Range>
8938 concept __range_with_movable_reference = input_range<_Range>
8939 && move_constructible<range_reference_t<_Range>>
8940 && move_constructible<range_rvalue_reference_t<_Range>>;
8944 requires __detail::__range_with_movable_reference<_Vp>
8945 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8947 _Vp _M_base = _Vp();
8949 template<bool _Const> class _Iterator;
8950 template<bool _Const> class _Sentinel;
8953 enumerate_view() requires default_initializable<_Vp> = default;
8956 enumerate_view(_Vp __base)
8957 : _M_base(std::move(__base))
8961 begin() requires (!__detail::__simple_view<_Vp>)
8962 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8965 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8966 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8969 end() requires (!__detail::__simple_view<_Vp>)
8971 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8972 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8974 return _Sentinel<false>(ranges::end(_M_base));
8978 end() const requires __detail::__range_with_movable_reference<const _Vp>
8980 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
8981 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
8983 return _Sentinel<true>(ranges::end(_M_base));
8987 size() requires sized_range<_Vp>
8988 { return ranges::size(_M_base); }
8991 size() const requires sized_range<const _Vp>
8992 { return ranges::size(_M_base); }
8995 base() const & requires copy_constructible<_Vp>
9000 { return std::move(_M_base); }
9003 template<typename _Range>
9004 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9006 template<typename _Tp>
9007 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9008 = enable_borrowed_range<_Tp>;
9011 requires __detail::__range_with_movable_reference<_Vp>
9012 template<bool _Const>
9013 class enumerate_view<_Vp>::_Iterator
9015 using _Base = __maybe_const_t<_Const, _Vp>;
9020 if constexpr (random_access_range<_Base>)
9021 return random_access_iterator_tag{};
9022 else if constexpr (bidirectional_range<_Base>)
9023 return bidirectional_iterator_tag{};
9024 else if constexpr (forward_range<_Base>)
9025 return forward_iterator_tag{};
9027 return input_iterator_tag{};
9030 friend enumerate_view;
9033 using iterator_category = input_iterator_tag;
9034 using iterator_concept = decltype(_S_iter_concept());
9035 using difference_type = range_difference_t<_Base>;
9036 using value_type = tuple<difference_type, range_value_t<_Base>>;
9039 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9041 iterator_t<_Base> _M_current = iterator_t<_Base>();
9042 difference_type _M_pos = 0;
9045 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9046 : _M_current(std::move(__current)), _M_pos(__pos)
9050 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9053 _Iterator(_Iterator<!_Const> __i)
9054 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9055 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9058 constexpr const iterator_t<_Base> &
9059 base() const & noexcept
9060 { return _M_current; }
9062 constexpr iterator_t<_Base>
9064 { return std::move(_M_current); }
9066 constexpr difference_type
9067 index() const noexcept
9072 { return __reference_type(_M_pos, *_M_current); }
9074 constexpr _Iterator&
9087 operator++(int) requires forward_range<_Base>
9094 constexpr _Iterator&
9095 operator--() requires bidirectional_range<_Base>
9103 operator--(int) requires bidirectional_range<_Base>
9110 constexpr _Iterator&
9111 operator+=(difference_type __n) requires random_access_range<_Base>
9118 constexpr _Iterator&
9119 operator-=(difference_type __n) requires random_access_range<_Base>
9127 operator[](difference_type __n) const requires random_access_range<_Base>
9128 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9130 friend constexpr bool
9131 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9132 { return __x._M_pos == __y._M_pos; }
9134 friend constexpr strong_ordering
9135 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9136 { return __x._M_pos <=> __y._M_pos; }
9138 friend constexpr _Iterator
9139 operator+(const _Iterator& __x, difference_type __y)
9140 requires random_access_range<_Base>
9141 { return (auto(__x) += __y); }
9143 friend constexpr _Iterator
9144 operator+(difference_type __x, const _Iterator& __y)
9145 requires random_access_range<_Base>
9146 { return auto(__y) += __x; }
9148 friend constexpr _Iterator
9149 operator-(const _Iterator& __x, difference_type __y)
9150 requires random_access_range<_Base>
9151 { return auto(__x) -= __y; }
9153 friend constexpr difference_type
9154 operator-(const _Iterator& __x, const _Iterator& __y)
9155 { return __x._M_pos - __y._M_pos; }
9157 friend constexpr auto
9158 iter_move(const _Iterator& __i)
9159 noexcept(noexcept(ranges::iter_move(__i._M_current))
9160 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9162 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9163 (__i._M_pos, ranges::iter_move(__i._M_current));
9168 requires __detail::__range_with_movable_reference<_Vp>
9169 template<bool _Const>
9170 class enumerate_view<_Vp>::_Sentinel
9172 using _Base = __maybe_const_t<_Const, _Vp>;
9174 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9177 _Sentinel(sentinel_t<_Base> __end)
9178 : _M_end(std::move(__end))
9181 friend enumerate_view;
9184 _Sentinel() = default;
9187 _Sentinel(_Sentinel<!_Const> __other)
9188 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9189 : _M_end(std::move(__other._M_end))
9192 constexpr sentinel_t<_Base>
9196 template<bool _OtherConst>
9197 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9198 friend constexpr bool
9199 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9200 { return __x._M_current == __y._M_end; }
9202 template<bool _OtherConst>
9203 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9204 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9205 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9206 { return __x._M_current - __y._M_end; }
9208 template<bool _OtherConst>
9209 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9210 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9211 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9212 { return __x._M_end - __y._M_current; }
9219 template<typename _Tp>
9220 concept __can_enumerate_view
9221 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9224 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9226 template<viewable_range _Range>
9227 requires __detail::__can_enumerate_view<_Range>
9229 operator() [[nodiscard]] (_Range&& __r) const
9230 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9233 inline constexpr _Enumerate enumerate;
9235#endif // __cpp_lib_ranges_enumerate
9237#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9239 requires input_range<_Vp>
9240 class as_const_view : public view_interface<as_const_view<_Vp>>
9242 _Vp _M_base = _Vp();
9245 as_const_view() requires default_initializable<_Vp> = default;
9248 as_const_view(_Vp __base)
9249 noexcept(is_nothrow_move_constructible_v<_Vp>)
9250 : _M_base(std::move(__base))
9255 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9256 requires copy_constructible<_Vp>
9261 noexcept(is_nothrow_move_constructible_v<_Vp>)
9262 { return std::move(_M_base); }
9265 begin() requires (!__detail::__simple_view<_Vp>)
9266 { return ranges::cbegin(_M_base); }
9269 begin() const requires range<const _Vp>
9270 { return ranges::cbegin(_M_base); }
9273 end() requires (!__detail::__simple_view<_Vp>)
9274 { return ranges::cend(_M_base); }
9277 end() const requires range<const _Vp>
9278 { return ranges::cend(_M_base); }
9281 size() requires sized_range<_Vp>
9282 { return ranges::size(_M_base); }
9285 size() const requires sized_range<const _Vp>
9286 { return ranges::size(_M_base); }
9289 template<typename _Range>
9290 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9292 template<typename _Tp>
9293 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9294 = enable_borrowed_range<_Tp>;
9300 template<typename _Tp>
9301 inline constexpr bool __is_constable_ref_view = false;
9303 template<typename _Range>
9304 inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
9305 = constant_range<const _Range>;
9307 template<typename _Range>
9308 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9311 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9313 template<viewable_range _Range>
9315 operator()(_Range&& __r) const
9316 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9317 requires __detail::__can_as_const_view<_Range>
9319 using _Tp = remove_cvref_t<_Range>;
9320 using element_type = remove_reference_t<range_reference_t<_Range>>;
9321 if constexpr (constant_range<views::all_t<_Range>>)
9322 return views::all(std::forward<_Range>(__r));
9323 else if constexpr (__detail::__is_empty_view<_Tp>)
9324 return views::empty<const element_type>;
9325 else if constexpr (std::__detail::__is_span<_Tp>)
9326 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9327 else if constexpr (__detail::__is_constable_ref_view<_Tp>)
9328 return ref_view(std::as_const(std::forward<_Range>(__r).base()));
9329 else if constexpr (is_lvalue_reference_v<_Range>
9330 && constant_range<const _Tp>
9332 return ref_view(static_cast<const _Tp&>(__r));
9334 return as_const_view(std::forward<_Range>(__r));
9338 inline constexpr _AsConst as_const;
9340#endif // __cpp_lib_as_const
9341} // namespace ranges
9343 namespace views = ranges::views;
9345#if __cpp_lib_ranges_to_container // C++ >= 23
9348/// @cond undocumented
9351 template<typename _Container>
9352 constexpr bool __reservable_container
9353 = sized_range<_Container>
9354 && requires(_Container& __c, range_size_t<_Container> __n) {
9356 { __c.capacity() } -> same_as<decltype(__n)>;
9357 { __c.max_size() } -> same_as<decltype(__n)>;
9360 template<typename _Cont, typename _Range>
9361 constexpr bool __toable = requires {
9362 requires (!input_range<_Cont>
9363 || convertible_to<range_reference_t<_Range>,
9364 range_value_t<_Cont>>);
9366} // namespace __detail
9369 /// Convert a range to a container.
9371 * @tparam _Cont A container type.
9372 * @param __r A range that models the `input_range` concept.
9373 * @param __args... Arguments to pass to the container constructor.
9376 * This function converts a range to the `_Cont` type.
9378 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9379 * will convert the view to `std::vector<int>`.
9381 * Additional constructor arguments for the container can be supplied after
9382 * the input range argument, e.g.
9383 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9385 template<typename _Cont, input_range _Rg, typename... _Args>
9386 requires (!view<_Cont>)
9388 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9390 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9391 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9393 if constexpr (__detail::__toable<_Cont, _Rg>)
9395 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9396 return _Cont(std::forward<_Rg>(__r),
9397 std::forward<_Args>(__args)...);
9398 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9399 return _Cont(from_range, std::forward<_Rg>(__r),
9400 std::forward<_Args>(__args)...);
9401 else if constexpr (requires { requires common_range<_Rg>;
9402 typename __iter_category_t<iterator_t<_Rg>>;
9403 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9404 input_iterator_tag>;
9405 requires constructible_from<_Cont, iterator_t<_Rg>,
9406 sentinel_t<_Rg>, _Args...>;
9408 return _Cont(ranges::begin(__r), ranges::end(__r),
9409 std::forward<_Args>(__args)...);
9412 static_assert(constructible_from<_Cont, _Args...>);
9413 _Cont __c(std::forward<_Args>(__args)...);
9414 if constexpr (sized_range<_Rg>
9415 && __detail::__reservable_container<_Cont>)
9416 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9417 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9418 // 4016. container-insertable checks do not match what
9419 // container-inserter does
9420 auto __it = ranges::begin(__r);
9421 const auto __sent = ranges::end(__r);
9422 while (__it != __sent)
9424 if constexpr (requires { __c.emplace_back(*__it); })
9425 __c.emplace_back(*__it);
9426 else if constexpr (requires { __c.push_back(*__it); })
9427 __c.push_back(*__it);
9428 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9429 __c.emplace(__c.end(), *__it);
9431 __c.insert(__c.end(), *__it);
9439 static_assert(input_range<range_reference_t<_Rg>>);
9440 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9441 // 3984. ranges::to's recursion branch may be ill-formed
9442 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9443 []<typename _Elt>(_Elt&& __elem) {
9444 using _ValT = range_value_t<_Cont>;
9445 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9446 }), std::forward<_Args>(__args)...);
9450/// @cond undocumented
9453 template<typename _Rg>
9456 using iterator_category = input_iterator_tag;
9457 using value_type = range_value_t<_Rg>;
9458 using difference_type = ptrdiff_t;
9459 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9460 using reference = range_reference_t<_Rg>;
9461 reference operator*() const;
9462 pointer operator->() const;
9463 _InputIter& operator++();
9464 _InputIter operator++(int);
9465 bool operator==(const _InputIter&) const;
9468 template<template<typename...> typename _Cont, input_range _Rg,
9471 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9473 template<template<typename...> typename _Cont, input_range _Rg,
9476 = decltype(_Cont(from_range, std::declval<_Rg>(),
9477 std::declval<_Args>()...));
9479 template<template<typename...> typename _Cont, input_range _Rg,
9482 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9483 std::declval<_InputIter<_Rg>>(),
9484 std::declval<_Args>()...));
9486} // namespace __detail
9489 template<template<typename...> typename _Cont, input_range _Rg,
9492 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9494 using __detail::_DeduceExpr1;
9495 using __detail::_DeduceExpr2;
9496 using __detail::_DeduceExpr3;
9497 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9498 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9499 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9500 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9501 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9502 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9503 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9504 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9505 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9507 static_assert(false); // Cannot deduce container specialization.
9510/// @cond undocumented
9513 template<typename _Cont>
9516 template<typename _Range, typename... _Args>
9517 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9518 std::declval<_Args>()...); }
9520 operator()(_Range&& __r, _Args&&... __args) const
9522 return ranges::to<_Cont>(std::forward<_Range>(__r),
9523 std::forward<_Args>(__args)...);
9526} // namespace __detail
9529 /// ranges::to adaptor for converting a range to a container type
9531 * @tparam _Cont A container type.
9532 * @param __args... Arguments to pass to the container constructor.
9535 * This range adaptor returns a range adaptor closure object that converts
9536 * a range to the `_Cont` type.
9538 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9539 * will convert the view to `std::vector<int>`.
9541 * Additional constructor arguments for the container can be supplied, e.g.
9542 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9544 template<typename _Cont, typename... _Args>
9545 requires (!view<_Cont>)
9547 to [[nodiscard]] (_Args&&... __args)
9549 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9550 static_assert(is_class_v<_Cont> || is_union_v<_Cont>);
9552 using __detail::_To;
9553 using views::__adaptor::_Partial;
9554 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9557/// @cond undocumented
9560 template<template<typename...> typename _Cont>
9563 template<typename _Range, typename... _Args>
9564 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9565 std::declval<_Args>()...); }
9567 operator()(_Range&& __r, _Args&&... __args) const
9569 return ranges::to<_Cont>(std::forward<_Range>(__r),
9570 std::forward<_Args>(__args)...);
9573} // namespace __detail
9576 /// ranges::to adaptor for converting a range to a deduced container type.
9578 * @tparam _Cont A container template.
9579 * @param __args... Arguments to pass to the container constructor.
9582 * This range adaptor returns a range adaptor closure object that converts
9583 * a range to a specialization of the `_Cont` class template. The specific
9584 * specialization of `_Cont` to be used is deduced automatically.
9586 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9587 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9588 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9590 * Additional constructor arguments for the container can be supplied, e.g.
9591 * `r | std::ranges::to<std::vector>(an_allocator)`.
9593 template<template<typename...> typename _Cont, typename... _Args>
9595 to [[nodiscard]] (_Args&&... __args)
9597 using __detail::_To2;
9598 using views::__adaptor::_Partial;
9599 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9602} // namespace ranges
9603#endif // __cpp_lib_ranges_to_container
9605_GLIBCXX_END_NAMESPACE_VERSION
9607#endif // library concepts
9609#endif /* _GLIBCXX_RANGES */