3// Copyright (C) 2019-2025 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
36#pragma GCC system_header
44#include <initializer_list>
50#if __cplusplus > 202002L
53#include <bits/ranges_util.h>
54#include <bits/refwrap.h>
56#define __glibcxx_want_algorithm_default_value_type
57#define __glibcxx_want_ranges
58#define __glibcxx_want_ranges_as_const
59#define __glibcxx_want_ranges_as_rvalue
60#define __glibcxx_want_ranges_cartesian_product
61#define __glibcxx_want_ranges_concat
62#define __glibcxx_want_ranges_chunk
63#define __glibcxx_want_ranges_chunk_by
64#define __glibcxx_want_ranges_enumerate
65#define __glibcxx_want_ranges_iota
66#define __glibcxx_want_ranges_join_with
67#define __glibcxx_want_ranges_repeat
68#define __glibcxx_want_ranges_slide
69#define __glibcxx_want_ranges_stride
70#define __glibcxx_want_ranges_to_container
71#define __glibcxx_want_ranges_zip
72#include <bits/version.h>
74#ifdef __glibcxx_generator // C++ >= 23 && __glibcxx_coroutine
75# include <bits/elements_of.h>
79 * @defgroup ranges Ranges
81 * Components for dealing with ranges of elements.
84namespace std _GLIBCXX_VISIBILITY(default)
86_GLIBCXX_BEGIN_NAMESPACE_VERSION
89 // [range.access] customization point objects
90 // [range.req] range and view concepts
91 // [range.dangling] dangling iterator handling
92 // Defined in <bits/ranges_base.h>
94 // [view.interface] View interface
95 // [range.subrange] Sub-ranges
96 // Defined in <bits/ranges_util.h>
98 // C++20 24.6 [range.factories] Range factories
100 /// A view that contains no elements.
101 template<typename _Tp> requires is_object_v<_Tp>
103 : public view_interface<empty_view<_Tp>>
106 static constexpr _Tp* begin() noexcept { return nullptr; }
107 static constexpr _Tp* end() noexcept { return nullptr; }
108 static constexpr _Tp* data() noexcept { return nullptr; }
109 static constexpr size_t size() noexcept { return 0; }
110 static constexpr bool empty() noexcept { return true; }
113 template<typename _Tp>
114 inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
118#if __cpp_lib_ranges >= 202207L // C++ >= 23
119 // P2494R2 Relaxing range adaptors to allow for move only types
120 template<typename _Tp>
121 concept __boxable = move_constructible<_Tp> && is_object_v<_Tp>;
123 template<typename _Tp>
124 concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;
127 template<__boxable _Tp>
128 struct __box : std::optional<_Tp>
130 using std::optional<_Tp>::optional;
134 noexcept(is_nothrow_default_constructible_v<_Tp>)
135 requires default_initializable<_Tp>
136 : std::optional<_Tp>{std::in_place}
139 __box(const __box&) = default;
140 __box(__box&&) = default;
142 using std::optional<_Tp>::operator=;
144 // _GLIBCXX_RESOLVE_LIB_DEFECTS
145 // 3477. Simplify constraints for semiregular-box
146 // 3572. copyable-box should be fully constexpr
148 operator=(const __box& __that)
149 noexcept(is_nothrow_copy_constructible_v<_Tp>)
150 requires (!copyable<_Tp>) && copy_constructible<_Tp>
152 if (this != std::__addressof(__that))
155 this->emplace(*__that);
163 operator=(__box&& __that)
164 noexcept(is_nothrow_move_constructible_v<_Tp>)
165 requires (!movable<_Tp>)
167 if (this != std::__addressof(__that))
170 this->emplace(std::move(*__that));
178 template<typename _Tp>
179 concept __boxable_copyable
180 = copy_constructible<_Tp>
181 && (copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
182 && is_nothrow_copy_constructible_v<_Tp>));
183 template<typename _Tp>
184 concept __boxable_movable
185 = (!copy_constructible<_Tp>)
186 && (movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
188 // For types which are already copyable (or since C++23, movable)
189 // this specialization of the box wrapper stores the object directly
190 // without going through std::optional. It provides just the subset of
191 // the primary template's API that we currently use.
192 template<__boxable _Tp>
193 requires __boxable_copyable<_Tp> || __boxable_movable<_Tp>
197 [[no_unique_address]] _Tp _M_value = _Tp();
200 __box() requires default_initializable<_Tp> = default;
203 __box(const _Tp& __t)
204 noexcept(is_nothrow_copy_constructible_v<_Tp>)
205 requires copy_constructible<_Tp>
211 noexcept(is_nothrow_move_constructible_v<_Tp>)
212 : _M_value(std::move(__t))
215 template<typename... _Args>
216 requires constructible_from<_Tp, _Args...>
218 __box(in_place_t, _Args&&... __args)
219 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
220 : _M_value(std::forward<_Args>(__args)...)
223 __box(const __box&) = default;
224 __box(__box&&) = default;
225 __box& operator=(const __box&) requires copyable<_Tp> = default;
226 __box& operator=(__box&&) requires movable<_Tp> = default;
228 // When _Tp is nothrow_copy_constructible but not copy_assignable,
229 // copy assignment is implemented via destroy-then-copy-construct.
231 operator=(const __box& __that) noexcept
232 requires (!copyable<_Tp>) && copy_constructible<_Tp>
234 static_assert(is_nothrow_copy_constructible_v<_Tp>);
235 if (this != std::__addressof(__that))
238 std::construct_at(std::__addressof(_M_value), *__that);
243 // Likewise for move assignment.
245 operator=(__box&& __that) noexcept
246 requires (!movable<_Tp>)
248 static_assert(is_nothrow_move_constructible_v<_Tp>);
249 if (this != std::__addressof(__that))
252 std::construct_at(std::__addressof(_M_value), std::move(*__that));
258 has_value() const noexcept
262 operator*() & noexcept
266 operator*() const & noexcept
270 operator*() && noexcept
271 { return std::move(_M_value); }
273 constexpr const _Tp&&
274 operator*() const && noexcept
275 { return std::move(_M_value); }
278 operator->() noexcept
279 { return std::__addressof(_M_value); }
282 operator->() const noexcept
283 { return std::__addressof(_M_value); }
285 } // namespace __detail
287 /// A view that contains exactly one element.
288#if __cpp_lib_ranges >= 202207L // C++ >= 23
289 template<move_constructible _Tp>
291 template<copy_constructible _Tp>
293 requires is_object_v<_Tp>
294 class single_view : public view_interface<single_view<_Tp>>
297 single_view() requires default_initializable<_Tp> = default;
300 single_view(const _Tp& __t)
301 noexcept(is_nothrow_copy_constructible_v<_Tp>)
302 requires copy_constructible<_Tp>
307 single_view(_Tp&& __t)
308 noexcept(is_nothrow_move_constructible_v<_Tp>)
309 : _M_value(std::move(__t))
312 // _GLIBCXX_RESOLVE_LIB_DEFECTS
313 // 3428. single_view's in place constructor should be explicit
314 template<typename... _Args>
315 requires constructible_from<_Tp, _Args...>
317 single_view(in_place_t, _Args&&... __args)
318 noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
319 : _M_value{in_place, std::forward<_Args>(__args)...}
327 begin() const noexcept
332 { return data() + 1; }
336 { return data() + 1; }
338 // _GLIBCXX_RESOLVE_LIB_DEFECTS
339 // 4035. single_view should provide empty
340 static constexpr bool
344 static constexpr size_t
350 { return _M_value.operator->(); }
353 data() const noexcept
354 { return _M_value.operator->(); }
357 [[no_unique_address]] __detail::__box<_Tp> _M_value;
360 template<typename _Tp>
361 single_view(_Tp) -> single_view<_Tp>;
365 template<typename _Wp>
366 constexpr auto __to_signed_like(_Wp __w) noexcept
368 if constexpr (!integral<_Wp>)
369 return iter_difference_t<_Wp>();
370 else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
371 return iter_difference_t<_Wp>(__w);
372 else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
373 return ptrdiff_t(__w);
374 else if constexpr (sizeof(long long) > sizeof(_Wp))
375 return (long long)(__w);
376#ifdef __SIZEOF_INT128__
377 else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
378 return __int128(__w);
381 return __max_diff_type(__w);
384 template<typename _Wp>
385 using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));
387 template<typename _It>
388 concept __decrementable = incrementable<_It>
391 { --__i } -> same_as<_It&>;
392 { __i-- } -> same_as<_It>;
395 template<typename _It>
396 concept __advanceable = __decrementable<_It> && totally_ordered<_It>
397 && requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
399 { __i += __n } -> same_as<_It&>;
400 { __i -= __n } -> same_as<_It&>;
404 { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
407 template<typename _Winc>
408 struct __iota_view_iter_cat
411 template<incrementable _Winc>
412 struct __iota_view_iter_cat<_Winc>
413 { using iterator_category = input_iterator_tag; };
414 } // namespace __detail
416 template<weakly_incrementable _Winc,
417 semiregular _Bound = unreachable_sentinel_t>
418 requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
420 class iota_view : public view_interface<iota_view<_Winc, _Bound>>
425 struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
431 using namespace __detail;
432 if constexpr (__advanceable<_Winc>)
433 return random_access_iterator_tag{};
434 else if constexpr (__decrementable<_Winc>)
435 return bidirectional_iterator_tag{};
436 else if constexpr (incrementable<_Winc>)
437 return forward_iterator_tag{};
439 return input_iterator_tag{};
443 using iterator_concept = decltype(_S_iter_concept());
444 // iterator_category defined in __iota_view_iter_cat
445 using value_type = _Winc;
446 using difference_type = __detail::__iota_diff_t<_Winc>;
448 _Iterator() requires default_initializable<_Winc> = default;
451 _Iterator(_Winc __value)
452 : _M_value(__value) { }
455 operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
470 operator++(int) requires incrementable<_Winc>
478 operator--() requires __detail::__decrementable<_Winc>
485 operator--(int) requires __detail::__decrementable<_Winc>
493 operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
495 using __detail::__is_integer_like;
496 using __detail::__is_signed_integer_like;
497 if constexpr (__is_integer_like<_Winc>
498 && !__is_signed_integer_like<_Winc>)
500 if (__n >= difference_type(0))
501 _M_value += static_cast<_Winc>(__n);
503 _M_value -= static_cast<_Winc>(-__n);
511 operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
513 using __detail::__is_integer_like;
514 using __detail::__is_signed_integer_like;
515 if constexpr (__is_integer_like<_Winc>
516 && !__is_signed_integer_like<_Winc>)
518 if (__n >= difference_type(0))
519 _M_value -= static_cast<_Winc>(__n);
521 _M_value += static_cast<_Winc>(-__n);
529 operator[](difference_type __n) const
530 requires __detail::__advanceable<_Winc>
531 { return _Winc(_M_value + __n); }
533 friend constexpr bool
534 operator==(const _Iterator& __x, const _Iterator& __y)
535 requires equality_comparable<_Winc>
536 { return __x._M_value == __y._M_value; }
538 friend constexpr bool
539 operator<(const _Iterator& __x, const _Iterator& __y)
540 requires totally_ordered<_Winc>
541 { return __x._M_value < __y._M_value; }
543 friend constexpr bool
544 operator>(const _Iterator& __x, const _Iterator& __y)
545 requires totally_ordered<_Winc>
546 { return __y < __x; }
548 friend constexpr bool
549 operator<=(const _Iterator& __x, const _Iterator& __y)
550 requires totally_ordered<_Winc>
551 { return !(__y < __x); }
553 friend constexpr bool
554 operator>=(const _Iterator& __x, const _Iterator& __y)
555 requires totally_ordered<_Winc>
556 { return !(__x < __y); }
558#ifdef __cpp_lib_three_way_comparison
559 friend constexpr auto
560 operator<=>(const _Iterator& __x, const _Iterator& __y)
561 requires totally_ordered<_Winc> && three_way_comparable<_Winc>
562 { return __x._M_value <=> __y._M_value; }
565 friend constexpr _Iterator
566 operator+(_Iterator __i, difference_type __n)
567 requires __detail::__advanceable<_Winc>
573 friend constexpr _Iterator
574 operator+(difference_type __n, _Iterator __i)
575 requires __detail::__advanceable<_Winc>
576 { return __i += __n; }
578 friend constexpr _Iterator
579 operator-(_Iterator __i, difference_type __n)
580 requires __detail::__advanceable<_Winc>
586 friend constexpr difference_type
587 operator-(const _Iterator& __x, const _Iterator& __y)
588 requires __detail::__advanceable<_Winc>
590 using __detail::__is_integer_like;
591 using __detail::__is_signed_integer_like;
592 using _Dt = difference_type;
593 if constexpr (__is_integer_like<_Winc>)
595 if constexpr (__is_signed_integer_like<_Winc>)
596 return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
598 return (__y._M_value > __x._M_value)
599 ? _Dt(-_Dt(__y._M_value - __x._M_value))
600 : _Dt(__x._M_value - __y._M_value);
603 return __x._M_value - __y._M_value;
607 _Winc _M_value = _Winc();
617 _M_equal(const _Iterator& __x) const
618 { return __x._M_value == _M_bound; }
621 _M_distance_from(const _Iterator& __x) const
622 { return _M_bound - __x._M_value; }
624 _Bound _M_bound = _Bound();
627 _Sentinel() = default;
630 _Sentinel(_Bound __bound)
631 : _M_bound(__bound) { }
633 friend constexpr bool
634 operator==(const _Iterator& __x, const _Sentinel& __y)
635 { return __y._M_equal(__x); }
637 friend constexpr iter_difference_t<_Winc>
638 operator-(const _Iterator& __x, const _Sentinel& __y)
639 requires sized_sentinel_for<_Bound, _Winc>
640 { return -__y._M_distance_from(__x); }
642 friend constexpr iter_difference_t<_Winc>
643 operator-(const _Sentinel& __x, const _Iterator& __y)
644 requires sized_sentinel_for<_Bound, _Winc>
645 { return __x._M_distance_from(__y); }
650 _Winc _M_value = _Winc();
651 [[no_unique_address]] _Bound _M_bound = _Bound();
654 iota_view() requires default_initializable<_Winc> = default;
657 iota_view(_Winc __value)
662 iota_view(type_identity_t<_Winc> __value,
663 type_identity_t<_Bound> __bound)
664 : _M_value(__value), _M_bound(__bound)
666 if constexpr (totally_ordered_with<_Winc, _Bound>)
667 __glibcxx_assert( bool(__value <= __bound) );
671 iota_view(_Iterator __first, _Iterator __last)
672 requires same_as<_Winc, _Bound>
673 : iota_view(__first._M_value, __last._M_value)
677 iota_view(_Iterator __first, unreachable_sentinel_t __last)
678 requires same_as<_Bound, unreachable_sentinel_t>
679 : iota_view(__first._M_value, __last)
683 iota_view(_Iterator __first, _Sentinel __last)
684 requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
685 : iota_view(__first._M_value, __last._M_bound)
689 begin() const { return _Iterator{_M_value}; }
694 if constexpr (same_as<_Bound, unreachable_sentinel_t>)
695 return unreachable_sentinel;
697 return _Sentinel{_M_bound};
701 end() const requires same_as<_Winc, _Bound>
702 { return _Iterator{_M_bound}; }
704 // _GLIBCXX_RESOLVE_LIB_DEFECTS
705 // 4001. iota_view should provide empty
708 { return _M_value == _M_bound; }
712 requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
713 || (integral<_Winc> && integral<_Bound>)
714 || sized_sentinel_for<_Bound, _Winc>
716 using __detail::__is_integer_like;
717 using __detail::__to_unsigned_like;
718 if constexpr (integral<_Winc> && integral<_Bound>)
720 using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
721 return _Up(_M_bound) - _Up(_M_value);
723 else if constexpr (__is_integer_like<_Winc>)
724 return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
726 return __to_unsigned_like(_M_bound - _M_value);
730 template<typename _Winc, typename _Bound>
731 requires (!__detail::__is_integer_like<_Winc>
732 || !__detail::__is_integer_like<_Bound>
733 || (__detail::__is_signed_integer_like<_Winc>
734 == __detail::__is_signed_integer_like<_Bound>))
735 iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
737 template<typename _Winc, typename _Bound>
738 inline constexpr bool
739 enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
743 template<typename _Tp>
744 inline constexpr empty_view<_Tp> empty{};
748 template<typename _Tp>
749 concept __can_single_view
750 = requires { single_view<decay_t<_Tp>>(std::declval<_Tp>()); };
751 } // namespace __detail
755 template<__detail::__can_single_view _Tp>
757 operator() [[nodiscard]] (_Tp&& __e) const
758 noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
759 { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
762 inline constexpr _Single single{};
766 template<typename... _Args>
767 concept __can_iota_view = requires { iota_view(std::declval<_Args>()...); };
768 } // namespace __detail
772 template<__detail::__can_iota_view _Tp>
774 operator() [[nodiscard]] (_Tp&& __e) const
775 { return iota_view(std::forward<_Tp>(__e)); }
777 template<typename _Tp, typename _Up>
778 requires __detail::__can_iota_view<_Tp, _Up>
780 operator() [[nodiscard]] (_Tp&& __e, _Up&& __f) const
781 { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
784 inline constexpr _Iota iota{};
790 template<typename _Val, typename _CharT, typename _Traits>
791 concept __stream_extractable
792 = requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
793 } // namespace __detail
795 template<movable _Val, typename _CharT,
796 typename _Traits = char_traits<_CharT>>
797 requires default_initializable<_Val>
798 && __detail::__stream_extractable<_Val, _CharT, _Traits>
799 class basic_istream_view
800 : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
804 basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
805 : _M_stream(std::__addressof(__stream))
811 *_M_stream >> _M_object;
812 return _Iterator{this};
815 constexpr default_sentinel_t
817 { return default_sentinel; }
820 basic_istream<_CharT, _Traits>* _M_stream;
821 _Val _M_object = _Val();
826 using iterator_concept = input_iterator_tag;
827 using difference_type = ptrdiff_t;
828 using value_type = _Val;
831 _Iterator(basic_istream_view* __parent) noexcept
832 : _M_parent(__parent)
835 _Iterator(const _Iterator&) = delete;
836 _Iterator(_Iterator&&) = default;
837 _Iterator& operator=(const _Iterator&) = delete;
838 _Iterator& operator=(_Iterator&&) = default;
843 *_M_parent->_M_stream >> _M_parent->_M_object;
853 { return _M_parent->_M_object; }
856 operator==(const _Iterator& __x, default_sentinel_t)
857 { return __x._M_at_end(); }
860 basic_istream_view* _M_parent;
864 { return !*_M_parent->_M_stream; }
870 template<typename _Val>
871 using istream_view = basic_istream_view<_Val, char>;
873 template<typename _Val>
874 using wistream_view = basic_istream_view<_Val, wchar_t>;
880 template<typename _Tp, typename _Up>
881 concept __can_istream_view = requires (_Up __e) {
882 basic_istream_view<_Tp, typename _Up::char_type, typename _Up::traits_type>(__e);
884 } // namespace __detail
886 template<typename _Tp>
889 template<typename _CharT, typename _Traits>
891 operator() [[nodiscard]] (basic_istream<_CharT, _Traits>& __e) const
892 requires __detail::__can_istream_view<_Tp, remove_reference_t<decltype(__e)>>
893 { return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
896 template<typename _Tp>
897 inline constexpr _Istream<_Tp> istream;
901 // C++20 24.7 [range.adaptors] Range adaptors
905 template<typename _Tp, int _Disc>
908 // Alias for a type that is conditionally present
909 // (and is an empty type otherwise).
910 // Data members using this alias should use [[no_unique_address]] so that
911 // they take no space when not needed.
912 // The optional template parameter _Disc is for discriminating two otherwise
913 // equivalent absent types so that even they can overlap.
914 template<bool _Present, typename _Tp, int _Disc = 0>
915 using __maybe_present_t = __conditional_t<_Present, _Tp, _Absent<_Tp, _Disc>>;
917 // Alias for a type that is conditionally const.
918 template<bool _Const, typename _Tp>
919 using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;
921} // namespace __detail
923// Shorthand for __detail::__maybe_const_t.
924using __detail::__maybe_const_t;
926namespace views::__adaptor
928 // True if the range adaptor _Adaptor can be applied with _Args.
929 template<typename _Adaptor, typename... _Args>
930 concept __adaptor_invocable
931 = requires { std::declval<_Adaptor>()(declval<_Args>()...); };
933 // True if the range adaptor non-closure _Adaptor can be partially applied
935 template<typename _Adaptor, typename... _Args>
936 concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
937 && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
938 && (constructible_from<decay_t<_Args>, _Args> && ...);
940 template<typename _Adaptor, typename... _Args>
943 template<typename _Lhs, typename _Rhs>
946 // The base class of every range adaptor closure.
948 // The derived class should define the optional static data member
949 // _S_has_simple_call_op to true if the behavior of this adaptor is
950 // independent of the constness/value category of the adaptor object.
951 template<typename _Derived>
952 struct _RangeAdaptorClosure;
954 template<typename _Tp, typename _Up>
955 requires (!same_as<_Tp, _RangeAdaptorClosure<_Up>>)
956 void __is_range_adaptor_closure_fn
957 (const _Tp&, const _RangeAdaptorClosure<_Up>&); // not defined
959 template<typename _Tp>
960 concept __is_range_adaptor_closure
961 = requires (_Tp __t) { __adaptor::__is_range_adaptor_closure_fn(__t, __t); };
963#pragma GCC diagnostic push
964#pragma GCC diagnostic ignored "-Wdangling-reference"
965 // range | adaptor is equivalent to adaptor(range).
966 template<typename _Self, typename _Range>
967 requires __is_range_adaptor_closure<_Self>
968 && __adaptor_invocable<_Self, _Range>
970 operator|(_Range&& __r, _Self&& __self)
971 { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }
973 // Compose the adaptors __lhs and __rhs into a pipeline, returning
974 // another range adaptor closure object.
975 template<typename _Lhs, typename _Rhs>
976 requires __is_range_adaptor_closure<_Lhs>
977 && __is_range_adaptor_closure<_Rhs>
979 operator|(_Lhs&& __lhs, _Rhs&& __rhs)
981 return _Pipe<decay_t<_Lhs>, decay_t<_Rhs>>{std::forward<_Lhs>(__lhs),
982 std::forward<_Rhs>(__rhs)};
984#pragma GCC diagnostic pop
986 template<typename _Derived>
987 struct _RangeAdaptorClosure
989 // In non-modules compilation ADL finds these operators either way and
990 // the friend declarations are redundant. But with the std module these
991 // friend declarations enable ADL to find these operators without having
993 template<typename _Self, typename _Range>
994 requires __is_range_adaptor_closure<_Self>
995 && __adaptor_invocable<_Self, _Range>
996 friend constexpr auto
997 operator|(_Range&& __r, _Self&& __self);
999 template<typename _Lhs, typename _Rhs>
1000 requires __is_range_adaptor_closure<_Lhs>
1001 && __is_range_adaptor_closure<_Rhs>
1002 friend constexpr auto
1003 operator|(_Lhs&& __lhs, _Rhs&& __rhs);
1006 // The base class of every range adaptor non-closure.
1008 // The static data member _Derived::_S_arity must contain the total number of
1009 // arguments that the adaptor takes, and the class _Derived must introduce
1010 // _RangeAdaptor::operator() into the class scope via a using-declaration.
1012 // The optional static data member _Derived::_S_has_simple_extra_args should
1013 // be defined to true if the behavior of this adaptor is independent of the
1014 // constness/value category of the extra arguments. This data member could
1015 // also be defined as a variable template parameterized by the types of the
1017 template<typename _Derived>
1018 struct _RangeAdaptor
1020 // Partially apply the arguments __args to the range adaptor _Derived,
1021 // returning a range adaptor closure object.
1022 template<typename... _Args>
1023 requires __adaptor_partial_app_viable<_Derived, _Args...>
1025 operator()(_Args&&... __args) const
1027 return _Partial<_Derived, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
1031 // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
1032 // one that's not overloaded according to constness or value category of the
1034 template<typename _Adaptor>
1035 concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;
1037 // True if the behavior of the range adaptor non-closure _Adaptor is
1038 // independent of the value category of its extra arguments _Args.
1039 template<typename _Adaptor, typename... _Args>
1040 concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
1041 || _Adaptor::template _S_has_simple_extra_args<_Args...>;
1043 // A range adaptor closure that represents partial application of
1044 // the range adaptor _Adaptor with arguments _Args.
1045 template<typename _Adaptor, typename... _Args>
1046 struct _Partial : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1048 tuple<_Args...> _M_args;
1050 // First parameter is to ensure this constructor is never used
1051 // instead of the copy/move constructor.
1052 template<typename... _Ts>
1054 _Partial(int, _Ts&&... __args)
1055 : _M_args(std::forward<_Ts>(__args)...)
1058 // Invoke _Adaptor with arguments __r, _M_args... according to the
1059 // value category of this _Partial object.
1060#if __cpp_explicit_this_parameter
1061 template<typename _Self, typename _Range>
1062 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Args>...>
1064 operator()(this _Self&& __self, _Range&& __r)
1066 auto __forwarder = [&__r] (auto&&... __args) {
1067 return _Adaptor{}(std::forward<_Range>(__r),
1068 std::forward<decltype(__args)>(__args)...);
1070 return std::apply(__forwarder, __like_t<_Self, _Partial>(__self)._M_args);
1073 template<typename _Range>
1074 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1076 operator()(_Range&& __r) const &
1078 auto __forwarder = [&__r] (const auto&... __args) {
1079 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1081 return std::apply(__forwarder, _M_args);
1084 template<typename _Range>
1085 requires __adaptor_invocable<_Adaptor, _Range, _Args...>
1087 operator()(_Range&& __r) &&
1089 auto __forwarder = [&__r] (auto&... __args) {
1090 return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
1092 return std::apply(__forwarder, _M_args);
1095 template<typename _Range>
1097 operator()(_Range&& __r) const && = delete;
1101 // A lightweight specialization of the above primary template for
1102 // the common case where _Adaptor accepts a single extra argument.
1103 template<typename _Adaptor, typename _Arg>
1104 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1108 template<typename _Tp>
1110 _Partial(int, _Tp&& __arg)
1111 : _M_arg(std::forward<_Tp>(__arg))
1114#if __cpp_explicit_this_parameter
1115 template<typename _Self, typename _Range>
1116 requires __adaptor_invocable<_Adaptor, _Range, __like_t<_Self, _Arg>>
1118 operator()(this _Self&& __self, _Range&& __r)
1120 return _Adaptor{}(std::forward<_Range>(__r),
1121 __like_t<_Self, _Partial>(__self)._M_arg);
1124 template<typename _Range>
1125 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1127 operator()(_Range&& __r) const &
1128 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1130 template<typename _Range>
1131 requires __adaptor_invocable<_Adaptor, _Range, _Arg>
1133 operator()(_Range&& __r) &&
1134 { return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }
1136 template<typename _Range>
1138 operator()(_Range&& __r) const && = delete;
1142 // Partial specialization of the primary template for the case where the extra
1143 // arguments of the adaptor can always be safely and efficiently forwarded by
1144 // const reference. This lets us get away with a single operator() overload,
1145 // which makes overload resolution failure diagnostics more concise.
1146 template<typename _Adaptor, typename... _Args>
1147 requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
1148 && (is_trivially_copy_constructible_v<_Args> && ...)
1149 struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure<_Partial<_Adaptor, _Args...>>
1151 tuple<_Args...> _M_args;
1153 template<typename... _Ts>
1155 _Partial(int, _Ts&&... __args)
1156 : _M_args(std::forward<_Ts>(__args)...)
1159 // Invoke _Adaptor with arguments __r, const _M_args&... regardless
1160 // of the value category of this _Partial object.
1161 template<typename _Range>
1162 requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
1164 operator()(_Range&& __r) const
1166 auto __forwarder = [&__r] (const auto&... __args) {
1167 return _Adaptor{}(std::forward<_Range>(__r), __args...);
1169 return std::apply(__forwarder, _M_args);
1172 static constexpr bool _S_has_simple_call_op = true;
1175 // A lightweight specialization of the above template for the common case
1176 // where _Adaptor accepts a single extra argument.
1177 template<typename _Adaptor, typename _Arg>
1178 requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
1179 && is_trivially_copy_constructible_v<_Arg>
1180 struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure<_Partial<_Adaptor, _Arg>>
1184 template<typename _Tp>
1186 _Partial(int, _Tp&& __arg)
1187 : _M_arg(std::forward<_Tp>(__arg))
1190 template<typename _Range>
1191 requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
1193 operator()(_Range&& __r) const
1194 { return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }
1196 static constexpr bool _S_has_simple_call_op = true;
1199 template<typename _Lhs, typename _Rhs, typename _Range>
1200 concept __pipe_invocable
1201 = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };
1203 // A range adaptor closure that represents composition of the range
1204 // adaptor closures _Lhs and _Rhs.
1205 template<typename _Lhs, typename _Rhs>
1206 struct _Pipe : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1208 [[no_unique_address]] _Lhs _M_lhs;
1209 [[no_unique_address]] _Rhs _M_rhs;
1211 template<typename _Tp, typename _Up>
1213 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1214 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1217 // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
1218 // range adaptor closure object.
1219#if __cpp_explicit_this_parameter
1220 template<typename _Self, typename _Range>
1221 requires __pipe_invocable<__like_t<_Self, _Lhs>, __like_t<_Self, _Rhs>, _Range>
1223 operator()(this _Self&& __self, _Range&& __r)
1225 return (__like_t<_Self, _Pipe>(__self)._M_rhs
1226 (__like_t<_Self, _Pipe>(__self)._M_lhs
1227 (std::forward<_Range>(__r))));
1230 template<typename _Range>
1231 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1233 operator()(_Range&& __r) const &
1234 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1236 template<typename _Range>
1237 requires __pipe_invocable<_Lhs, _Rhs, _Range>
1239 operator()(_Range&& __r) &&
1240 { return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }
1242 template<typename _Range>
1244 operator()(_Range&& __r) const && = delete;
1248 // A partial specialization of the above primary template for the case where
1249 // both adaptor operands have a simple operator(). This in turn lets us
1250 // implement composition using a single simple operator(), which makes
1251 // overload resolution failure diagnostics more concise.
1252 template<typename _Lhs, typename _Rhs>
1253 requires __closure_has_simple_call_op<_Lhs>
1254 && __closure_has_simple_call_op<_Rhs>
1255 struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure<_Pipe<_Lhs, _Rhs>>
1257 [[no_unique_address]] _Lhs _M_lhs;
1258 [[no_unique_address]] _Rhs _M_rhs;
1260 template<typename _Tp, typename _Up>
1262 _Pipe(_Tp&& __lhs, _Up&& __rhs)
1263 : _M_lhs(std::forward<_Tp>(__lhs)), _M_rhs(std::forward<_Up>(__rhs))
1266 template<typename _Range>
1267 requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
1269 operator()(_Range&& __r) const
1270 { return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }
1272 static constexpr bool _S_has_simple_call_op = true;
1274} // namespace views::__adaptor
1276#if __cpp_lib_ranges >= 202202L
1277 // P2387R3 Pipe support for user-defined range adaptors
1278 template<typename _Derived>
1279 requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
1280 class range_adaptor_closure
1281 : public views::__adaptor::_RangeAdaptorClosure<_Derived>
1285 template<range _Range> requires is_object_v<_Range>
1286 class ref_view : public view_interface<ref_view<_Range>>
1291 static void _S_fun(_Range&); // not defined
1292 static void _S_fun(_Range&&) = delete;
1295 template<__detail::__different_from<ref_view> _Tp>
1296 requires convertible_to<_Tp, _Range&>
1297 && requires { _S_fun(declval<_Tp>()); }
1300 noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
1301 : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
1308 constexpr iterator_t<_Range>
1310 { return ranges::begin(*_M_r); }
1312 constexpr sentinel_t<_Range>
1314 { return ranges::end(*_M_r); }
1317 empty() const requires requires { ranges::empty(*_M_r); }
1318 { return ranges::empty(*_M_r); }
1321 size() const requires sized_range<_Range>
1322 { return ranges::size(*_M_r); }
1325 data() const requires contiguous_range<_Range>
1326 { return ranges::data(*_M_r); }
1329 template<typename _Range>
1330 ref_view(_Range&) -> ref_view<_Range>;
1332 template<typename _Tp>
1333 inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
1335 template<range _Range>
1336 requires movable<_Range>
1337 && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
1338 class owning_view : public view_interface<owning_view<_Range>>
1341 _Range _M_r = _Range();
1344 owning_view() requires default_initializable<_Range> = default;
1347 owning_view(_Range&& __t)
1348 noexcept(is_nothrow_move_constructible_v<_Range>)
1349 : _M_r(std::move(__t))
1352 owning_view(owning_view&&) = default;
1353 owning_view& operator=(owning_view&&) = default;
1359 constexpr const _Range&
1360 base() const& noexcept
1365 { return std::move(_M_r); }
1367 constexpr const _Range&&
1368 base() const&& noexcept
1369 { return std::move(_M_r); }
1371 constexpr iterator_t<_Range>
1373 { return ranges::begin(_M_r); }
1375 constexpr sentinel_t<_Range>
1377 { return ranges::end(_M_r); }
1380 begin() const requires range<const _Range>
1381 { return ranges::begin(_M_r); }
1384 end() const requires range<const _Range>
1385 { return ranges::end(_M_r); }
1388 empty() requires requires { ranges::empty(_M_r); }
1389 { return ranges::empty(_M_r); }
1392 empty() const requires requires { ranges::empty(_M_r); }
1393 { return ranges::empty(_M_r); }
1396 size() requires sized_range<_Range>
1397 { return ranges::size(_M_r); }
1400 size() const requires sized_range<const _Range>
1401 { return ranges::size(_M_r); }
1404 data() requires contiguous_range<_Range>
1405 { return ranges::data(_M_r); }
1408 data() const requires contiguous_range<const _Range>
1409 { return ranges::data(_M_r); }
1412 template<typename _Tp>
1413 inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
1414 = enable_borrowed_range<_Tp>;
1420 template<typename _Range>
1421 concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };
1423 template<typename _Range>
1424 concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
1425 } // namespace __detail
1427 struct _All : __adaptor::_RangeAdaptorClosure<_All>
1429 template<typename _Range>
1430 static constexpr bool
1433 if constexpr (view<decay_t<_Range>>)
1434 return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
1435 else if constexpr (__detail::__can_ref_view<_Range>)
1438 return noexcept(owning_view{std::declval<_Range>()});
1441 template<viewable_range _Range>
1442 requires view<decay_t<_Range>>
1443 || __detail::__can_ref_view<_Range>
1444 || __detail::__can_owning_view<_Range>
1446 operator() [[nodiscard]] (_Range&& __r) const
1447 noexcept(_S_noexcept<_Range>())
1449 if constexpr (view<decay_t<_Range>>)
1450 return std::forward<_Range>(__r);
1451 else if constexpr (__detail::__can_ref_view<_Range>)
1452 return ref_view{std::forward<_Range>(__r)};
1454 return owning_view{std::forward<_Range>(__r)};
1457 static constexpr bool _S_has_simple_call_op = true;
1460 inline constexpr _All all;
1462 template<viewable_range _Range>
1463 using all_t = decltype(all(std::declval<_Range>()));
1464 } // namespace views
1468 template<typename _Tp>
1469 struct __non_propagating_cache
1471 // When _Tp is not an object type (e.g. is a reference type), we make
1472 // __non_propagating_cache<_Tp> empty rather than ill-formed so that
1473 // users can easily conditionally declare data members with this type
1474 // (such as join_view::_M_inner).
1477 template<typename _Tp>
1478 requires is_object_v<_Tp>
1479 struct __non_propagating_cache<_Tp>
1480 : protected _Optional_base<_Tp>
1482 __non_propagating_cache() = default;
1485 __non_propagating_cache(const __non_propagating_cache&) noexcept
1489 __non_propagating_cache(__non_propagating_cache&& __other) noexcept
1490 { __other._M_reset(); }
1492 constexpr __non_propagating_cache&
1493 operator=(const __non_propagating_cache& __other) noexcept
1495 if (std::__addressof(__other) != this)
1500 constexpr __non_propagating_cache&
1501 operator=(__non_propagating_cache&& __other) noexcept
1508 constexpr __non_propagating_cache&
1509 operator=(_Tp __val)
1512 this->_M_payload._M_construct(std::move(__val));
1517 operator bool() const noexcept
1518 { return this->_M_is_engaged(); }
1521 operator*() noexcept
1522 { return this->_M_get(); }
1524 constexpr const _Tp&
1525 operator*() const noexcept
1526 { return this->_M_get(); }
1528 template<typename _Iter>
1530 _M_emplace_deref(const _Iter& __i)
1533 auto __f = [] (auto& __x) { return *__x; };
1534 this->_M_payload._M_apply(_Optional_func{__f}, __i);
1535 return this->_M_get();
1539 template<range _Range>
1540 struct _CachedPosition
1543 _M_has_value() const
1546 constexpr iterator_t<_Range>
1547 _M_get(const _Range&) const
1549 __glibcxx_assert(false);
1550 __builtin_unreachable();
1554 _M_set(const _Range&, const iterator_t<_Range>&) const
1558 template<forward_range _Range>
1559 struct _CachedPosition<_Range>
1560 : protected __non_propagating_cache<iterator_t<_Range>>
1563 _M_has_value() const
1564 { return this->_M_is_engaged(); }
1566 constexpr iterator_t<_Range>
1567 _M_get(const _Range&) const
1569 __glibcxx_assert(_M_has_value());
1574 _M_set(const _Range&, const iterator_t<_Range>& __it)
1576 __glibcxx_assert(!_M_has_value());
1577 std::construct_at(std::__addressof(this->_M_payload._M_payload),
1579 this->_M_payload._M_engaged = true;
1583 template<random_access_range _Range>
1584 requires (sizeof(range_difference_t<_Range>)
1585 <= sizeof(iterator_t<_Range>))
1586 struct _CachedPosition<_Range>
1589 range_difference_t<_Range> _M_offset = -1;
1592 _CachedPosition() = default;
1595 _CachedPosition(const _CachedPosition&) = default;
1598 _CachedPosition(_CachedPosition&& __other) noexcept
1599 { *this = std::move(__other); }
1601 constexpr _CachedPosition&
1602 operator=(const _CachedPosition&) = default;
1604 constexpr _CachedPosition&
1605 operator=(_CachedPosition&& __other) noexcept
1607 // Propagate the cached offset, but invalidate the source.
1608 _M_offset = __other._M_offset;
1609 __other._M_offset = -1;
1614 _M_has_value() const
1615 { return _M_offset >= 0; }
1617 constexpr iterator_t<_Range>
1618 _M_get(_Range& __r) const
1620 __glibcxx_assert(_M_has_value());
1621 return ranges::begin(__r) + _M_offset;
1625 _M_set(_Range& __r, const iterator_t<_Range>& __it)
1627 __glibcxx_assert(!_M_has_value());
1628 _M_offset = __it - ranges::begin(__r);
1631 } // namespace __detail
1635 template<typename _Base>
1636 struct __filter_view_iter_cat
1639 template<forward_range _Base>
1640 struct __filter_view_iter_cat<_Base>
1646 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1647 if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
1648 return bidirectional_iterator_tag{};
1649 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
1650 return forward_iterator_tag{};
1655 using iterator_category = decltype(_S_iter_cat());
1657 } // namespace __detail
1659 template<input_range _Vp,
1660 indirect_unary_predicate<iterator_t<_Vp>> _Pred>
1661 requires view<_Vp> && is_object_v<_Pred>
1662 class filter_view : public view_interface<filter_view<_Vp, _Pred>>
1667 struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
1670 static constexpr auto
1673 if constexpr (bidirectional_range<_Vp>)
1674 return bidirectional_iterator_tag{};
1675 else if constexpr (forward_range<_Vp>)
1676 return forward_iterator_tag{};
1678 return input_iterator_tag{};
1683 using _Vp_iter = iterator_t<_Vp>;
1685 _Vp_iter _M_current = _Vp_iter();
1686 filter_view* _M_parent = nullptr;
1689 using iterator_concept = decltype(_S_iter_concept());
1690 // iterator_category defined in __filter_view_iter_cat
1691 using value_type = range_value_t<_Vp>;
1692 using difference_type = range_difference_t<_Vp>;
1694 _Iterator() requires default_initializable<_Vp_iter> = default;
1697 _Iterator(filter_view* __parent, _Vp_iter __current)
1698 : _M_current(std::move(__current)),
1702 constexpr const _Vp_iter&
1703 base() const & noexcept
1704 { return _M_current; }
1708 { return std::move(_M_current); }
1710 constexpr range_reference_t<_Vp>
1712 { return *_M_current; }
1716 requires __detail::__has_arrow<_Vp_iter>
1717 && copyable<_Vp_iter>
1718 { return _M_current; }
1720 constexpr _Iterator&
1723 _M_current = ranges::find_if(std::move(++_M_current),
1724 ranges::end(_M_parent->_M_base),
1725 std::ref(*_M_parent->_M_pred));
1734 operator++(int) requires forward_range<_Vp>
1741 constexpr _Iterator&
1742 operator--() requires bidirectional_range<_Vp>
1746 while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
1751 operator--(int) requires bidirectional_range<_Vp>
1758 friend constexpr bool
1759 operator==(const _Iterator& __x, const _Iterator& __y)
1760 requires equality_comparable<_Vp_iter>
1761 { return __x._M_current == __y._M_current; }
1763 friend constexpr range_rvalue_reference_t<_Vp>
1764 iter_move(const _Iterator& __i)
1765 noexcept(noexcept(ranges::iter_move(__i._M_current)))
1766 { return ranges::iter_move(__i._M_current); }
1768 friend constexpr void
1769 iter_swap(const _Iterator& __x, const _Iterator& __y)
1770 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
1771 requires indirectly_swappable<_Vp_iter>
1772 { ranges::iter_swap(__x._M_current, __y._M_current); }
1778 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
1781 __equal(const _Iterator& __i) const
1782 { return __i._M_current == _M_end; }
1785 _Sentinel() = default;
1788 _Sentinel(filter_view* __parent)
1789 : _M_end(ranges::end(__parent->_M_base))
1792 constexpr sentinel_t<_Vp>
1796 friend constexpr bool
1797 operator==(const _Iterator& __x, const _Sentinel& __y)
1798 { return __y.__equal(__x); }
1801 _Vp _M_base = _Vp();
1802 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
1803 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
1806 filter_view() requires (default_initializable<_Vp>
1807 && default_initializable<_Pred>)
1811 filter_view(_Vp __base, _Pred __pred)
1812 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
1816 base() const& requires copy_constructible<_Vp>
1821 { return std::move(_M_base); }
1823 constexpr const _Pred&
1825 { return *_M_pred; }
1830 if (_M_cached_begin._M_has_value())
1831 return {this, _M_cached_begin._M_get(_M_base)};
1833 __glibcxx_assert(_M_pred.has_value());
1834 auto __it = ranges::find_if(ranges::begin(_M_base),
1835 ranges::end(_M_base),
1836 std::ref(*_M_pred));
1837 _M_cached_begin._M_set(_M_base, __it);
1838 return {this, std::move(__it)};
1844 if constexpr (common_range<_Vp>)
1845 return _Iterator{this, ranges::end(_M_base)};
1847 return _Sentinel{this};
1851 template<typename _Range, typename _Pred>
1852 filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
1858 template<typename _Range, typename _Pred>
1859 concept __can_filter_view
1860 = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
1861 } // namespace __detail
1863 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
1865 template<viewable_range _Range, typename _Pred>
1866 requires __detail::__can_filter_view<_Range, _Pred>
1868 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
1870 return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
1873 using _RangeAdaptor<_Filter>::operator();
1874 static constexpr int _S_arity = 2;
1875 static constexpr bool _S_has_simple_extra_args = true;
1878 inline constexpr _Filter filter;
1879 } // namespace views
1881#if __cpp_lib_ranges >= 202207L // C++ >= 23
1882 template<input_range _Vp, move_constructible _Fp>
1884 template<input_range _Vp, copy_constructible _Fp>
1886 requires view<_Vp> && is_object_v<_Fp>
1887 && regular_invocable<_Fp&, range_reference_t<_Vp>>
1888 && std::__detail::__can_reference<invoke_result_t<_Fp&,
1889 range_reference_t<_Vp>>>
1890 class transform_view : public view_interface<transform_view<_Vp, _Fp>>
1893 template<bool _Const>
1894 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
1896 template<bool _Const>
1900 template<bool _Const>
1901 requires forward_range<_Base<_Const>>
1902 struct __iter_cat<_Const>
1908 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1909 // 3564. transform_view::iterator<true>::value_type and
1910 // iterator_category should use const F&
1911 using _Base = transform_view::_Base<_Const>;
1912 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1913 range_reference_t<_Base>>;
1914 // _GLIBCXX_RESOLVE_LIB_DEFECTS
1915 // 3798. Rvalue reference and iterator_category
1916 if constexpr (is_reference_v<_Res>)
1919 = typename iterator_traits<iterator_t<_Base>>::iterator_category;
1920 if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
1921 return random_access_iterator_tag{};
1926 return input_iterator_tag{};
1929 using iterator_category = decltype(_S_iter_cat());
1932 template<bool _Const>
1935 template<bool _Const>
1936 struct _Iterator : __iter_cat<_Const>
1939 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
1940 using _Base = transform_view::_Base<_Const>;
1945 if constexpr (random_access_range<_Base>)
1946 return random_access_iterator_tag{};
1947 else if constexpr (bidirectional_range<_Base>)
1948 return bidirectional_iterator_tag{};
1949 else if constexpr (forward_range<_Base>)
1950 return forward_iterator_tag{};
1952 return input_iterator_tag{};
1955 using _Base_iter = iterator_t<_Base>;
1957 _Base_iter _M_current = _Base_iter();
1958 _Parent* _M_parent = nullptr;
1961 using iterator_concept = decltype(_S_iter_concept());
1962 // iterator_category defined in __transform_view_iter_cat
1964 = remove_cvref_t<invoke_result_t<__maybe_const_t<_Const, _Fp>&,
1965 range_reference_t<_Base>>>;
1966 using difference_type = range_difference_t<_Base>;
1968 _Iterator() requires default_initializable<_Base_iter> = default;
1971 _Iterator(_Parent* __parent, _Base_iter __current)
1972 : _M_current(std::move(__current)),
1977 _Iterator(_Iterator<!_Const> __i)
1979 && convertible_to<iterator_t<_Vp>, _Base_iter>
1980 : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
1983 constexpr const _Base_iter&
1984 base() const & noexcept
1985 { return _M_current; }
1987 constexpr _Base_iter
1989 { return std::move(_M_current); }
1991 constexpr decltype(auto)
1993 noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
1994 { return std::__invoke(*_M_parent->_M_fun, *_M_current); }
1996 constexpr _Iterator&
2008 operator++(int) requires forward_range<_Base>
2015 constexpr _Iterator&
2016 operator--() requires bidirectional_range<_Base>
2023 operator--(int) requires bidirectional_range<_Base>
2030 constexpr _Iterator&
2031 operator+=(difference_type __n) requires random_access_range<_Base>
2037 constexpr _Iterator&
2038 operator-=(difference_type __n) requires random_access_range<_Base>
2044 constexpr decltype(auto)
2045 operator[](difference_type __n) const
2046 requires random_access_range<_Base>
2047 { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }
2049 friend constexpr bool
2050 operator==(const _Iterator& __x, const _Iterator& __y)
2051 requires equality_comparable<_Base_iter>
2052 { return __x._M_current == __y._M_current; }
2054 friend constexpr bool
2055 operator<(const _Iterator& __x, const _Iterator& __y)
2056 requires random_access_range<_Base>
2057 { return __x._M_current < __y._M_current; }
2059 friend constexpr bool
2060 operator>(const _Iterator& __x, const _Iterator& __y)
2061 requires random_access_range<_Base>
2062 { return __y < __x; }
2064 friend constexpr bool
2065 operator<=(const _Iterator& __x, const _Iterator& __y)
2066 requires random_access_range<_Base>
2067 { return !(__y < __x); }
2069 friend constexpr bool
2070 operator>=(const _Iterator& __x, const _Iterator& __y)
2071 requires random_access_range<_Base>
2072 { return !(__x < __y); }
2074#ifdef __cpp_lib_three_way_comparison
2075 friend constexpr auto
2076 operator<=>(const _Iterator& __x, const _Iterator& __y)
2077 requires random_access_range<_Base>
2078 && three_way_comparable<_Base_iter>
2079 { return __x._M_current <=> __y._M_current; }
2082 friend constexpr _Iterator
2083 operator+(_Iterator __i, difference_type __n)
2084 requires random_access_range<_Base>
2085 { return {__i._M_parent, __i._M_current + __n}; }
2087 friend constexpr _Iterator
2088 operator+(difference_type __n, _Iterator __i)
2089 requires random_access_range<_Base>
2090 { return {__i._M_parent, __i._M_current + __n}; }
2092 friend constexpr _Iterator
2093 operator-(_Iterator __i, difference_type __n)
2094 requires random_access_range<_Base>
2095 { return {__i._M_parent, __i._M_current - __n}; }
2097 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2098 // 3483. transform_view::iterator's difference is overconstrained
2099 friend constexpr difference_type
2100 operator-(const _Iterator& __x, const _Iterator& __y)
2101 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
2102 { return __x._M_current - __y._M_current; }
2104 friend constexpr decltype(auto)
2105 iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
2107 if constexpr (is_lvalue_reference_v<decltype(*__i)>)
2108 return std::move(*__i);
2113 friend _Iterator<!_Const>;
2114 template<bool> friend struct _Sentinel;
2117 template<bool _Const>
2121 using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
2122 using _Base = transform_view::_Base<_Const>;
2124 template<bool _Const2>
2126 __distance_from(const _Iterator<_Const2>& __i) const
2127 { return _M_end - __i._M_current; }
2129 template<bool _Const2>
2131 __equal(const _Iterator<_Const2>& __i) const
2132 { return __i._M_current == _M_end; }
2134 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2137 _Sentinel() = default;
2140 _Sentinel(sentinel_t<_Base> __end)
2145 _Sentinel(_Sentinel<!_Const> __i)
2147 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2148 : _M_end(std::move(__i._M_end))
2151 constexpr sentinel_t<_Base>
2155 template<bool _Const2>
2156 requires sentinel_for<sentinel_t<_Base>,
2157 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
2158 friend constexpr bool
2159 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2160 { return __y.__equal(__x); }
2162 template<bool _Const2,
2163 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2164 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2165 friend constexpr range_difference_t<_Base2>
2166 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
2167 { return -__y.__distance_from(__x); }
2169 template<bool _Const2,
2170 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
2171 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2172 friend constexpr range_difference_t<_Base2>
2173 operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
2174 { return __y.__distance_from(__x); }
2176 friend _Sentinel<!_Const>;
2179 _Vp _M_base = _Vp();
2180 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
2183 transform_view() requires (default_initializable<_Vp>
2184 && default_initializable<_Fp>)
2188 transform_view(_Vp __base, _Fp __fun)
2189 : _M_base(std::move(__base)), _M_fun(std::move(__fun))
2193 base() const& requires copy_constructible<_Vp>
2194 { return _M_base ; }
2198 { return std::move(_M_base); }
2200 constexpr _Iterator<false>
2202 { return _Iterator<false>{this, ranges::begin(_M_base)}; }
2204 constexpr _Iterator<true>
2206 requires range<const _Vp>
2207 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2208 { return _Iterator<true>{this, ranges::begin(_M_base)}; }
2210 constexpr _Sentinel<false>
2212 { return _Sentinel<false>{ranges::end(_M_base)}; }
2214 constexpr _Iterator<false>
2215 end() requires common_range<_Vp>
2216 { return _Iterator<false>{this, ranges::end(_M_base)}; }
2218 constexpr _Sentinel<true>
2220 requires range<const _Vp>
2221 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2222 { return _Sentinel<true>{ranges::end(_M_base)}; }
2224 constexpr _Iterator<true>
2226 requires common_range<const _Vp>
2227 && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
2228 { return _Iterator<true>{this, ranges::end(_M_base)}; }
2231 size() requires sized_range<_Vp>
2232 { return ranges::size(_M_base); }
2235 size() const requires sized_range<const _Vp>
2236 { return ranges::size(_M_base); }
2239 template<typename _Range, typename _Fp>
2240 transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
2246 template<typename _Range, typename _Fp>
2247 concept __can_transform_view
2248 = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
2249 } // namespace __detail
2251 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
2253 template<viewable_range _Range, typename _Fp>
2254 requires __detail::__can_transform_view<_Range, _Fp>
2256 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
2258 return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
2261 using _RangeAdaptor<_Transform>::operator();
2262 static constexpr int _S_arity = 2;
2263 static constexpr bool _S_has_simple_extra_args = true;
2266 inline constexpr _Transform transform;
2267 } // namespace views
2270 class take_view : public view_interface<take_view<_Vp>>
2273 template<bool _Const>
2274 using _CI = counted_iterator<
2275 iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;
2277 template<bool _Const>
2281 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2282 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2285 _Sentinel() = default;
2288 _Sentinel(sentinel_t<_Base> __end)
2293 _Sentinel(_Sentinel<!_Const> __s)
2294 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2295 : _M_end(std::move(__s._M_end))
2298 constexpr sentinel_t<_Base>
2302 friend constexpr bool
2303 operator==(const _CI<_Const>& __y, const _Sentinel& __x)
2304 { return __y.count() == 0 || __y.base() == __x._M_end; }
2306 template<bool _OtherConst = !_Const,
2307 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2308 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2309 friend constexpr bool
2310 operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
2311 { return __y.count() == 0 || __y.base() == __x._M_end; }
2313 friend _Sentinel<!_Const>;
2316 _Vp _M_base = _Vp();
2317 range_difference_t<_Vp> _M_count = 0;
2320 take_view() requires default_initializable<_Vp> = default;
2323 take_view(_Vp __base, range_difference_t<_Vp> __count)
2324 : _M_base(std::move(__base)), _M_count(std::move(__count))
2328 base() const& requires copy_constructible<_Vp>
2333 { return std::move(_M_base); }
2336 begin() requires (!__detail::__simple_view<_Vp>)
2338 if constexpr (sized_range<_Vp>)
2340 if constexpr (random_access_range<_Vp>)
2341 return ranges::begin(_M_base);
2345 return counted_iterator(ranges::begin(_M_base), __sz);
2349 return counted_iterator(ranges::begin(_M_base), _M_count);
2353 begin() const requires range<const _Vp>
2355 if constexpr (sized_range<const _Vp>)
2357 if constexpr (random_access_range<const _Vp>)
2358 return ranges::begin(_M_base);
2362 return counted_iterator(ranges::begin(_M_base), __sz);
2366 return counted_iterator(ranges::begin(_M_base), _M_count);
2370 end() requires (!__detail::__simple_view<_Vp>)
2372 if constexpr (sized_range<_Vp>)
2374 if constexpr (random_access_range<_Vp>)
2375 return ranges::begin(_M_base) + size();
2377 return default_sentinel;
2380 return _Sentinel<false>{ranges::end(_M_base)};
2384 end() const requires range<const _Vp>
2386 if constexpr (sized_range<const _Vp>)
2388 if constexpr (random_access_range<const _Vp>)
2389 return ranges::begin(_M_base) + size();
2391 return default_sentinel;
2394 return _Sentinel<true>{ranges::end(_M_base)};
2398 size() requires sized_range<_Vp>
2400 auto __n = ranges::size(_M_base);
2401 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2405 size() const requires sized_range<const _Vp>
2407 auto __n = ranges::size(_M_base);
2408 return std::min(__n, static_cast<decltype(__n)>(_M_count));
2412 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2413 // 3447. Deduction guides for take_view and drop_view have different
2415 template<typename _Range>
2416 take_view(_Range&&, range_difference_t<_Range>)
2417 -> take_view<views::all_t<_Range>>;
2419 template<typename _Tp>
2420 inline constexpr bool enable_borrowed_range<take_view<_Tp>>
2421 = enable_borrowed_range<_Tp>;
2427 template<typename _Range>
2428 inline constexpr bool __is_empty_view = false;
2430 template<typename _Tp>
2431 inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;
2433 template<typename _Range>
2434 inline constexpr bool __is_basic_string_view = false;
2436 template<typename _CharT, typename _Traits>
2437 inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
2440 using ranges::__detail::__is_subrange;
2442 template<typename _Range>
2443 inline constexpr bool __is_iota_view = false;
2445 template<typename _Winc, typename _Bound>
2446 inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;
2448 template<typename _Range>
2449 inline constexpr bool __is_repeat_view = false;
2451 template<typename _Range>
2453 __take_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2455 template<typename _Range, typename _Dp>
2456 concept __can_take_view
2457 = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
2458 } // namespace __detail
2460 struct _Take : __adaptor::_RangeAdaptor<_Take>
2462 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2463 requires __detail::__can_take_view<_Range, _Dp>
2465 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2467 using _Tp = remove_cvref_t<_Range>;
2468 if constexpr (__detail::__is_empty_view<_Tp>)
2470 else if constexpr (random_access_range<_Tp>
2472 && (std::__detail::__is_span<_Tp>
2473 || __detail::__is_basic_string_view<_Tp>
2474 || __detail::__is_subrange<_Tp>
2475 || __detail::__is_iota_view<_Tp>))
2477 __n = std::min<_Dp>(ranges::distance(__r), __n);
2478 auto __begin = ranges::begin(__r);
2479 auto __end = __begin + __n;
2480 if constexpr (std::__detail::__is_span<_Tp>)
2481 return span<typename _Tp::element_type>(__begin, __end);
2482 else if constexpr (__detail::__is_basic_string_view<_Tp>)
2483 return _Tp(__begin, __end);
2484 else if constexpr (__detail::__is_subrange<_Tp>)
2485 return subrange<iterator_t<_Tp>>(__begin, __end);
2487 return iota_view(*__begin, *__end);
2489 else if constexpr (__detail::__is_repeat_view<_Tp>)
2490 return __detail::__take_of_repeat_view(std::forward<_Range>(__r), __n);
2492 return take_view(std::forward<_Range>(__r), __n);
2495 using _RangeAdaptor<_Take>::operator();
2496 static constexpr int _S_arity = 2;
2497 // The count argument of views::take is not always simple -- it can be
2498 // e.g. a move-only class that's implicitly convertible to the difference
2499 // type. But an integer-like count argument is surely simple.
2500 template<typename _Tp>
2501 static constexpr bool _S_has_simple_extra_args
2502 = ranges::__detail::__is_integer_like<_Tp>;
2505 inline constexpr _Take take;
2506 } // namespace views
2508 template<view _Vp, typename _Pred>
2509 requires input_range<_Vp> && is_object_v<_Pred>
2510 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2511 class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
2513 template<bool _Const>
2517 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2519 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
2520 const _Pred* _M_pred = nullptr;
2523 _Sentinel() = default;
2526 _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
2527 : _M_end(__end), _M_pred(__pred)
2531 _Sentinel(_Sentinel<!_Const> __s)
2532 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
2533 : _M_end(__s._M_end), _M_pred(__s._M_pred)
2536 constexpr sentinel_t<_Base>
2537 base() const { return _M_end; }
2539 friend constexpr bool
2540 operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
2541 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2543 template<bool _OtherConst = !_Const,
2544 typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
2545 requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
2546 friend constexpr bool
2547 operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
2548 { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
2550 friend _Sentinel<!_Const>;
2553 _Vp _M_base = _Vp();
2554 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2557 take_while_view() requires (default_initializable<_Vp>
2558 && default_initializable<_Pred>)
2562 take_while_view(_Vp __base, _Pred __pred)
2563 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2567 base() const& requires copy_constructible<_Vp>
2572 { return std::move(_M_base); }
2574 constexpr const _Pred&
2576 { return *_M_pred; }
2579 begin() requires (!__detail::__simple_view<_Vp>)
2580 { return ranges::begin(_M_base); }
2583 begin() const requires range<const _Vp>
2584 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2585 { return ranges::begin(_M_base); }
2588 end() requires (!__detail::__simple_view<_Vp>)
2589 { return _Sentinel<false>(ranges::end(_M_base),
2590 std::__addressof(*_M_pred)); }
2593 end() const requires range<const _Vp>
2594 && indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
2595 { return _Sentinel<true>(ranges::end(_M_base),
2596 std::__addressof(*_M_pred)); }
2599 template<typename _Range, typename _Pred>
2600 take_while_view(_Range&&, _Pred)
2601 -> take_while_view<views::all_t<_Range>, _Pred>;
2607 template<typename _Range, typename _Pred>
2608 concept __can_take_while_view
2609 = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2610 } // namespace __detail
2612 struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
2614 template<viewable_range _Range, typename _Pred>
2615 requires __detail::__can_take_while_view<_Range, _Pred>
2617 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2619 return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
2622 using _RangeAdaptor<_TakeWhile>::operator();
2623 static constexpr int _S_arity = 2;
2624 static constexpr bool _S_has_simple_extra_args = true;
2627 inline constexpr _TakeWhile take_while;
2628 } // namespace views
2631 class drop_view : public view_interface<drop_view<_Vp>>
2634 _Vp _M_base = _Vp();
2635 range_difference_t<_Vp> _M_count = 0;
2637 // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
2638 // both random_access_range and sized_range. Otherwise, cache its result.
2639 static constexpr bool _S_needs_cached_begin
2640 = !(random_access_range<const _Vp> && sized_range<const _Vp>);
2641 [[no_unique_address]]
2642 __detail::__maybe_present_t<_S_needs_cached_begin,
2643 __detail::_CachedPosition<_Vp>>
2647 drop_view() requires default_initializable<_Vp> = default;
2650 drop_view(_Vp __base, range_difference_t<_Vp> __count)
2651 : _M_base(std::move(__base)), _M_count(__count)
2652 { __glibcxx_assert(__count >= 0); }
2655 base() const& requires copy_constructible<_Vp>
2660 { return std::move(_M_base); }
2662 // This overload is disabled for simple views with constant-time begin().
2665 requires (!(__detail::__simple_view<_Vp>
2666 && random_access_range<const _Vp>
2667 && sized_range<const _Vp>))
2669 if constexpr (_S_needs_cached_begin)
2670 if (_M_cached_begin._M_has_value())
2671 return _M_cached_begin._M_get(_M_base);
2673 auto __it = ranges::next(ranges::begin(_M_base),
2674 _M_count, ranges::end(_M_base));
2675 if constexpr (_S_needs_cached_begin)
2676 _M_cached_begin._M_set(_M_base, __it);
2680 // _GLIBCXX_RESOLVE_LIB_DEFECTS
2681 // 3482. drop_view's const begin should additionally require sized_range
2684 requires random_access_range<const _Vp> && sized_range<const _Vp>
2686 return ranges::begin(_M_base) + ranges::min(ranges::distance(_M_base),
2691 end() requires (!__detail::__simple_view<_Vp>)
2692 { return ranges::end(_M_base); }
2695 end() const requires range<const _Vp>
2696 { return ranges::end(_M_base); }
2699 size() requires sized_range<_Vp>
2701 const auto __s = ranges::size(_M_base);
2702 const auto __c = static_cast<decltype(__s)>(_M_count);
2703 return __s < __c ? 0 : __s - __c;
2707 size() const requires sized_range<const _Vp>
2709 const auto __s = ranges::size(_M_base);
2710 const auto __c = static_cast<decltype(__s)>(_M_count);
2711 return __s < __c ? 0 : __s - __c;
2715 template<typename _Range>
2716 drop_view(_Range&&, range_difference_t<_Range>)
2717 -> drop_view<views::all_t<_Range>>;
2719 template<typename _Tp>
2720 inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
2721 = enable_borrowed_range<_Tp>;
2727 template<typename _Range>
2729 __drop_of_repeat_view(_Range&&, range_difference_t<_Range>); // defined later
2731 template<typename _Range, typename _Dp>
2732 concept __can_drop_view
2733 = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
2734 } // namespace __detail
2736 struct _Drop : __adaptor::_RangeAdaptor<_Drop>
2738 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
2739 requires __detail::__can_drop_view<_Range, _Dp>
2741 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
2743 using _Tp = remove_cvref_t<_Range>;
2744 if constexpr (__detail::__is_empty_view<_Tp>)
2746 else if constexpr (random_access_range<_Tp>
2748 && (std::__detail::__is_span<_Tp>
2749 || __detail::__is_basic_string_view<_Tp>
2750 || __detail::__is_iota_view<_Tp>
2751 || __detail::__is_subrange<_Tp>))
2753 __n = std::min<_Dp>(ranges::distance(__r), __n);
2754 auto __begin = ranges::begin(__r) + __n;
2755 auto __end = ranges::end(__r);
2756 if constexpr (std::__detail::__is_span<_Tp>)
2757 return span<typename _Tp::element_type>(__begin, __end);
2758 else if constexpr (__detail::__is_subrange<_Tp>)
2760 if constexpr (_Tp::_S_store_size)
2762 using ranges::__detail::__to_unsigned_like;
2763 auto __m = ranges::distance(__r) - __n;
2764 return _Tp(__begin, __end, __to_unsigned_like(__m));
2767 return _Tp(__begin, __end);
2770 return _Tp(__begin, __end);
2772 else if constexpr (__detail::__is_repeat_view<_Tp>)
2773 return __detail::__drop_of_repeat_view(std::forward<_Range>(__r), __n);
2775 return drop_view(std::forward<_Range>(__r), __n);
2778 using _RangeAdaptor<_Drop>::operator();
2779 static constexpr int _S_arity = 2;
2780 template<typename _Tp>
2781 static constexpr bool _S_has_simple_extra_args
2782 = _Take::_S_has_simple_extra_args<_Tp>;
2785 inline constexpr _Drop drop;
2786 } // namespace views
2788 template<view _Vp, typename _Pred>
2789 requires input_range<_Vp> && is_object_v<_Pred>
2790 && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
2791 class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
2794 _Vp _M_base = _Vp();
2795 [[no_unique_address]] __detail::__box<_Pred> _M_pred;
2796 [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;
2799 drop_while_view() requires (default_initializable<_Vp>
2800 && default_initializable<_Pred>)
2804 drop_while_view(_Vp __base, _Pred __pred)
2805 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
2809 base() const& requires copy_constructible<_Vp>
2814 { return std::move(_M_base); }
2816 constexpr const _Pred&
2818 { return *_M_pred; }
2823 if (_M_cached_begin._M_has_value())
2824 return _M_cached_begin._M_get(_M_base);
2826 __glibcxx_assert(_M_pred.has_value());
2827 auto __it = ranges::find_if_not(ranges::begin(_M_base),
2828 ranges::end(_M_base),
2829 std::cref(*_M_pred));
2830 _M_cached_begin._M_set(_M_base, __it);
2836 { return ranges::end(_M_base); }
2839 template<typename _Range, typename _Pred>
2840 drop_while_view(_Range&&, _Pred)
2841 -> drop_while_view<views::all_t<_Range>, _Pred>;
2843 template<typename _Tp, typename _Pred>
2844 inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
2845 = enable_borrowed_range<_Tp>;
2851 template<typename _Range, typename _Pred>
2852 concept __can_drop_while_view
2853 = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
2854 } // namespace __detail
2856 struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
2858 template<viewable_range _Range, typename _Pred>
2859 requires __detail::__can_drop_while_view<_Range, _Pred>
2861 operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
2863 return drop_while_view(std::forward<_Range>(__r),
2864 std::forward<_Pred>(__p));
2867 using _RangeAdaptor<_DropWhile>::operator();
2868 static constexpr int _S_arity = 2;
2869 static constexpr bool _S_has_simple_extra_args = true;
2872 inline constexpr _DropWhile drop_while;
2873 } // namespace views
2877 template<typename _Tp>
2879 __as_lvalue(_Tp&& __t)
2880 { return static_cast<_Tp&>(__t); }
2881 } // namespace __detail
2883 template<input_range _Vp>
2884 requires view<_Vp> && input_range<range_reference_t<_Vp>>
2885 class join_view : public view_interface<join_view<_Vp>>
2888 using _InnerRange = range_reference_t<_Vp>;
2890 template<bool _Const>
2891 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
2893 template<bool _Const>
2894 using _Outer_iter = iterator_t<_Base<_Const>>;
2896 template<bool _Const>
2897 using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;
2899 template<bool _Const>
2900 static constexpr bool _S_ref_is_glvalue
2901 = is_reference_v<range_reference_t<_Base<_Const>>>;
2903 template<bool _Const>
2907 template<bool _Const>
2908 requires _S_ref_is_glvalue<_Const>
2909 && forward_range<_Base<_Const>>
2910 && forward_range<range_reference_t<_Base<_Const>>>
2911 struct __iter_cat<_Const>
2914 static constexpr auto
2917 using _Outer_iter = join_view::_Outer_iter<_Const>;
2918 using _Inner_iter = join_view::_Inner_iter<_Const>;
2919 using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
2920 using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
2921 if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
2922 && derived_from<_InnerCat, bidirectional_iterator_tag>
2923 && common_range<range_reference_t<_Base<_Const>>>)
2924 return bidirectional_iterator_tag{};
2925 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
2926 && derived_from<_InnerCat, forward_iterator_tag>)
2927 return forward_iterator_tag{};
2929 return input_iterator_tag{};
2932 using iterator_category = decltype(_S_iter_cat());
2935 template<bool _Const>
2938 template<bool _Const>
2939 struct _Iterator : __iter_cat<_Const>
2942 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
2943 using _Base = join_view::_Base<_Const>;
2947 static constexpr bool _S_ref_is_glvalue
2948 = join_view::_S_ref_is_glvalue<_Const>;
2953 auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
2954 if constexpr (_S_ref_is_glvalue)
2957 return _M_parent->_M_inner._M_emplace_deref(__x);
2960 _Outer_iter& __outer = _M_get_outer();
2961 for (; __outer != ranges::end(_M_parent->_M_base); ++__outer)
2963 auto&& __inner = __update_inner(__outer);
2964 _M_inner = ranges::begin(__inner);
2965 if (_M_inner != ranges::end(__inner))
2969 if constexpr (_S_ref_is_glvalue)
2973 static constexpr auto
2976 if constexpr (_S_ref_is_glvalue
2977 && bidirectional_range<_Base>
2978 && bidirectional_range<range_reference_t<_Base>>
2979 && common_range<range_reference_t<_Base>>)
2980 return bidirectional_iterator_tag{};
2981 else if constexpr (_S_ref_is_glvalue
2982 && forward_range<_Base>
2983 && forward_range<range_reference_t<_Base>>)
2984 return forward_iterator_tag{};
2986 return input_iterator_tag{};
2989 using _Outer_iter = join_view::_Outer_iter<_Const>;
2990 using _Inner_iter = join_view::_Inner_iter<_Const>;
2992 constexpr _Outer_iter&
2995 if constexpr (forward_range<_Base>)
2998 return *_M_parent->_M_outer;
3001 constexpr const _Outer_iter&
3002 _M_get_outer() const
3004 if constexpr (forward_range<_Base>)
3007 return *_M_parent->_M_outer;
3011 _Iterator(_Parent* __parent, _Outer_iter __outer) requires forward_range<_Base>
3012 : _M_outer(std::move(__outer)), _M_parent(__parent)
3016 _Iterator(_Parent* __parent) requires (!forward_range<_Base>)
3017 : _M_parent(__parent)
3020 [[no_unique_address]]
3021 __detail::__maybe_present_t<forward_range<_Base>, _Outer_iter> _M_outer;
3022 optional<_Inner_iter> _M_inner;
3023 _Parent* _M_parent = nullptr;
3026 using iterator_concept = decltype(_S_iter_concept());
3027 // iterator_category defined in __join_view_iter_cat
3028 using value_type = range_value_t<range_reference_t<_Base>>;
3029 using difference_type
3030 = common_type_t<range_difference_t<_Base>,
3031 range_difference_t<range_reference_t<_Base>>>;
3033 _Iterator() = default;
3036 _Iterator(_Iterator<!_Const> __i)
3038 && convertible_to<iterator_t<_Vp>, _Outer_iter>
3039 && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
3040 : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
3041 _M_parent(__i._M_parent)
3044 constexpr decltype(auto)
3046 { return **_M_inner; }
3048 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3049 // 3500. join_view::iterator::operator->() is bogus
3050 constexpr _Inner_iter
3052 requires __detail::__has_arrow<_Inner_iter>
3053 && copyable<_Inner_iter>
3054 { return *_M_inner; }
3056 constexpr _Iterator&
3059 auto&& __inner_range = [this] () -> auto&& {
3060 if constexpr (_S_ref_is_glvalue)
3061 return *_M_get_outer();
3063 return *_M_parent->_M_inner;
3065 if (++*_M_inner == ranges::end(__inner_range))
3079 requires _S_ref_is_glvalue && forward_range<_Base>
3080 && forward_range<range_reference_t<_Base>>
3087 constexpr _Iterator&
3089 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3090 && bidirectional_range<range_reference_t<_Base>>
3091 && common_range<range_reference_t<_Base>>
3093 if (_M_outer == ranges::end(_M_parent->_M_base))
3094 _M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3095 while (*_M_inner == ranges::begin(__detail::__as_lvalue(*_M_outer)))
3096 *_M_inner = ranges::end(__detail::__as_lvalue(*--_M_outer));
3103 requires _S_ref_is_glvalue && bidirectional_range<_Base>
3104 && bidirectional_range<range_reference_t<_Base>>
3105 && common_range<range_reference_t<_Base>>
3112 friend constexpr bool
3113 operator==(const _Iterator& __x, const _Iterator& __y)
3114 requires _S_ref_is_glvalue
3115 && forward_range<_Base>
3116 && equality_comparable<_Inner_iter>
3118 return (__x._M_outer == __y._M_outer
3119 && __x._M_inner == __y._M_inner);
3122 friend constexpr decltype(auto)
3123 iter_move(const _Iterator& __i)
3124 noexcept(noexcept(ranges::iter_move(*__i._M_inner)))
3125 { return ranges::iter_move(*__i._M_inner); }
3127 friend constexpr void
3128 iter_swap(const _Iterator& __x, const _Iterator& __y)
3129 noexcept(noexcept(ranges::iter_swap(*__x._M_inner, *__y._M_inner)))
3130 requires indirectly_swappable<_Inner_iter>
3131 { return ranges::iter_swap(*__x._M_inner, *__y._M_inner); }
3133 friend _Iterator<!_Const>;
3134 template<bool> friend struct _Sentinel;
3137 template<bool _Const>
3141 using _Parent = __detail::__maybe_const_t<_Const, join_view>;
3142 using _Base = join_view::_Base<_Const>;
3144 template<bool _Const2>
3146 __equal(const _Iterator<_Const2>& __i) const
3147 { return __i._M_get_outer() == _M_end; }
3149 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
3152 _Sentinel() = default;
3155 _Sentinel(_Parent* __parent)
3156 : _M_end(ranges::end(__parent->_M_base))
3160 _Sentinel(_Sentinel<!_Const> __s)
3161 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
3162 : _M_end(std::move(__s._M_end))
3165 template<bool _Const2>
3166 requires sentinel_for<sentinel_t<_Base>,
3167 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
3168 friend constexpr bool
3169 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
3170 { return __y.__equal(__x); }
3172 friend _Sentinel<!_Const>;
3175 _Vp _M_base = _Vp();
3176 [[no_unique_address]]
3177 __detail::__maybe_present_t<!forward_range<_Vp>,
3178 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer;
3179 [[no_unique_address]]
3180 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
3183 join_view() requires default_initializable<_Vp> = default;
3186 join_view(_Vp __base)
3187 : _M_base(std::move(__base))
3191 base() const& requires copy_constructible<_Vp>
3196 { return std::move(_M_base); }
3201 if constexpr (forward_range<_Vp>)
3203 constexpr bool __use_const
3204 = (__detail::__simple_view<_Vp>
3205 && is_reference_v<range_reference_t<_Vp>>);
3206 return _Iterator<__use_const>{this, ranges::begin(_M_base)};
3210 _M_outer = ranges::begin(_M_base);
3211 return _Iterator<false>{this};
3217 requires forward_range<const _Vp>
3218 && is_reference_v<range_reference_t<const _Vp>>
3219 && input_range<range_reference_t<const _Vp>>
3221 return _Iterator<true>{this, ranges::begin(_M_base)};
3227 if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
3228 && forward_range<_InnerRange>
3229 && common_range<_Vp> && common_range<_InnerRange>)
3230 return _Iterator<__detail::__simple_view<_Vp>>{this,
3231 ranges::end(_M_base)};
3233 return _Sentinel<__detail::__simple_view<_Vp>>{this};
3238 requires forward_range<const _Vp>
3239 && is_reference_v<range_reference_t<const _Vp>>
3240 && input_range<range_reference_t<const _Vp>>
3242 if constexpr (is_reference_v<range_reference_t<const _Vp>>
3243 && forward_range<range_reference_t<const _Vp>>
3244 && common_range<const _Vp>
3245 && common_range<range_reference_t<const _Vp>>)
3246 return _Iterator<true>{this, ranges::end(_M_base)};
3248 return _Sentinel<true>{this};
3252 template<typename _Range>
3253 explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
3259 template<typename _Range>
3260 concept __can_join_view
3261 = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
3262 } // namespace __detail
3264 struct _Join : __adaptor::_RangeAdaptorClosure<_Join>
3266 template<viewable_range _Range>
3267 requires __detail::__can_join_view<_Range>
3269 operator() [[nodiscard]] (_Range&& __r) const
3271 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3272 // 3474. Nesting join_views is broken because of CTAD
3273 return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
3276 static constexpr bool _S_has_simple_call_op = true;
3279 inline constexpr _Join join;
3280 } // namespace views
3285 struct __require_constant;
3287 template<typename _Range>
3288 concept __tiny_range = sized_range<_Range>
3290 { typename __require_constant<remove_reference_t<_Range>::size()>; }
3291 && (remove_reference_t<_Range>::size() <= 1);
3293 template<typename _Base>
3294 struct __lazy_split_view_outer_iter_cat
3297 template<forward_range _Base>
3298 struct __lazy_split_view_outer_iter_cat<_Base>
3299 { using iterator_category = input_iterator_tag; };
3301 template<typename _Base>
3302 struct __lazy_split_view_inner_iter_cat
3305 template<forward_range _Base>
3306 struct __lazy_split_view_inner_iter_cat<_Base>
3309 static constexpr auto
3312 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
3313 if constexpr (derived_from<_Cat, forward_iterator_tag>)
3314 return forward_iterator_tag{};
3319 using iterator_category = decltype(_S_iter_cat());
3323 template<input_range _Vp, forward_range _Pattern>
3324 requires view<_Vp> && view<_Pattern>
3325 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3327 && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
3328 class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
3331 template<bool _Const>
3332 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
3334 template<bool _Const>
3337 template<bool _Const>
3339 : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
3342 using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
3343 using _Base = lazy_split_view::_Base<_Const>;
3347 { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }
3349 // [range.lazy.split.outer] p1
3350 // Many of the following specifications refer to the notional member
3351 // current of outer-iterator. current is equivalent to current_ if
3352 // V models forward_range, and parent_->current_ otherwise.
3354 __current() noexcept
3356 if constexpr (forward_range<_Vp>)
3359 return *_M_parent->_M_current;
3363 __current() const noexcept
3365 if constexpr (forward_range<_Vp>)
3368 return *_M_parent->_M_current;
3371 _Parent* _M_parent = nullptr;
3373 [[no_unique_address]]
3374 __detail::__maybe_present_t<forward_range<_Vp>,
3375 iterator_t<_Base>> _M_current;
3376 bool _M_trailing_empty = false;
3379 using iterator_concept = __conditional_t<forward_range<_Base>,
3380 forward_iterator_tag,
3381 input_iterator_tag>;
3382 // iterator_category defined in __lazy_split_view_outer_iter_cat
3383 using difference_type = range_difference_t<_Base>;
3385 struct value_type : view_interface<value_type>
3388 _OuterIter _M_i = _OuterIter();
3390 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3391 // 4013. lazy_split_view::outer-iterator::value_type should not
3392 // provide default constructor
3394 value_type(_OuterIter __i)
3395 : _M_i(std::move(__i))
3401 constexpr _InnerIter<_Const>
3403 { return _InnerIter<_Const>{_M_i}; }
3405 constexpr default_sentinel_t
3406 end() const noexcept
3407 { return default_sentinel; }
3410 _OuterIter() = default;
3413 _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
3414 : _M_parent(__parent)
3418 _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
3419 requires forward_range<_Base>
3420 : _M_parent(__parent),
3421 _M_current(std::move(__current))
3425 _OuterIter(_OuterIter<!_Const> __i)
3427 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
3428 : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current)),
3429 _M_trailing_empty(__i._M_trailing_empty)
3432 constexpr value_type
3434 { return value_type{*this}; }
3436 constexpr _OuterIter&
3439 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3440 // 3505. lazy_split_view::outer-iterator::operator++ misspecified
3441 const auto __end = ranges::end(_M_parent->_M_base);
3442 if (__current() == __end)
3444 _M_trailing_empty = false;
3447 const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
3448 if (__pbegin == __pend)
3450 else if constexpr (__detail::__tiny_range<_Pattern>)
3452 __current() = ranges::find(std::move(__current()), __end,
3454 if (__current() != __end)
3457 if (__current() == __end)
3458 _M_trailing_empty = true;
3465 = ranges::mismatch(__current(), __end, __pbegin, __pend);
3469 if (__current() == __end)
3470 _M_trailing_empty = true;
3473 } while (++__current() != __end);
3477 constexpr decltype(auto)
3480 if constexpr (forward_range<_Base>)
3490 friend constexpr bool
3491 operator==(const _OuterIter& __x, const _OuterIter& __y)
3492 requires forward_range<_Base>
3494 return __x._M_current == __y._M_current
3495 && __x._M_trailing_empty == __y._M_trailing_empty;
3498 friend constexpr bool
3499 operator==(const _OuterIter& __x, default_sentinel_t)
3500 { return __x.__at_end(); };
3502 friend _OuterIter<!_Const>;
3503 friend _InnerIter<_Const>;
3506 template<bool _Const>
3508 : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
3511 using _Base = lazy_split_view::_Base<_Const>;
3516 auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
3517 auto __end = ranges::end(_M_i._M_parent->_M_base);
3518 if constexpr (__detail::__tiny_range<_Pattern>)
3520 const auto& __cur = _M_i_current();
3523 if (__pcur == __pend)
3524 return _M_incremented;
3525 return *__cur == *__pcur;
3529 auto __cur = _M_i_current();
3532 if (__pcur == __pend)
3533 return _M_incremented;
3536 if (*__cur != *__pcur)
3538 if (++__pcur == __pend)
3540 } while (++__cur != __end);
3546 _M_i_current() noexcept
3547 { return _M_i.__current(); }
3550 _M_i_current() const noexcept
3551 { return _M_i.__current(); }
3553 _OuterIter<_Const> _M_i = _OuterIter<_Const>();
3554 bool _M_incremented = false;
3557 using iterator_concept
3558 = typename _OuterIter<_Const>::iterator_concept;
3559 // iterator_category defined in __lazy_split_view_inner_iter_cat
3560 using value_type = range_value_t<_Base>;
3561 using difference_type = range_difference_t<_Base>;
3563 _InnerIter() = default;
3566 _InnerIter(_OuterIter<_Const> __i)
3567 : _M_i(std::move(__i))
3570 constexpr const iterator_t<_Base>&
3571 base() const& noexcept
3572 { return _M_i_current(); }
3574 constexpr iterator_t<_Base>
3575 base() && requires forward_range<_Vp>
3576 { return std::move(_M_i_current()); }
3578 constexpr decltype(auto)
3580 { return *_M_i_current(); }
3582 constexpr _InnerIter&
3585 _M_incremented = true;
3586 if constexpr (!forward_range<_Base>)
3587 if constexpr (_Pattern::size() == 0)
3593 constexpr decltype(auto)
3596 if constexpr (forward_range<_Base>)
3606 friend constexpr bool
3607 operator==(const _InnerIter& __x, const _InnerIter& __y)
3608 requires forward_range<_Base>
3609 { return __x._M_i == __y._M_i; }
3611 friend constexpr bool
3612 operator==(const _InnerIter& __x, default_sentinel_t)
3613 { return __x.__at_end(); }
3615 friend constexpr decltype(auto)
3616 iter_move(const _InnerIter& __i)
3617 noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
3618 { return ranges::iter_move(__i._M_i_current()); }
3620 friend constexpr void
3621 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
3622 noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
3623 __y._M_i_current())))
3624 requires indirectly_swappable<iterator_t<_Base>>
3625 { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
3628 _Vp _M_base = _Vp();
3629 _Pattern _M_pattern = _Pattern();
3630 [[no_unique_address]]
3631 __detail::__maybe_present_t<!forward_range<_Vp>,
3632 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;
3636 lazy_split_view() requires (default_initializable<_Vp>
3637 && default_initializable<_Pattern>)
3641 lazy_split_view(_Vp __base, _Pattern __pattern)
3642 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3645 template<input_range _Range>
3646 requires constructible_from<_Vp, views::all_t<_Range>>
3647 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3649 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
3650 : _M_base(views::all(std::forward<_Range>(__r))),
3651 _M_pattern(views::single(std::move(__e)))
3655 base() const& requires copy_constructible<_Vp>
3660 { return std::move(_M_base); }
3665 if constexpr (forward_range<_Vp>)
3667 constexpr bool __simple
3668 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3669 return _OuterIter<__simple>{this, ranges::begin(_M_base)};
3673 _M_current = ranges::begin(_M_base);
3674 return _OuterIter<false>{this};
3679 begin() const requires forward_range<_Vp> && forward_range<const _Vp>
3681 return _OuterIter<true>{this, ranges::begin(_M_base)};
3685 end() requires forward_range<_Vp> && common_range<_Vp>
3687 constexpr bool __simple
3688 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
3689 return _OuterIter<__simple>{this, ranges::end(_M_base)};
3695 if constexpr (forward_range<_Vp>
3696 && forward_range<const _Vp>
3697 && common_range<const _Vp>)
3698 return _OuterIter<true>{this, ranges::end(_M_base)};
3700 return default_sentinel;
3704 template<typename _Range, typename _Pattern>
3705 lazy_split_view(_Range&&, _Pattern&&)
3706 -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3708 template<input_range _Range>
3709 lazy_split_view(_Range&&, range_value_t<_Range>)
3710 -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3716 template<typename _Range, typename _Pattern>
3717 concept __can_lazy_split_view
3718 = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3719 } // namespace __detail
3721 struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
3723 template<viewable_range _Range, typename _Pattern>
3724 requires __detail::__can_lazy_split_view<_Range, _Pattern>
3726 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3728 return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3731 using _RangeAdaptor<_LazySplit>::operator();
3732 static constexpr int _S_arity = 2;
3733 // The pattern argument of views::lazy_split is not always simple -- it can be
3734 // a non-view range, the value category of which affects whether the call
3735 // is well-formed. But a scalar or a view pattern argument is surely
3737 template<typename _Pattern>
3738 static constexpr bool _S_has_simple_extra_args
3739 = is_scalar_v<_Pattern> || (view<_Pattern>
3740 && copy_constructible<_Pattern>);
3743 inline constexpr _LazySplit lazy_split;
3744 } // namespace views
3746 template<forward_range _Vp, forward_range _Pattern>
3747 requires view<_Vp> && view<_Pattern>
3748 && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
3750 class split_view : public view_interface<split_view<_Vp, _Pattern>>
3753 _Vp _M_base = _Vp();
3754 _Pattern _M_pattern = _Pattern();
3755 __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;
3761 split_view() requires (default_initializable<_Vp>
3762 && default_initializable<_Pattern>)
3766 split_view(_Vp __base, _Pattern __pattern)
3767 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
3770 template<forward_range _Range>
3771 requires constructible_from<_Vp, views::all_t<_Range>>
3772 && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
3774 split_view(_Range&& __r, range_value_t<_Range> __e)
3775 : _M_base(views::all(std::forward<_Range>(__r))),
3776 _M_pattern(views::single(std::move(__e)))
3780 base() const& requires copy_constructible<_Vp>
3785 { return std::move(_M_base); }
3790 if (!_M_cached_begin)
3791 _M_cached_begin = _M_find_next(ranges::begin(_M_base));
3792 return {this, ranges::begin(_M_base), *_M_cached_begin};
3798 if constexpr (common_range<_Vp>)
3799 return _Iterator{this, ranges::end(_M_base), {}};
3801 return _Sentinel{this};
3804 constexpr subrange<iterator_t<_Vp>>
3805 _M_find_next(iterator_t<_Vp> __it)
3807 auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
3808 if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
3820 split_view* _M_parent = nullptr;
3821 iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
3822 subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
3823 bool _M_trailing_empty = false;
3825 friend struct _Sentinel;
3828 using iterator_concept = forward_iterator_tag;
3829 using iterator_category = input_iterator_tag;
3830 using value_type = subrange<iterator_t<_Vp>>;
3831 using difference_type = range_difference_t<_Vp>;
3833 _Iterator() = default;
3836 _Iterator(split_view* __parent,
3837 iterator_t<_Vp> __current,
3838 subrange<iterator_t<_Vp>> __next)
3839 : _M_parent(__parent),
3840 _M_cur(std::move(__current)),
3841 _M_next(std::move(__next))
3844 constexpr iterator_t<_Vp>
3848 constexpr value_type
3850 { return {_M_cur, _M_next.begin()}; }
3852 constexpr _Iterator&
3855 _M_cur = _M_next.begin();
3856 if (_M_cur != ranges::end(_M_parent->_M_base))
3858 _M_cur = _M_next.end();
3859 if (_M_cur == ranges::end(_M_parent->_M_base))
3861 _M_trailing_empty = true;
3862 _M_next = {_M_cur, _M_cur};
3865 _M_next = _M_parent->_M_find_next(_M_cur);
3868 _M_trailing_empty = false;
3880 friend constexpr bool
3881 operator==(const _Iterator& __x, const _Iterator& __y)
3883 return __x._M_cur == __y._M_cur
3884 && __x._M_trailing_empty == __y._M_trailing_empty;
3891 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
3894 _M_equal(const _Iterator& __x) const
3895 { return __x._M_cur == _M_end && !__x._M_trailing_empty; }
3898 _Sentinel() = default;
3901 _Sentinel(split_view* __parent)
3902 : _M_end(ranges::end(__parent->_M_base))
3905 friend constexpr bool
3906 operator==(const _Iterator& __x, const _Sentinel& __y)
3907 { return __y._M_equal(__x); }
3911 template<typename _Range, typename _Pattern>
3912 split_view(_Range&&, _Pattern&&)
3913 -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
3915 template<forward_range _Range>
3916 split_view(_Range&&, range_value_t<_Range>)
3917 -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
3923 template<typename _Range, typename _Pattern>
3924 concept __can_split_view
3925 = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
3926 } // namespace __detail
3928 struct _Split : __adaptor::_RangeAdaptor<_Split>
3930 template<viewable_range _Range, typename _Pattern>
3931 requires __detail::__can_split_view<_Range, _Pattern>
3933 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
3935 return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
3938 using _RangeAdaptor<_Split>::operator();
3939 static constexpr int _S_arity = 2;
3940 template<typename _Pattern>
3941 static constexpr bool _S_has_simple_extra_args
3942 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
3945 inline constexpr _Split split;
3946 } // namespace views
3952 template<input_or_output_iterator _Iter>
3954 operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
3956 if constexpr (contiguous_iterator<_Iter>)
3957 return span(std::to_address(__i), __n);
3958 else if constexpr (random_access_iterator<_Iter>)
3959 return subrange(__i, __i + __n);
3961 return subrange(counted_iterator(std::move(__i), __n),
3966 inline constexpr _Counted counted{};
3967 } // namespace views
3970 requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
3971 class common_view : public view_interface<common_view<_Vp>>
3974 _Vp _M_base = _Vp();
3977 common_view() requires default_initializable<_Vp> = default;
3980 common_view(_Vp __r)
3981 : _M_base(std::move(__r))
3985 base() const& requires copy_constructible<_Vp>
3990 { return std::move(_M_base); }
3992 // _GLIBCXX_RESOLVE_LIB_DEFECTS
3993 // 4012. common_view::begin/end are missing the simple-view check
3995 begin() requires (!__detail::__simple_view<_Vp>)
3997 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
3998 return ranges::begin(_M_base);
4000 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4001 (ranges::begin(_M_base));
4005 begin() const requires range<const _Vp>
4007 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4008 return ranges::begin(_M_base);
4010 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4011 (ranges::begin(_M_base));
4015 end() requires (!__detail::__simple_view<_Vp>)
4017 if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
4018 return ranges::begin(_M_base) + ranges::size(_M_base);
4020 return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
4021 (ranges::end(_M_base));
4025 end() const requires range<const _Vp>
4027 if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
4028 return ranges::begin(_M_base) + ranges::size(_M_base);
4030 return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
4031 (ranges::end(_M_base));
4035 size() requires sized_range<_Vp>
4036 { return ranges::size(_M_base); }
4039 size() const requires sized_range<const _Vp>
4040 { return ranges::size(_M_base); }
4043 template<typename _Range>
4044 common_view(_Range&&) -> common_view<views::all_t<_Range>>;
4046 template<typename _Tp>
4047 inline constexpr bool enable_borrowed_range<common_view<_Tp>>
4048 = enable_borrowed_range<_Tp>;
4054 template<typename _Range>
4055 concept __already_common = common_range<_Range>
4056 && requires { views::all(std::declval<_Range>()); };
4058 template<typename _Range>
4059 concept __can_common_view
4060 = requires { common_view{std::declval<_Range>()}; };
4061 } // namespace __detail
4063 struct _Common : __adaptor::_RangeAdaptorClosure<_Common>
4065 template<viewable_range _Range>
4066 requires __detail::__already_common<_Range>
4067 || __detail::__can_common_view<_Range>
4069 operator() [[nodiscard]] (_Range&& __r) const
4071 if constexpr (__detail::__already_common<_Range>)
4072 return views::all(std::forward<_Range>(__r));
4074 return common_view{std::forward<_Range>(__r)};
4077 static constexpr bool _S_has_simple_call_op = true;
4080 inline constexpr _Common common;
4081 } // namespace views
4084 requires bidirectional_range<_Vp>
4085 class reverse_view : public view_interface<reverse_view<_Vp>>
4088 static constexpr bool _S_needs_cached_begin
4089 = !common_range<_Vp> && !(random_access_range<_Vp>
4090 && sized_sentinel_for<sentinel_t<_Vp>,
4093 _Vp _M_base = _Vp();
4094 [[no_unique_address]]
4095 __detail::__maybe_present_t<_S_needs_cached_begin,
4096 __detail::_CachedPosition<_Vp>>
4100 reverse_view() requires default_initializable<_Vp> = default;
4103 reverse_view(_Vp __r)
4104 : _M_base(std::move(__r))
4108 base() const& requires copy_constructible<_Vp>
4113 { return std::move(_M_base); }
4115 constexpr reverse_iterator<iterator_t<_Vp>>
4118 if constexpr (_S_needs_cached_begin)
4119 if (_M_cached_begin._M_has_value())
4120 return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));
4122 auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
4123 if constexpr (_S_needs_cached_begin)
4124 _M_cached_begin._M_set(_M_base, __it);
4125 return std::make_reverse_iterator(std::move(__it));
4129 begin() requires common_range<_Vp>
4130 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4133 begin() const requires common_range<const _Vp>
4134 { return std::make_reverse_iterator(ranges::end(_M_base)); }
4136 constexpr reverse_iterator<iterator_t<_Vp>>
4138 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4141 end() const requires common_range<const _Vp>
4142 { return std::make_reverse_iterator(ranges::begin(_M_base)); }
4145 size() requires sized_range<_Vp>
4146 { return ranges::size(_M_base); }
4149 size() const requires sized_range<const _Vp>
4150 { return ranges::size(_M_base); }
4153 template<typename _Range>
4154 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
4156 template<typename _Tp>
4157 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
4158 = enable_borrowed_range<_Tp>;
4165 inline constexpr bool __is_reversible_subrange = false;
4167 template<typename _Iter, subrange_kind _Kind>
4168 inline constexpr bool
4169 __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
4170 reverse_iterator<_Iter>,
4174 inline constexpr bool __is_reverse_view = false;
4176 template<typename _Vp>
4177 inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;
4179 template<typename _Range>
4180 concept __can_reverse_view
4181 = requires { reverse_view{std::declval<_Range>()}; };
4182 } // namespace __detail
4184 struct _Reverse : __adaptor::_RangeAdaptorClosure<_Reverse>
4186 template<viewable_range _Range>
4187 requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
4188 || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
4189 || __detail::__can_reverse_view<_Range>
4191 operator() [[nodiscard]] (_Range&& __r) const
4193 using _Tp = remove_cvref_t<_Range>;
4194 if constexpr (__detail::__is_reverse_view<_Tp>)
4195 return std::forward<_Range>(__r).base();
4196 else if constexpr (__detail::__is_reversible_subrange<_Tp>)
4198 using _Iter = decltype(ranges::begin(__r).base());
4199 if constexpr (sized_range<_Tp>)
4200 return subrange<_Iter, _Iter, subrange_kind::sized>
4201 {__r.end().base(), __r.begin().base(), __r.size()};
4203 return subrange<_Iter, _Iter, subrange_kind::unsized>
4204 {__r.end().base(), __r.begin().base()};
4207 return reverse_view{std::forward<_Range>(__r)};
4210 static constexpr bool _S_has_simple_call_op = true;
4213 inline constexpr _Reverse reverse;
4214 } // namespace views
4218#if __cpp_lib_tuple_like // >= C++23
4219 template<typename _Tp, size_t _Nm>
4220 concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
4222 template<typename _Tp, size_t _Nm>
4223 concept __has_tuple_element = requires(_Tp __t)
4225 typename tuple_size<_Tp>::type;
4226 requires _Nm < tuple_size_v<_Tp>;
4227 typename tuple_element_t<_Nm, _Tp>;
4228 { std::get<_Nm>(__t) }
4229 -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
4233 template<typename _Tp, size_t _Nm>
4234 concept __returnable_element
4235 = is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
4238 template<input_range _Vp, size_t _Nm>
4240 && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
4241 && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
4243 && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
4244 class elements_view : public view_interface<elements_view<_Vp, _Nm>>
4247 elements_view() requires default_initializable<_Vp> = default;
4250 elements_view(_Vp __base)
4251 : _M_base(std::move(__base))
4255 base() const& requires copy_constructible<_Vp>
4260 { return std::move(_M_base); }
4263 begin() requires (!__detail::__simple_view<_Vp>)
4264 { return _Iterator<false>(ranges::begin(_M_base)); }
4267 begin() const requires range<const _Vp>
4268 { return _Iterator<true>(ranges::begin(_M_base)); }
4271 end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
4272 { return _Sentinel<false>{ranges::end(_M_base)}; }
4275 end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
4276 { return _Iterator<false>{ranges::end(_M_base)}; }
4279 end() const requires range<const _Vp>
4280 { return _Sentinel<true>{ranges::end(_M_base)}; }
4283 end() const requires common_range<const _Vp>
4284 { return _Iterator<true>{ranges::end(_M_base)}; }
4287 size() requires sized_range<_Vp>
4288 { return ranges::size(_M_base); }
4291 size() const requires sized_range<const _Vp>
4292 { return ranges::size(_M_base); }
4295 template<bool _Const>
4296 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
4298 template<bool _Const>
4302 template<bool _Const>
4303 requires forward_range<_Base<_Const>>
4304 struct __iter_cat<_Const>
4307 static auto _S_iter_cat()
4309 using _Base = elements_view::_Base<_Const>;
4310 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
4311 using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
4312 if constexpr (!is_lvalue_reference_v<_Res>)
4313 return input_iterator_tag{};
4314 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
4315 return random_access_iterator_tag{};
4320 using iterator_category = decltype(_S_iter_cat());
4323 template<bool _Const>
4326 template<bool _Const>
4327 struct _Iterator : __iter_cat<_Const>
4330 using _Base = elements_view::_Base<_Const>;
4332 iterator_t<_Base> _M_current = iterator_t<_Base>();
4334 static constexpr decltype(auto)
4335 _S_get_element(const iterator_t<_Base>& __i)
4337 if constexpr (is_reference_v<range_reference_t<_Base>>)
4338 return std::get<_Nm>(*__i);
4341 using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
4342 return static_cast<_Et>(std::get<_Nm>(*__i));
4349 if constexpr (random_access_range<_Base>)
4350 return random_access_iterator_tag{};
4351 else if constexpr (bidirectional_range<_Base>)
4352 return bidirectional_iterator_tag{};
4353 else if constexpr (forward_range<_Base>)
4354 return forward_iterator_tag{};
4356 return input_iterator_tag{};
4359 friend _Iterator<!_Const>;
4362 using iterator_concept = decltype(_S_iter_concept());
4363 // iterator_category defined in elements_view::__iter_cat
4365 = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
4366 using difference_type = range_difference_t<_Base>;
4368 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
4371 _Iterator(iterator_t<_Base> __current)
4372 : _M_current(std::move(__current))
4376 _Iterator(_Iterator<!_Const> __i)
4377 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
4378 : _M_current(std::move(__i._M_current))
4381 constexpr const iterator_t<_Base>&
4382 base() const& noexcept
4383 { return _M_current; }
4385 constexpr iterator_t<_Base>
4387 { return std::move(_M_current); }
4389 constexpr decltype(auto)
4391 { return _S_get_element(_M_current); }
4393 constexpr _Iterator&
4405 operator++(int) requires forward_range<_Base>
4412 constexpr _Iterator&
4413 operator--() requires bidirectional_range<_Base>
4420 operator--(int) requires bidirectional_range<_Base>
4427 constexpr _Iterator&
4428 operator+=(difference_type __n)
4429 requires random_access_range<_Base>
4435 constexpr _Iterator&
4436 operator-=(difference_type __n)
4437 requires random_access_range<_Base>
4443 constexpr decltype(auto)
4444 operator[](difference_type __n) const
4445 requires random_access_range<_Base>
4446 { return _S_get_element(_M_current + __n); }
4448 friend constexpr bool
4449 operator==(const _Iterator& __x, const _Iterator& __y)
4450 requires equality_comparable<iterator_t<_Base>>
4451 { return __x._M_current == __y._M_current; }
4453 friend constexpr bool
4454 operator<(const _Iterator& __x, const _Iterator& __y)
4455 requires random_access_range<_Base>
4456 { return __x._M_current < __y._M_current; }
4458 friend constexpr bool
4459 operator>(const _Iterator& __x, const _Iterator& __y)
4460 requires random_access_range<_Base>
4461 { return __y._M_current < __x._M_current; }
4463 friend constexpr bool
4464 operator<=(const _Iterator& __x, const _Iterator& __y)
4465 requires random_access_range<_Base>
4466 { return !(__y._M_current > __x._M_current); }
4468 friend constexpr bool
4469 operator>=(const _Iterator& __x, const _Iterator& __y)
4470 requires random_access_range<_Base>
4471 { return !(__x._M_current > __y._M_current); }
4473#ifdef __cpp_lib_three_way_comparison
4474 friend constexpr auto
4475 operator<=>(const _Iterator& __x, const _Iterator& __y)
4476 requires random_access_range<_Base>
4477 && three_way_comparable<iterator_t<_Base>>
4478 { return __x._M_current <=> __y._M_current; }
4481 friend constexpr _Iterator
4482 operator+(const _Iterator& __x, difference_type __y)
4483 requires random_access_range<_Base>
4484 { return _Iterator{__x} += __y; }
4486 friend constexpr _Iterator
4487 operator+(difference_type __x, const _Iterator& __y)
4488 requires random_access_range<_Base>
4489 { return __y + __x; }
4491 friend constexpr _Iterator
4492 operator-(const _Iterator& __x, difference_type __y)
4493 requires random_access_range<_Base>
4494 { return _Iterator{__x} -= __y; }
4496 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4497 // 3483. transform_view::iterator's difference is overconstrained
4498 friend constexpr difference_type
4499 operator-(const _Iterator& __x, const _Iterator& __y)
4500 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
4501 { return __x._M_current - __y._M_current; }
4503 template <bool> friend struct _Sentinel;
4506 template<bool _Const>
4510 template<bool _Const2>
4512 _M_equal(const _Iterator<_Const2>& __x) const
4513 { return __x._M_current == _M_end; }
4515 template<bool _Const2>
4517 _M_distance_from(const _Iterator<_Const2>& __i) const
4518 { return _M_end - __i._M_current; }
4520 using _Base = elements_view::_Base<_Const>;
4521 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
4524 _Sentinel() = default;
4527 _Sentinel(sentinel_t<_Base> __end)
4528 : _M_end(std::move(__end))
4532 _Sentinel(_Sentinel<!_Const> __other)
4534 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
4535 : _M_end(std::move(__other._M_end))
4538 constexpr sentinel_t<_Base>
4542 template<bool _Const2>
4543 requires sentinel_for<sentinel_t<_Base>,
4544 iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
4545 friend constexpr bool
4546 operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4547 { return __y._M_equal(__x); }
4549 template<bool _Const2,
4550 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4551 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4552 friend constexpr range_difference_t<_Base2>
4553 operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
4554 { return -__y._M_distance_from(__x); }
4556 template<bool _Const2,
4557 typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
4558 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
4559 friend constexpr range_difference_t<_Base2>
4560 operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
4561 { return __x._M_distance_from(__y); }
4563 friend _Sentinel<!_Const>;
4566 _Vp _M_base = _Vp();
4569 template<typename _Tp, size_t _Nm>
4570 inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
4571 = enable_borrowed_range<_Tp>;
4573 // _GLIBCXX_RESOLVE_LIB_DEFECTS
4574 // 3563. keys_view example is broken
4575 template<typename _Range>
4576 using keys_view = elements_view<_Range, 0>;
4578 template<typename _Range>
4579 using values_view = elements_view<_Range, 1>;
4585 template<size_t _Nm, typename _Range>
4586 concept __can_elements_view
4587 = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
4588 } // namespace __detail
4590 template<size_t _Nm>
4591 struct _Elements : __adaptor::_RangeAdaptorClosure<_Elements<_Nm>>
4593 template<viewable_range _Range>
4594 requires __detail::__can_elements_view<_Nm, _Range>
4596 operator() [[nodiscard]] (_Range&& __r) const
4598 return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
4601 static constexpr bool _S_has_simple_call_op = true;
4604 template<size_t _Nm>
4605 inline constexpr _Elements<_Nm> elements;
4606 inline constexpr auto keys = elements<0>;
4607 inline constexpr auto values = elements<1>;
4608 } // namespace views
4610#ifdef __cpp_lib_ranges_zip // C++ >= 23
4613 template<typename... _Rs>
4614 concept __zip_is_common = (sizeof...(_Rs) == 1 && (common_range<_Rs> && ...))
4615 || (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
4616 || ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
4618 template<typename _Fp, typename _Tuple>
4620 __tuple_transform(_Fp&& __f, _Tuple&& __tuple)
4622 return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4623 return tuple<invoke_result_t<_Fp&, _Ts>...>
4624 (std::__invoke(__f, std::forward<_Ts>(__elts))...);
4625 }, std::forward<_Tuple>(__tuple));
4628 template<typename _Fp, typename _Tuple>
4630 __tuple_for_each(_Fp&& __f, _Tuple&& __tuple)
4632 std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
4633 (std::__invoke(__f, std::forward<_Ts>(__elts)), ...);
4634 }, std::forward<_Tuple>(__tuple));
4636 } // namespace __detail
4638 template<input_range... _Vs>
4639 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4640 class zip_view : public view_interface<zip_view<_Vs...>>
4642 tuple<_Vs...> _M_views;
4644 template<bool> class _Iterator;
4645 template<bool> class _Sentinel;
4648 zip_view() = default;
4651 zip_view(_Vs... __views)
4652 : _M_views(std::move(__views)...)
4656 begin() requires (!(__detail::__simple_view<_Vs> && ...))
4657 { return _Iterator<false>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4660 begin() const requires (range<const _Vs> && ...)
4661 { return _Iterator<true>(__detail::__tuple_transform(ranges::begin, _M_views)); }
4664 end() requires (!(__detail::__simple_view<_Vs> && ...))
4666 if constexpr (!__detail::__zip_is_common<_Vs...>)
4667 return _Sentinel<false>(__detail::__tuple_transform(ranges::end, _M_views));
4668 else if constexpr ((random_access_range<_Vs> && ...))
4669 return begin() + iter_difference_t<_Iterator<false>>(size());
4671 return _Iterator<false>(__detail::__tuple_transform(ranges::end, _M_views));
4675 end() const requires (range<const _Vs> && ...)
4677 if constexpr (!__detail::__zip_is_common<const _Vs...>)
4678 return _Sentinel<true>(__detail::__tuple_transform(ranges::end, _M_views));
4679 else if constexpr ((random_access_range<const _Vs> && ...))
4680 return begin() + iter_difference_t<_Iterator<true>>(size());
4682 return _Iterator<true>(__detail::__tuple_transform(ranges::end, _M_views));
4686 size() requires (sized_range<_Vs> && ...)
4688 return std::apply([](auto... sizes) {
4689 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4690 return ranges::min({_CT(sizes)...});
4691 }, __detail::__tuple_transform(ranges::size, _M_views));
4695 size() const requires (sized_range<const _Vs> && ...)
4697 return std::apply([](auto... sizes) {
4698 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(sizes)...>>;
4699 return ranges::min({_CT(sizes)...});
4700 }, __detail::__tuple_transform(ranges::size, _M_views));
4704 template<typename... _Rs>
4705 zip_view(_Rs&&...) -> zip_view<views::all_t<_Rs>...>;
4707 template<typename... _Views>
4708 inline constexpr bool enable_borrowed_range<zip_view<_Views...>>
4709 = (enable_borrowed_range<_Views> && ...);
4713 template<bool _Const, typename... _Vs>
4714 concept __all_random_access
4715 = (random_access_range<__maybe_const_t<_Const, _Vs>> && ...);
4717 template<bool _Const, typename... _Vs>
4718 concept __all_bidirectional
4719 = (bidirectional_range<__maybe_const_t<_Const, _Vs>> && ...);
4721 template<bool _Const, typename... _Vs>
4722 concept __all_forward
4723 = (forward_range<__maybe_const_t<_Const, _Vs>> && ...);
4725 template<bool _Const, typename... _Views>
4726 struct __zip_view_iter_cat
4729 template<bool _Const, typename... _Views>
4730 requires __all_forward<_Const, _Views...>
4731 struct __zip_view_iter_cat<_Const, _Views...>
4732 { using iterator_category = input_iterator_tag; };
4733 } // namespace __detail
4735 template<input_range... _Vs>
4736 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4737 template<bool _Const>
4738 class zip_view<_Vs...>::_Iterator
4739 : public __detail::__zip_view_iter_cat<_Const, _Vs...>
4741#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
4744 tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
4747 _Iterator(decltype(_M_current) __current)
4748 : _M_current(std::move(__current))
4754 if constexpr (__detail::__all_random_access<_Const, _Vs...>)
4755 return random_access_iterator_tag{};
4756 else if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4757 return bidirectional_iterator_tag{};
4758 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
4759 return forward_iterator_tag{};
4761 return input_iterator_tag{};
4764#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
4765 template<move_constructible _Fp, input_range... _Ws>
4766 requires (view<_Ws> && ...) && (sizeof...(_Ws) > 0) && is_object_v<_Fp>
4767 && regular_invocable<_Fp&, range_reference_t<_Ws>...>
4768 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Ws>...>>
4769 friend class zip_transform_view;
4773 // iterator_category defined in __zip_view_iter_cat
4774 using iterator_concept = decltype(_S_iter_concept());
4776 = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4777 using difference_type
4778 = common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
4780 _Iterator() = default;
4783 _Iterator(_Iterator<!_Const> __i)
4785 && (convertible_to<iterator_t<_Vs>,
4786 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4787 : _M_current(std::move(__i._M_current))
4793 auto __f = [](auto& __i) -> decltype(auto) {
4796 return __detail::__tuple_transform(__f, _M_current);
4799 constexpr _Iterator&
4802 __detail::__tuple_for_each([](auto& __i) { ++__i; }, _M_current);
4812 requires __detail::__all_forward<_Const, _Vs...>
4819 constexpr _Iterator&
4821 requires __detail::__all_bidirectional<_Const, _Vs...>
4823 __detail::__tuple_for_each([](auto& __i) { --__i; }, _M_current);
4829 requires __detail::__all_bidirectional<_Const, _Vs...>
4836 constexpr _Iterator&
4837 operator+=(difference_type __x)
4838 requires __detail::__all_random_access<_Const, _Vs...>
4840 auto __f = [&]<typename _It>(_It& __i) {
4841 __i += iter_difference_t<_It>(__x);
4843 __detail::__tuple_for_each(__f, _M_current);
4847 constexpr _Iterator&
4848 operator-=(difference_type __x)
4849 requires __detail::__all_random_access<_Const, _Vs...>
4851 auto __f = [&]<typename _It>(_It& __i) {
4852 __i -= iter_difference_t<_It>(__x);
4854 __detail::__tuple_for_each(__f, _M_current);
4859 operator[](difference_type __n) const
4860 requires __detail::__all_random_access<_Const, _Vs...>
4862 auto __f = [&]<typename _It>(_It& __i) -> decltype(auto) {
4863 return __i[iter_difference_t<_It>(__n)];
4865 return __detail::__tuple_transform(__f, _M_current);
4868 friend constexpr bool
4869 operator==(const _Iterator& __x, const _Iterator& __y)
4870 requires (equality_comparable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4872 if constexpr (__detail::__all_bidirectional<_Const, _Vs...>)
4873 return __x._M_current == __y._M_current;
4875 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4876 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_current)) || ...);
4877 }(make_index_sequence<sizeof...(_Vs)>{});
4880 friend constexpr auto
4881 operator<=>(const _Iterator& __x, const _Iterator& __y)
4882 requires __detail::__all_random_access<_Const, _Vs...>
4883 { return __x._M_current <=> __y._M_current; }
4885 friend constexpr _Iterator
4886 operator+(const _Iterator& __i, difference_type __n)
4887 requires __detail::__all_random_access<_Const, _Vs...>
4894 friend constexpr _Iterator
4895 operator+(difference_type __n, const _Iterator& __i)
4896 requires __detail::__all_random_access<_Const, _Vs...>
4903 friend constexpr _Iterator
4904 operator-(const _Iterator& __i, difference_type __n)
4905 requires __detail::__all_random_access<_Const, _Vs...>
4912 friend constexpr difference_type
4913 operator-(const _Iterator& __x, const _Iterator& __y)
4914 requires (sized_sentinel_for<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>,
4915 iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4917 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4918 return ranges::min({difference_type(std::get<_Is>(__x._M_current)
4919 - std::get<_Is>(__y._M_current))...},
4921 [](difference_type __i) {
4922 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4924 }(make_index_sequence<sizeof...(_Vs)>{});
4927 friend constexpr auto
4928 iter_move(const _Iterator& __i)
4929 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
4931 friend constexpr void
4932 iter_swap(const _Iterator& __l, const _Iterator& __r)
4933 requires (indirectly_swappable<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4935 [&]<size_t... _Is>(index_sequence<_Is...>) {
4936 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
4937 }(make_index_sequence<sizeof...(_Vs)>{});
4940 friend class zip_view;
4943 template<input_range... _Vs>
4944 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0)
4945 template<bool _Const>
4946 class zip_view<_Vs...>::_Sentinel
4948 tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
4951 _Sentinel(decltype(_M_end) __end)
4955 friend class zip_view;
4958 _Sentinel() = default;
4961 _Sentinel(_Sentinel<!_Const> __i)
4963 && (convertible_to<sentinel_t<_Vs>,
4964 sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>> && ...)
4965 : _M_end(std::move(__i._M_end))
4968 template<bool _OtherConst>
4969 requires (sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4970 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4971 friend constexpr bool
4972 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4974 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4975 return ((std::get<_Is>(__x._M_current) == std::get<_Is>(__y._M_end)) || ...);
4976 }(make_index_sequence<sizeof...(_Vs)>{});
4979 template<bool _OtherConst>
4980 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4981 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4982 friend constexpr auto
4983 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
4986 = common_type_t<range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vs>>...>;
4987 return [&]<size_t... _Is>(index_sequence<_Is...>) {
4988 return ranges::min({_Ret(std::get<_Is>(__x._M_current) - std::get<_Is>(__y._M_end))...},
4991 return __detail::__to_unsigned_like(__i < 0 ? -__i : __i);
4993 }(make_index_sequence<sizeof...(_Vs)>{});
4996 template<bool _OtherConst>
4997 requires (sized_sentinel_for<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>,
4998 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vs>>> && ...)
4999 friend constexpr auto
5000 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5001 { return -(__x - __y); }
5008 template<typename... _Ts>
5009 concept __can_zip_view
5010 = requires { zip_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
5015 template<typename... _Ts>
5016 requires (sizeof...(_Ts) == 0 || __detail::__can_zip_view<_Ts...>)
5018 operator() [[nodiscard]] (_Ts&&... __ts) const
5020 if constexpr (sizeof...(_Ts) == 0)
5021 return views::empty<tuple<>>;
5023 return zip_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
5027 inline constexpr _Zip zip;
5032 template<typename _Range, bool _Const>
5033 using __range_iter_cat
5034 = typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Range>>>::iterator_category;
5037 template<move_constructible _Fp, input_range... _Vs>
5038 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5039 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5040 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5041 class zip_transform_view : public view_interface<zip_transform_view<_Fp, _Vs...>>
5043 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5044 zip_view<_Vs...> _M_zip;
5046 using _InnerView = zip_view<_Vs...>;
5048 template<bool _Const>
5049 using __ziperator = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5051 template<bool _Const>
5052 using __zentinel = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5054 template<bool _Const>
5055 using _Base = __detail::__maybe_const_t<_Const, _InnerView>;
5057 template<bool _Const>
5061 template<bool _Const>
5062 requires forward_range<_Base<_Const>>
5063 struct __iter_cat<_Const>
5069 using __detail::__maybe_const_t;
5070 using __detail::__range_iter_cat;
5071 using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
5072 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
5073 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5074 // 3798. Rvalue reference and iterator_category
5075 if constexpr (!is_reference_v<_Res>)
5076 return input_iterator_tag{};
5077 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5078 random_access_iterator_tag> && ...))
5079 return random_access_iterator_tag{};
5080 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5081 bidirectional_iterator_tag> && ...))
5082 return bidirectional_iterator_tag{};
5083 else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>,
5084 forward_iterator_tag> && ...))
5085 return forward_iterator_tag{};
5087 return input_iterator_tag{};
5090 using iterator_category = decltype(_S_iter_cat());
5093 template<bool> class _Iterator;
5094 template<bool> class _Sentinel;
5097 zip_transform_view() = default;
5100 zip_transform_view(_Fp __fun, _Vs... __views)
5101 : _M_fun(std::move(__fun)), _M_zip(std::move(__views)...)
5106 { return _Iterator<false>(*this, _M_zip.begin()); }
5110 requires range<const _InnerView>
5111 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5112 { return _Iterator<true>(*this, _M_zip.begin()); }
5117 if constexpr (common_range<_InnerView>)
5118 return _Iterator<false>(*this, _M_zip.end());
5120 return _Sentinel<false>(_M_zip.end());
5125 requires range<const _InnerView>
5126 && regular_invocable<const _Fp&, range_reference_t<const _Vs>...>
5128 if constexpr (common_range<const _InnerView>)
5129 return _Iterator<true>(*this, _M_zip.end());
5131 return _Sentinel<true>(_M_zip.end());
5135 size() requires sized_range<_InnerView>
5136 { return _M_zip.size(); }
5139 size() const requires sized_range<const _InnerView>
5140 { return _M_zip.size(); }
5143 template<class _Fp, class... Rs>
5144 zip_transform_view(_Fp, Rs&&...) -> zip_transform_view<_Fp, views::all_t<Rs>...>;
5146 template<move_constructible _Fp, input_range... _Vs>
5147 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5148 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5149 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5150 template<bool _Const>
5151 class zip_transform_view<_Fp, _Vs...>::_Iterator : public __iter_cat<_Const>
5153 using _Parent = __detail::__maybe_const_t<_Const, zip_transform_view>;
5155 _Parent* _M_parent = nullptr;
5156 __ziperator<_Const> _M_inner;
5159 _Iterator(_Parent& __parent, __ziperator<_Const> __inner)
5160 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5163 friend class zip_transform_view;
5166 // iterator_category defined in zip_transform_view::__iter_cat
5167 using iterator_concept = typename __ziperator<_Const>::iterator_concept;
5169 = remove_cvref_t<invoke_result_t<__detail::__maybe_const_t<_Const, _Fp>&,
5170 range_reference_t<__detail::__maybe_const_t<_Const, _Vs>>...>>;
5171 using difference_type = range_difference_t<_Base<_Const>>;
5173 _Iterator() = default;
5176 _Iterator(_Iterator<!_Const> __i)
5177 requires _Const && convertible_to<__ziperator<false>, __ziperator<_Const>>
5178 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5181 constexpr decltype(auto)
5184 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5185 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5186 }, _M_inner._M_current);
5189 constexpr _Iterator&
5201 operator++(int) requires forward_range<_Base<_Const>>
5208 constexpr _Iterator&
5209 operator--() requires bidirectional_range<_Base<_Const>>
5216 operator--(int) requires bidirectional_range<_Base<_Const>>
5223 constexpr _Iterator&
5224 operator+=(difference_type __x) requires random_access_range<_Base<_Const>>
5230 constexpr _Iterator&
5231 operator-=(difference_type __x) requires random_access_range<_Base<_Const>>
5237 constexpr decltype(auto)
5238 operator[](difference_type __n) const requires random_access_range<_Base<_Const>>
5240 return std::apply([&]<typename... _Is>(const _Is&... __iters) -> decltype(auto) {
5241 return std::__invoke(*_M_parent->_M_fun, __iters[iter_difference_t<_Is>(__n)]...);
5242 }, _M_inner._M_current);
5245 friend constexpr bool
5246 operator==(const _Iterator& __x, const _Iterator& __y)
5247 requires equality_comparable<__ziperator<_Const>>
5248 { return __x._M_inner == __y._M_inner; }
5250 friend constexpr auto
5251 operator<=>(const _Iterator& __x, const _Iterator& __y)
5252 requires random_access_range<_Base<_Const>>
5253 { return __x._M_inner <=> __y._M_inner; }
5255 friend constexpr _Iterator
5256 operator+(const _Iterator& __i, difference_type __n)
5257 requires random_access_range<_Base<_Const>>
5258 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5260 friend constexpr _Iterator
5261 operator+(difference_type __n, const _Iterator& __i)
5262 requires random_access_range<_Base<_Const>>
5263 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5265 friend constexpr _Iterator
5266 operator-(const _Iterator& __i, difference_type __n)
5267 requires random_access_range<_Base<_Const>>
5268 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5270 friend constexpr difference_type
5271 operator-(const _Iterator& __x, const _Iterator& __y)
5272 requires sized_sentinel_for<__ziperator<_Const>, __ziperator<_Const>>
5273 { return __x._M_inner - __y._M_inner; }
5276 template<move_constructible _Fp, input_range... _Vs>
5277 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && is_object_v<_Fp>
5278 && regular_invocable<_Fp&, range_reference_t<_Vs>...>
5279 && std::__detail::__can_reference<invoke_result_t<_Fp&, range_reference_t<_Vs>...>>
5280 template<bool _Const>
5281 class zip_transform_view<_Fp, _Vs...>::_Sentinel
5283 __zentinel<_Const> _M_inner;
5286 _Sentinel(__zentinel<_Const> __inner)
5290 friend class zip_transform_view;
5293 _Sentinel() = default;
5296 _Sentinel(_Sentinel<!_Const> __i)
5297 requires _Const && convertible_to<__zentinel<false>, __zentinel<_Const>>
5298 : _M_inner(std::move(__i._M_inner))
5301 template<bool _OtherConst>
5302 requires sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5303 friend constexpr bool
5304 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5305 { return __x._M_inner == __y._M_inner; }
5307 template<bool _OtherConst>
5308 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5309 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5310 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5311 { return __x._M_inner - __y._M_inner; }
5313 template<bool _OtherConst>
5314 requires sized_sentinel_for<__zentinel<_Const>, __ziperator<_OtherConst>>
5315 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
5316 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
5317 { return __x._M_inner - __y._M_inner; }
5324 template<typename _Fp, typename... _Ts>
5325 concept __can_zip_transform_view
5326 = requires { zip_transform_view(std::declval<_Fp>(), std::declval<_Ts>()...); };
5329 struct _ZipTransform
5331 template<typename _Fp, typename... _Ts>
5332 requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...>
5334 operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
5336 if constexpr (sizeof...(_Ts) == 0)
5337 return views::empty<decay_t<invoke_result_t<decay_t<_Fp>&>>>;
5339 return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...);
5343 inline constexpr _ZipTransform zip_transform;
5346 template<forward_range _Vp, size_t _Nm>
5347 requires view<_Vp> && (_Nm > 0)
5348 class adjacent_view : public view_interface<adjacent_view<_Vp, _Nm>>
5350 _Vp _M_base = _Vp();
5352 template<bool> class _Iterator;
5353 template<bool> class _Sentinel;
5355 struct __as_sentinel
5359 adjacent_view() requires default_initializable<_Vp> = default;
5362 adjacent_view(_Vp __base)
5363 : _M_base(std::move(__base))
5366 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5367 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5369 base() const & requires copy_constructible<_Vp>
5374 { return std::move(_M_base); }
5377 begin() requires (!__detail::__simple_view<_Vp>)
5378 { return _Iterator<false>(ranges::begin(_M_base), ranges::end(_M_base)); }
5381 begin() const requires range<const _Vp>
5382 { return _Iterator<true>(ranges::begin(_M_base), ranges::end(_M_base)); }
5385 end() requires (!__detail::__simple_view<_Vp>)
5387 if constexpr (common_range<_Vp>)
5388 return _Iterator<false>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5390 return _Sentinel<false>(ranges::end(_M_base));
5394 end() const requires range<const _Vp>
5396 if constexpr (common_range<const _Vp>)
5397 return _Iterator<true>(__as_sentinel{}, ranges::begin(_M_base), ranges::end(_M_base));
5399 return _Sentinel<true>(ranges::end(_M_base));
5403 size() requires sized_range<_Vp>
5405 using _ST = decltype(ranges::size(_M_base));
5406 using _CT = common_type_t<_ST, size_t>;
5407 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5408 __sz -= std::min<_CT>(__sz, _Nm - 1);
5409 return static_cast<_ST>(__sz);
5413 size() const requires sized_range<const _Vp>
5415 using _ST = decltype(ranges::size(_M_base));
5416 using _CT = common_type_t<_ST, size_t>;
5417 auto __sz = static_cast<_CT>(ranges::size(_M_base));
5418 __sz -= std::min<_CT>(__sz, _Nm - 1);
5419 return static_cast<_ST>(__sz);
5423 template<typename _Vp, size_t _Nm>
5424 inline constexpr bool enable_borrowed_range<adjacent_view<_Vp, _Nm>>
5425 = enable_borrowed_range<_Vp>;
5429 // Yields tuple<_Tp, ..., _Tp> with _Nm elements.
5430 template<typename _Tp, size_t _Nm>
5431 using __repeated_tuple = decltype(std::tuple_cat(std::declval<array<_Tp, _Nm>>()));
5433 // For a functor F that is callable with N arguments, the expression
5434 // declval<__unarize<F, N>>(x) is equivalent to declval<F>(x, ..., x).
5435 template<typename _Fp, size_t _Nm>
5438 template<typename... _Ts>
5439 static invoke_result_t<_Fp, _Ts...>
5440 __tuple_apply(const tuple<_Ts...>&); // not defined
5442 template<typename _Tp>
5443 decltype(__tuple_apply(std::declval<__repeated_tuple<_Tp, _Nm>>()))
5444 operator()(_Tp&&); // not defined
5448 template<forward_range _Vp, size_t _Nm>
5449 requires view<_Vp> && (_Nm > 0)
5450 template<bool _Const>
5451 class adjacent_view<_Vp, _Nm>::_Iterator
5453#ifdef _GLIBCXX_CLANG // LLVM-61763 workaround
5456 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5457 array<iterator_t<_Base>, _Nm> _M_current = array<iterator_t<_Base>, _Nm>();
5460 _Iterator(iterator_t<_Base> __first, sentinel_t<_Base> __last)
5462 for (auto& __i : _M_current)
5465 ranges::advance(__first, 1, __last);
5470 _Iterator(__as_sentinel, iterator_t<_Base> __first, iterator_t<_Base> __last)
5472 if constexpr (!bidirectional_range<_Base>)
5473 for (auto& __it : _M_current)
5476 for (size_t __i = 0; __i < _Nm; ++__i)
5478 _M_current[_Nm - 1 - __i] = __last;
5479 ranges::advance(__last, -1, __first);
5486 if constexpr (random_access_range<_Base>)
5487 return random_access_iterator_tag{};
5488 else if constexpr (bidirectional_range<_Base>)
5489 return bidirectional_iterator_tag{};
5491 return forward_iterator_tag{};
5494 friend class adjacent_view;
5496#ifndef _GLIBCXX_CLANG // LLVM-61763 workaround
5497 template<forward_range _Wp, move_constructible _Fp, size_t _Mm>
5498 requires view<_Wp> && (_Mm > 0) && is_object_v<_Fp>
5499 && regular_invocable<__detail::__unarize<_Fp&, _Mm>, range_reference_t<_Wp>>
5500 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Mm>,
5501 range_reference_t<_Wp>>>
5502 friend class adjacent_transform_view;
5506 using iterator_category = input_iterator_tag;
5507 using iterator_concept = decltype(_S_iter_concept());
5508 using value_type = conditional_t<_Nm == 2,
5509 pair<range_value_t<_Base>, range_value_t<_Base>>,
5510 __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
5511 using difference_type = range_difference_t<_Base>;
5513 _Iterator() = default;
5516 _Iterator(_Iterator<!_Const> __i)
5517 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
5519 for (size_t __j = 0; __j < _Nm; ++__j)
5520 _M_current[__j] = std::move(__i._M_current[__j]);
5526 auto __f = [](auto& __i) -> decltype(auto) { return *__i; };
5527 return __detail::__tuple_transform(__f, _M_current);
5530 constexpr _Iterator&
5533 for (auto& __i : _M_current)
5546 constexpr _Iterator&
5547 operator--() requires bidirectional_range<_Base>
5549 for (auto& __i : _M_current)
5555 operator--(int) requires bidirectional_range<_Base>
5562 constexpr _Iterator&
5563 operator+=(difference_type __x)
5564 requires random_access_range<_Base>
5566 for (auto& __i : _M_current)
5571 constexpr _Iterator&
5572 operator-=(difference_type __x)
5573 requires random_access_range<_Base>
5575 for (auto& __i : _M_current)
5581 operator[](difference_type __n) const
5582 requires random_access_range<_Base>
5584 auto __f = [&](auto& __i) -> decltype(auto) { return __i[__n]; };
5585 return __detail::__tuple_transform(__f, _M_current);
5588 friend constexpr bool
5589 operator==(const _Iterator& __x, const _Iterator& __y)
5590 { return __x._M_current.back() == __y._M_current.back(); }
5592 friend constexpr bool
5593 operator<(const _Iterator& __x, const _Iterator& __y)
5594 requires random_access_range<_Base>
5595 { return __x._M_current.back() < __y._M_current.back(); }
5597 friend constexpr bool
5598 operator>(const _Iterator& __x, const _Iterator& __y)
5599 requires random_access_range<_Base>
5600 { return __y < __x; }
5602 friend constexpr bool
5603 operator<=(const _Iterator& __x, const _Iterator& __y)
5604 requires random_access_range<_Base>
5605 { return !(__y < __x); }
5607 friend constexpr bool
5608 operator>=(const _Iterator& __x, const _Iterator& __y)
5609 requires random_access_range<_Base>
5610 { return !(__x < __y); }
5612 friend constexpr auto
5613 operator<=>(const _Iterator& __x, const _Iterator& __y)
5614 requires random_access_range<_Base>
5615 && three_way_comparable<iterator_t<_Base>>
5616 { return __x._M_current.back() <=> __y._M_current.back(); }
5618 friend constexpr _Iterator
5619 operator+(const _Iterator& __i, difference_type __n)
5620 requires random_access_range<_Base>
5627 friend constexpr _Iterator
5628 operator+(difference_type __n, const _Iterator& __i)
5629 requires random_access_range<_Base>
5636 friend constexpr _Iterator
5637 operator-(const _Iterator& __i, difference_type __n)
5638 requires random_access_range<_Base>
5645 friend constexpr difference_type
5646 operator-(const _Iterator& __x, const _Iterator& __y)
5647 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
5648 { return __x._M_current.back() - __y._M_current.back(); }
5650 friend constexpr auto
5651 iter_move(const _Iterator& __i)
5652 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
5654 friend constexpr void
5655 iter_swap(const _Iterator& __l, const _Iterator& __r)
5656 requires indirectly_swappable<iterator_t<_Base>>
5658 for (size_t __i = 0; __i < _Nm; __i++)
5659 ranges::iter_swap(__l._M_current[__i], __r._M_current[__i]);
5663 template<forward_range _Vp, size_t _Nm>
5664 requires view<_Vp> && (_Nm > 0)
5665 template<bool _Const>
5666 class adjacent_view<_Vp, _Nm>::_Sentinel
5668 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5670 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
5673 _Sentinel(sentinel_t<_Base> __end)
5677 friend class adjacent_view;
5680 _Sentinel() = default;
5683 _Sentinel(_Sentinel<!_Const> __i)
5684 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
5685 : _M_end(std::move(__i._M_end))
5688 template<bool _OtherConst>
5689 requires sentinel_for<sentinel_t<_Base>,
5690 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5691 friend constexpr bool
5692 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5693 { return __x._M_current.back() == __y._M_end; }
5695 template<bool _OtherConst>
5696 requires sized_sentinel_for<sentinel_t<_Base>,
5697 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5698 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5699 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
5700 { return __x._M_current.back() - __y._M_end; }
5702 template<bool _OtherConst>
5703 requires sized_sentinel_for<sentinel_t<_Base>,
5704 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
5705 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _Vp>>
5706 operator-(const _Sentinel& __y, const _Iterator<_OtherConst>& __x)
5707 { return __y._M_end - __x._M_current.back(); }
5714 template<size_t _Nm, typename _Range>
5715 concept __can_adjacent_view
5716 = requires { adjacent_view<all_t<_Range>, _Nm>(std::declval<_Range>()); };
5719 template<size_t _Nm>
5720 struct _Adjacent : __adaptor::_RangeAdaptorClosure<_Adjacent<_Nm>>
5722 template<viewable_range _Range>
5723 requires (_Nm == 0) || __detail::__can_adjacent_view<_Nm, _Range>
5725 operator() [[nodiscard]] (_Range&& __r) const
5727 if constexpr (_Nm == 0)
5728 return views::empty<tuple<>>;
5730 return adjacent_view<all_t<_Range>, _Nm>(std::forward<_Range>(__r));
5734 template<size_t _Nm>
5735 inline constexpr _Adjacent<_Nm> adjacent;
5737 inline constexpr auto pairwise = adjacent<2>;
5740 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5741 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5742 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5743 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5744 range_reference_t<_Vp>>>
5745 class adjacent_transform_view : public view_interface<adjacent_transform_view<_Vp, _Fp, _Nm>>
5747 [[no_unique_address]] __detail::__box<_Fp> _M_fun;
5748 adjacent_view<_Vp, _Nm> _M_inner;
5750 using _InnerView = adjacent_view<_Vp, _Nm>;
5752 template<bool _Const>
5753 using _InnerIter = iterator_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5755 template<bool _Const>
5756 using _InnerSent = sentinel_t<__detail::__maybe_const_t<_Const, _InnerView>>;
5758 template<bool> class _Iterator;
5759 template<bool> class _Sentinel;
5762 adjacent_transform_view() = default;
5765 adjacent_transform_view(_Vp __base, _Fp __fun)
5766 : _M_fun(std::move(__fun)), _M_inner(std::move(__base))
5769 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5770 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
5771 // 3947. Unexpected constraints on adjacent_transform_view::base()
5773 base() const & requires copy_constructible<_Vp>
5774 { return _M_inner.base(); }
5778 { return std::move(_M_inner.base()); }
5782 { return _Iterator<false>(*this, _M_inner.begin()); }
5786 requires range<const _InnerView>
5787 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5788 range_reference_t<const _Vp>>
5789 { return _Iterator<true>(*this, _M_inner.begin()); }
5794 if constexpr (common_range<_InnerView>)
5795 return _Iterator<false>(*this, _M_inner.end());
5797 return _Sentinel<false>(_M_inner.end());
5802 requires range<const _InnerView>
5803 && regular_invocable<__detail::__unarize<const _Fp&, _Nm>,
5804 range_reference_t<const _Vp>>
5806 if constexpr (common_range<const _InnerView>)
5807 return _Iterator<true>(*this, _M_inner.end());
5809 return _Sentinel<true>(_M_inner.end());
5813 size() requires sized_range<_InnerView>
5814 { return _M_inner.size(); }
5817 size() const requires sized_range<const _InnerView>
5818 { return _M_inner.size(); }
5821 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5822 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5823 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5824 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5825 range_reference_t<_Vp>>>
5826 template<bool _Const>
5827 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Iterator
5829 using _Parent = __detail::__maybe_const_t<_Const, adjacent_transform_view>;
5830 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
5832 _Parent* _M_parent = nullptr;
5833 _InnerIter<_Const> _M_inner;
5836 _Iterator(_Parent& __parent, _InnerIter<_Const> __inner)
5837 : _M_parent(std::__addressof(__parent)), _M_inner(std::move(__inner))
5843 using __detail::__maybe_const_t;
5844 using __detail::__unarize;
5845 using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, _Nm>,
5846 range_reference_t<_Base>>;
5847 using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
5848 // _GLIBCXX_RESOLVE_LIB_DEFECTS
5849 // 3798. Rvalue reference and iterator_category
5850 if constexpr (!is_reference_v<_Res>)
5851 return input_iterator_tag{};
5852 else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
5853 return random_access_iterator_tag{};
5854 else if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
5855 return bidirectional_iterator_tag{};
5856 else if constexpr (derived_from<_Cat, forward_iterator_tag>)
5857 return forward_iterator_tag{};
5859 return input_iterator_tag{};
5862 friend class adjacent_transform_view;
5865 using iterator_category = decltype(_S_iter_cat());
5866 using iterator_concept = typename _InnerIter<_Const>::iterator_concept;
5868 = remove_cvref_t<invoke_result_t
5869 <__detail::__unarize<__detail::__maybe_const_t<_Const, _Fp>&, _Nm>,
5870 range_reference_t<_Base>>>;
5871 using difference_type = range_difference_t<_Base>;
5873 _Iterator() = default;
5876 _Iterator(_Iterator<!_Const> __i)
5877 requires _Const && convertible_to<_InnerIter<false>, _InnerIter<_Const>>
5878 : _M_parent(__i._M_parent), _M_inner(std::move(__i._M_inner))
5881 constexpr decltype(auto)
5884 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5885 return std::__invoke(*_M_parent->_M_fun, *__iters...);
5886 }, _M_inner._M_current);
5889 constexpr _Iterator&
5904 constexpr _Iterator&
5905 operator--() requires bidirectional_range<_Base>
5912 operator--(int) requires bidirectional_range<_Base>
5919 constexpr _Iterator&
5920 operator+=(difference_type __x) requires random_access_range<_Base>
5926 constexpr _Iterator&
5927 operator-=(difference_type __x) requires random_access_range<_Base>
5933 constexpr decltype(auto)
5934 operator[](difference_type __n) const requires random_access_range<_Base>
5936 return std::apply([&](const auto&... __iters) -> decltype(auto) {
5937 return std::__invoke(*_M_parent->_M_fun, __iters[__n]...);
5938 }, _M_inner._M_current);
5941 friend constexpr bool
5942 operator==(const _Iterator& __x, const _Iterator& __y)
5943 { return __x._M_inner == __y._M_inner; }
5945 friend constexpr bool
5946 operator<(const _Iterator& __x, const _Iterator& __y)
5947 requires random_access_range<_Base>
5948 { return __x._M_inner < __y._M_inner; }
5950 friend constexpr bool
5951 operator>(const _Iterator& __x, const _Iterator& __y)
5952 requires random_access_range<_Base>
5953 { return __x._M_inner > __y._M_inner; }
5955 friend constexpr bool
5956 operator<=(const _Iterator& __x, const _Iterator& __y)
5957 requires random_access_range<_Base>
5958 { return __x._M_inner <= __y._M_inner; }
5960 friend constexpr bool
5961 operator>=(const _Iterator& __x, const _Iterator& __y)
5962 requires random_access_range<_Base>
5963 { return __x._M_inner >= __y._M_inner; }
5965 friend constexpr auto
5966 operator<=>(const _Iterator& __x, const _Iterator& __y)
5967 requires random_access_range<_Base> &&
5968 three_way_comparable<_InnerIter<_Const>>
5969 { return __x._M_inner <=> __y._M_inner; }
5971 friend constexpr _Iterator
5972 operator+(const _Iterator& __i, difference_type __n)
5973 requires random_access_range<_Base>
5974 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5976 friend constexpr _Iterator
5977 operator+(difference_type __n, const _Iterator& __i)
5978 requires random_access_range<_Base>
5979 { return _Iterator(*__i._M_parent, __i._M_inner + __n); }
5981 friend constexpr _Iterator
5982 operator-(const _Iterator& __i, difference_type __n)
5983 requires random_access_range<_Base>
5984 { return _Iterator(*__i._M_parent, __i._M_inner - __n); }
5986 friend constexpr difference_type
5987 operator-(const _Iterator& __x, const _Iterator& __y)
5988 requires sized_sentinel_for<_InnerIter<_Const>, _InnerIter<_Const>>
5989 { return __x._M_inner - __y._M_inner; }
5992 template<forward_range _Vp, move_constructible _Fp, size_t _Nm>
5993 requires view<_Vp> && (_Nm > 0) && is_object_v<_Fp>
5994 && regular_invocable<__detail::__unarize<_Fp&, _Nm>, range_reference_t<_Vp>>
5995 && std::__detail::__can_reference<invoke_result_t<__detail::__unarize<_Fp&, _Nm>,
5996 range_reference_t<_Vp>>>
5997 template<bool _Const>
5998 class adjacent_transform_view<_Vp, _Fp, _Nm>::_Sentinel
6000 _InnerSent<_Const> _M_inner;
6003 _Sentinel(_InnerSent<_Const> __inner)
6007 friend class adjacent_transform_view;
6010 _Sentinel() = default;
6013 _Sentinel(_Sentinel<!_Const> __i)
6014 requires _Const && convertible_to<_InnerSent<false>, _InnerSent<_Const>>
6015 : _M_inner(std::move(__i._M_inner))
6018 template<bool _OtherConst>
6019 requires sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6020 friend constexpr bool
6021 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6022 { return __x._M_inner == __y._M_inner; }
6024 template<bool _OtherConst>
6025 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6026 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6027 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
6028 { return __x._M_inner - __y._M_inner; }
6030 template<bool _OtherConst>
6031 requires sized_sentinel_for<_InnerSent<_Const>, _InnerIter<_OtherConst>>
6032 friend constexpr range_difference_t<__detail::__maybe_const_t<_OtherConst, _InnerView>>
6033 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
6034 { return __x._M_inner - __y._M_inner; }
6041 template<size_t _Nm, typename _Range, typename _Fp>
6042 concept __can_adjacent_transform_view
6043 = requires { adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6044 (std::declval<_Range>(), std::declval<_Fp>()); };
6047 template<size_t _Nm>
6048 struct _AdjacentTransform : __adaptor::_RangeAdaptor<_AdjacentTransform<_Nm>>
6050 template<viewable_range _Range, typename _Fp>
6051 requires (_Nm == 0) || __detail::__can_adjacent_transform_view<_Nm, _Range, _Fp>
6053 operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
6055 if constexpr (_Nm == 0)
6056 return zip_transform(std::forward<_Fp>(__f));
6058 return adjacent_transform_view<all_t<_Range>, decay_t<_Fp>, _Nm>
6059 (std::forward<_Range>(__r), std::forward<_Fp>(__f));
6062 using __adaptor::_RangeAdaptor<_AdjacentTransform>::operator();
6063 static constexpr int _S_arity = 2;
6064 static constexpr bool _S_has_simple_extra_args = true;
6067 template<size_t _Nm>
6068 inline constexpr _AdjacentTransform<_Nm> adjacent_transform;
6070 inline constexpr auto pairwise_transform = adjacent_transform<2>;
6072#endif // __cpp_lib_ranges_zip
6074#ifdef __cpp_lib_ranges_chunk // C++ >= 23
6077 template<typename _Tp>
6078 constexpr _Tp __div_ceil(_Tp __num, _Tp __denom)
6080 _Tp __r = __num / __denom;
6081 if (__num % __denom)
6088 requires input_range<_Vp>
6089 class chunk_view : public view_interface<chunk_view<_Vp>>
6092 range_difference_t<_Vp> _M_n;
6093 range_difference_t<_Vp> _M_remainder = 0;
6094 __detail::__non_propagating_cache<iterator_t<_Vp>> _M_current;
6101 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6102 : _M_base(std::move(__base)), _M_n(__n)
6103 { __glibcxx_assert(__n >= 0); }
6106 base() const & requires copy_constructible<_Vp>
6111 { return std::move(_M_base); }
6113 constexpr _OuterIter
6116 _M_current = ranges::begin(_M_base);
6117 _M_remainder = _M_n;
6118 return _OuterIter(*this);
6121 constexpr default_sentinel_t
6122 end() const noexcept
6123 { return default_sentinel; }
6126 size() requires sized_range<_Vp>
6128 return __detail::__to_unsigned_like(__detail::__div_ceil
6129 (ranges::distance(_M_base), _M_n));
6133 size() const requires sized_range<const _Vp>
6135 return __detail::__to_unsigned_like(__detail::__div_ceil
6136 (ranges::distance(_M_base), _M_n));
6140 template<typename _Range>
6141 chunk_view(_Range&&, range_difference_t<_Range>) -> chunk_view<views::all_t<_Range>>;
6144 requires input_range<_Vp>
6145 class chunk_view<_Vp>::_OuterIter
6147 chunk_view* _M_parent;
6150 _OuterIter(chunk_view& __parent) noexcept
6151 : _M_parent(std::__addressof(__parent))
6157 using iterator_concept = input_iterator_tag;
6158 using difference_type = range_difference_t<_Vp>;
6162 _OuterIter(_OuterIter&&) = default;
6163 _OuterIter& operator=(_OuterIter&&) = default;
6165 constexpr value_type
6168 __glibcxx_assert(*this != default_sentinel);
6169 return value_type(*_M_parent);
6172 constexpr _OuterIter&
6175 __glibcxx_assert(*this != default_sentinel);
6176 ranges::advance(*_M_parent->_M_current, _M_parent->_M_remainder,
6177 ranges::end(_M_parent->_M_base));
6178 _M_parent->_M_remainder = _M_parent->_M_n;
6186 friend constexpr bool
6187 operator==(const _OuterIter& __x, default_sentinel_t)
6189 return *__x._M_parent->_M_current == ranges::end(__x._M_parent->_M_base)
6190 && __x._M_parent->_M_remainder != 0;
6193 friend constexpr difference_type
6194 operator-(default_sentinel_t, const _OuterIter& __x)
6195 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6197 const auto __dist = ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current;
6199 if (__dist < __x._M_parent->_M_remainder)
6200 return __dist == 0 ? 0 : 1;
6202 return 1 + __detail::__div_ceil(__dist - __x._M_parent->_M_remainder,
6203 __x._M_parent->_M_n);
6206 friend constexpr difference_type
6207 operator-(const _OuterIter& __x, default_sentinel_t __y)
6208 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6209 { return -(__y - __x); }
6213 requires input_range<_Vp>
6214 struct chunk_view<_Vp>::_OuterIter::value_type : view_interface<value_type>
6217 chunk_view* _M_parent;
6220 value_type(chunk_view& __parent) noexcept
6221 : _M_parent(std::__addressof(__parent))
6227 constexpr _InnerIter
6228 begin() const noexcept
6229 { return _InnerIter(*_M_parent); }
6231 constexpr default_sentinel_t
6232 end() const noexcept
6233 { return default_sentinel; }
6237 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6239 return __detail::__to_unsigned_like
6240 (ranges::min(_M_parent->_M_remainder,
6241 ranges::end(_M_parent->_M_base) - *_M_parent->_M_current));
6246 requires input_range<_Vp>
6247 class chunk_view<_Vp>::_InnerIter
6249 chunk_view* _M_parent;
6252 _InnerIter(chunk_view& __parent) noexcept
6253 : _M_parent(std::__addressof(__parent))
6256 friend _OuterIter::value_type;
6259 using iterator_concept = input_iterator_tag;
6260 using difference_type = range_difference_t<_Vp>;
6261 using value_type = range_value_t<_Vp>;
6263 _InnerIter(_InnerIter&&) = default;
6264 _InnerIter& operator=(_InnerIter&&) = default;
6266 constexpr const iterator_t<_Vp>&
6268 { return *_M_parent->_M_current; }
6270 constexpr range_reference_t<_Vp>
6273 __glibcxx_assert(*this != default_sentinel);
6274 return **_M_parent->_M_current;
6277 constexpr _InnerIter&
6280 __glibcxx_assert(*this != default_sentinel);
6281 ++*_M_parent->_M_current;
6282 if (*_M_parent->_M_current == ranges::end(_M_parent->_M_base))
6283 _M_parent->_M_remainder = 0;
6285 --_M_parent->_M_remainder;
6293 friend constexpr bool
6294 operator==(const _InnerIter& __x, default_sentinel_t) noexcept
6295 { return __x._M_parent->_M_remainder == 0; }
6297 friend constexpr difference_type
6298 operator-(default_sentinel_t, const _InnerIter& __x)
6299 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6301 return ranges::min(__x._M_parent->_M_remainder,
6302 ranges::end(__x._M_parent->_M_base) - *__x._M_parent->_M_current);
6305 friend constexpr difference_type
6306 operator-(const _InnerIter& __x, default_sentinel_t __y)
6307 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6308 { return -(__y - __x); }
6310 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6311 // 3851. chunk_view::inner-iterator missing custom iter_move and iter_swap
6312 friend constexpr range_rvalue_reference_t<_Vp>
6313 iter_move(const _InnerIter& __i)
6314 noexcept(noexcept(ranges::iter_move(*__i._M_parent->_M_current)))
6315 { return ranges::iter_move(*__i._M_parent->_M_current); }
6317 friend constexpr void
6318 iter_swap(const _InnerIter& __x, const _InnerIter& __y)
6319 noexcept(noexcept(ranges::iter_swap(*__x._M_parent->_M_current,
6320 *__x._M_parent->_M_current)))
6321 requires indirectly_swappable<iterator_t<_Vp>>
6322 { return ranges::iter_swap(*__x._M_parent->_M_current, *__y._M_parent->_M_current); }
6326 requires forward_range<_Vp>
6327 class chunk_view<_Vp> : public view_interface<chunk_view<_Vp>>
6330 range_difference_t<_Vp> _M_n;
6331 template<bool> class _Iterator;
6335 chunk_view(_Vp __base, range_difference_t<_Vp> __n)
6336 : _M_base(std::move(__base)), _M_n(__n)
6337 { __glibcxx_assert(__n > 0); }
6340 base() const & requires copy_constructible<_Vp>
6345 { return std::move(_M_base); }
6348 begin() requires (!__detail::__simple_view<_Vp>)
6349 { return _Iterator<false>(this, ranges::begin(_M_base)); }
6352 begin() const requires forward_range<const _Vp>
6353 { return _Iterator<true>(this, ranges::begin(_M_base)); }
6356 end() requires (!__detail::__simple_view<_Vp>)
6358 if constexpr (common_range<_Vp> && sized_range<_Vp>)
6360 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6361 return _Iterator<false>(this, ranges::end(_M_base), __missing);
6363 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
6364 return _Iterator<false>(this, ranges::end(_M_base));
6366 return default_sentinel;
6370 end() const requires forward_range<const _Vp>
6372 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
6374 auto __missing = (_M_n - ranges::distance(_M_base) % _M_n) % _M_n;
6375 return _Iterator<true>(this, ranges::end(_M_base), __missing);
6377 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
6378 return _Iterator<true>(this, ranges::end(_M_base));
6380 return default_sentinel;
6384 size() requires sized_range<_Vp>
6386 return __detail::__to_unsigned_like(__detail::__div_ceil
6387 (ranges::distance(_M_base), _M_n));
6391 size() const requires sized_range<const _Vp>
6393 return __detail::__to_unsigned_like(__detail::__div_ceil
6394 (ranges::distance(_M_base), _M_n));
6398 template<typename _Vp>
6399 inline constexpr bool enable_borrowed_range<chunk_view<_Vp>>
6400 = forward_range<_Vp> && enable_borrowed_range<_Vp>;
6403 requires forward_range<_Vp>
6404 template<bool _Const>
6405 class chunk_view<_Vp>::_Iterator
6407 using _Parent = __detail::__maybe_const_t<_Const, chunk_view>;
6408 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6410 iterator_t<_Base> _M_current = iterator_t<_Base>();
6411 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
6412 range_difference_t<_Base> _M_n = 0;
6413 range_difference_t<_Base> _M_missing = 0;
6416 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
6417 range_difference_t<_Base> __missing = 0)
6418 : _M_current(__current), _M_end(ranges::end(__parent->_M_base)),
6419 _M_n(__parent->_M_n), _M_missing(__missing)
6425 if constexpr (random_access_range<_Base>)
6426 return random_access_iterator_tag{};
6427 else if constexpr (bidirectional_range<_Base>)
6428 return bidirectional_iterator_tag{};
6430 return forward_iterator_tag{};
6436 using iterator_category = input_iterator_tag;
6437 using iterator_concept = decltype(_S_iter_cat());
6438 using value_type = decltype(views::take(subrange(_M_current, _M_end), _M_n));
6439 using difference_type = range_difference_t<_Base>;
6441 _Iterator() = default;
6443 constexpr _Iterator(_Iterator<!_Const> __i)
6445 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6446 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
6447 : _M_current(std::move(__i._M_current)), _M_end(std::move(__i._M_end)),
6448 _M_n(__i._M_n), _M_missing(__i._M_missing)
6451 constexpr iterator_t<_Base>
6453 { return _M_current; }
6455 constexpr value_type
6458 __glibcxx_assert(_M_current != _M_end);
6459 return views::take(subrange(_M_current, _M_end), _M_n);
6462 constexpr _Iterator&
6465 __glibcxx_assert(_M_current != _M_end);
6466 _M_missing = ranges::advance(_M_current, _M_n, _M_end);
6478 constexpr _Iterator&
6479 operator--() requires bidirectional_range<_Base>
6481 ranges::advance(_M_current, _M_missing - _M_n);
6487 operator--(int) requires bidirectional_range<_Base>
6494 constexpr _Iterator&
6495 operator+=(difference_type __x)
6496 requires random_access_range<_Base>
6500 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_n * (__x - 1));
6501 _M_missing = ranges::advance(_M_current, _M_n * __x, _M_end);
6505 ranges::advance(_M_current, _M_n * __x + _M_missing);
6511 constexpr _Iterator&
6512 operator-=(difference_type __x)
6513 requires random_access_range<_Base>
6514 { return *this += -__x; }
6516 constexpr value_type
6517 operator[](difference_type __n) const
6518 requires random_access_range<_Base>
6519 { return *(*this + __n); }
6521 friend constexpr bool
6522 operator==(const _Iterator& __x, const _Iterator& __y)
6523 { return __x._M_current == __y._M_current; }
6525 friend constexpr bool
6526 operator==(const _Iterator& __x, default_sentinel_t)
6527 { return __x._M_current == __x._M_end; }
6529 friend constexpr bool
6530 operator<(const _Iterator& __x, const _Iterator& __y)
6531 requires random_access_range<_Base>
6532 { return __x._M_current > __y._M_current; }
6534 friend constexpr bool
6535 operator>(const _Iterator& __x, const _Iterator& __y)
6536 requires random_access_range<_Base>
6537 { return __y < __x; }
6539 friend constexpr bool
6540 operator<=(const _Iterator& __x, const _Iterator& __y)
6541 requires random_access_range<_Base>
6542 { return !(__y < __x); }
6544 friend constexpr bool
6545 operator>=(const _Iterator& __x, const _Iterator& __y)
6546 requires random_access_range<_Base>
6547 { return !(__x < __y); }
6549 friend constexpr auto
6550 operator<=>(const _Iterator& __x, const _Iterator& __y)
6551 requires random_access_range<_Base>
6552 && three_way_comparable<iterator_t<_Base>>
6553 { return __x._M_current <=> __y._M_current; }
6555 friend constexpr _Iterator
6556 operator+(const _Iterator& __i, difference_type __n)
6557 requires random_access_range<_Base>
6564 friend constexpr _Iterator
6565 operator+(difference_type __n, const _Iterator& __i)
6566 requires random_access_range<_Base>
6573 friend constexpr _Iterator
6574 operator-(const _Iterator& __i, difference_type __n)
6575 requires random_access_range<_Base>
6582 friend constexpr difference_type
6583 operator-(const _Iterator& __x, const _Iterator& __y)
6584 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6586 return (__x._M_current - __y._M_current
6587 + __x._M_missing - __y._M_missing) / __x._M_n;
6590 friend constexpr difference_type
6591 operator-(default_sentinel_t __y, const _Iterator& __x)
6592 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6593 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_n); }
6595 friend constexpr difference_type
6596 operator-(const _Iterator& __x, default_sentinel_t __y)
6597 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
6598 { return -(__y - __x); }
6605 template<typename _Range, typename _Dp>
6606 concept __can_chunk_view
6607 = requires { chunk_view(std::declval<_Range>(), std::declval<_Dp>()); };
6610 struct _Chunk : __adaptor::_RangeAdaptor<_Chunk>
6612 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6613 requires __detail::__can_chunk_view<_Range, _Dp>
6615 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6616 { return chunk_view(std::forward<_Range>(__r), __n); }
6618 using __adaptor::_RangeAdaptor<_Chunk>::operator();
6619 static constexpr int _S_arity = 2;
6620 static constexpr bool _S_has_simple_extra_args = true;
6623 inline constexpr _Chunk chunk;
6625#endif // __cpp_lib_ranges_chunk
6627#ifdef __cpp_lib_ranges_slide // C++ >= 23
6630 template<typename _Vp>
6631 concept __slide_caches_nothing = random_access_range<_Vp> && sized_range<_Vp>;
6633 template<typename _Vp>
6634 concept __slide_caches_last
6635 = !__slide_caches_nothing<_Vp> && bidirectional_range<_Vp> && common_range<_Vp>;
6637 template<typename _Vp>
6638 concept __slide_caches_first
6639 = !__slide_caches_nothing<_Vp> && !__slide_caches_last<_Vp>;
6642 template<forward_range _Vp>
6644 class slide_view : public view_interface<slide_view<_Vp>>
6647 range_difference_t<_Vp> _M_n;
6648 [[no_unique_address]]
6649 __detail::__maybe_present_t<__detail::__slide_caches_first<_Vp>,
6650 __detail::_CachedPosition<_Vp>, 0> _M_cached_begin;
6651 [[no_unique_address]]
6652 __detail::__maybe_present_t<__detail::__slide_caches_last<_Vp>,
6653 __detail::_CachedPosition<_Vp>, 1> _M_cached_end;
6655 template<bool> class _Iterator;
6660 slide_view(_Vp __base, range_difference_t<_Vp> __n)
6661 : _M_base(std::move(__base)), _M_n(__n)
6662 { __glibcxx_assert(__n > 0); }
6664 // _GLIBCXX_RESOLVE_LIB_DEFECTS
6665 // 3848. adjacent_view, adjacent_transform_view and slide_view missing base accessor
6667 base() const & requires copy_constructible<_Vp>
6672 { return std::move(_M_base); }
6675 begin() requires (!(__detail::__simple_view<_Vp>
6676 && __detail::__slide_caches_nothing<const _Vp>))
6678 if constexpr (__detail::__slide_caches_first<_Vp>)
6680 iterator_t<_Vp> __it;
6681 if (_M_cached_begin._M_has_value())
6682 __it = _M_cached_begin._M_get(_M_base);
6685 __it = ranges::next(ranges::begin(_M_base), _M_n - 1, ranges::end(_M_base));
6686 _M_cached_begin._M_set(_M_base, __it);
6688 return _Iterator<false>(ranges::begin(_M_base), std::move(__it), _M_n);
6691 return _Iterator<false>(ranges::begin(_M_base), _M_n);
6695 begin() const requires __detail::__slide_caches_nothing<const _Vp>
6696 { return _Iterator<true>(ranges::begin(_M_base), _M_n); }
6699 end() requires (!(__detail::__simple_view<_Vp>
6700 && __detail::__slide_caches_nothing<const _Vp>))
6702 if constexpr (__detail::__slide_caches_nothing<_Vp>)
6703 return _Iterator<false>(ranges::begin(_M_base) + range_difference_t<_Vp>(size()),
6705 else if constexpr (__detail::__slide_caches_last<_Vp>)
6707 iterator_t<_Vp> __it;
6708 if (_M_cached_end._M_has_value())
6709 __it = _M_cached_end._M_get(_M_base);
6712 __it = ranges::prev(ranges::end(_M_base), _M_n - 1, ranges::begin(_M_base));
6713 _M_cached_end._M_set(_M_base, __it);
6715 return _Iterator<false>(std::move(__it), _M_n);
6717 else if constexpr (common_range<_Vp>)
6718 return _Iterator<false>(ranges::end(_M_base), ranges::end(_M_base), _M_n);
6720 return _Sentinel(ranges::end(_M_base));
6724 end() const requires __detail::__slide_caches_nothing<const _Vp>
6725 { return begin() + range_difference_t<const _Vp>(size()); }
6728 size() requires sized_range<_Vp>
6730 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6733 return __detail::__to_unsigned_like(__sz);
6737 size() const requires sized_range<const _Vp>
6739 auto __sz = ranges::distance(_M_base) - _M_n + 1;
6742 return __detail::__to_unsigned_like(__sz);
6746 template<typename _Range>
6747 slide_view(_Range&&, range_difference_t<_Range>) -> slide_view<views::all_t<_Range>>;
6749 template<typename _Vp>
6750 inline constexpr bool enable_borrowed_range<slide_view<_Vp>>
6751 = enable_borrowed_range<_Vp>;
6753 template<forward_range _Vp>
6755 template<bool _Const>
6756 class slide_view<_Vp>::_Iterator
6758 using _Base = __detail::__maybe_const_t<_Const, _Vp>;
6759 static constexpr bool _S_last_elt_present
6760 = __detail::__slide_caches_first<_Base>;
6762 iterator_t<_Base> _M_current = iterator_t<_Base>();
6763 [[no_unique_address]]
6764 __detail::__maybe_present_t<_S_last_elt_present, iterator_t<_Base>>
6765 _M_last_elt = decltype(_M_last_elt)();
6766 range_difference_t<_Base> _M_n = 0;
6769 _Iterator(iterator_t<_Base> __current, range_difference_t<_Base> __n)
6770 requires (!_S_last_elt_present)
6771 : _M_current(__current), _M_n(__n)
6775 _Iterator(iterator_t<_Base> __current, iterator_t<_Base> __last_elt,
6776 range_difference_t<_Base> __n)
6777 requires _S_last_elt_present
6778 : _M_current(__current), _M_last_elt(__last_elt), _M_n(__n)
6784 if constexpr (random_access_range<_Base>)
6785 return random_access_iterator_tag{};
6786 else if constexpr (bidirectional_range<_Base>)
6787 return bidirectional_iterator_tag{};
6789 return forward_iterator_tag{};
6793 friend slide_view::_Sentinel;
6796 using iterator_category = input_iterator_tag;
6797 using iterator_concept = decltype(_S_iter_concept());
6798 using value_type = decltype(views::counted(_M_current, _M_n));
6799 using difference_type = range_difference_t<_Base>;
6801 _Iterator() = default;
6804 _Iterator(_Iterator<!_Const> __i)
6805 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
6806 : _M_current(std::move(__i._M_current)), _M_n(__i._M_n)
6811 { return views::counted(_M_current, _M_n); }
6813 constexpr _Iterator&
6817 if constexpr (_S_last_elt_present)
6830 constexpr _Iterator&
6831 operator--() requires bidirectional_range<_Base>
6834 if constexpr (_S_last_elt_present)
6840 operator--(int) requires bidirectional_range<_Base>
6847 constexpr _Iterator&
6848 operator+=(difference_type __x)
6849 requires random_access_range<_Base>
6852 if constexpr (_S_last_elt_present)
6857 constexpr _Iterator&
6858 operator-=(difference_type __x)
6859 requires random_access_range<_Base>
6862 if constexpr (_S_last_elt_present)
6868 operator[](difference_type __n) const
6869 requires random_access_range<_Base>
6870 { return views::counted(_M_current + __n, _M_n); }
6872 friend constexpr bool
6873 operator==(const _Iterator& __x, const _Iterator& __y)
6875 if constexpr (_S_last_elt_present)
6876 return __x._M_last_elt == __y._M_last_elt;
6878 return __x._M_current == __y._M_current;
6881 friend constexpr bool
6882 operator<(const _Iterator& __x, const _Iterator& __y)
6883 requires random_access_range<_Base>
6884 { return __x._M_current < __y._M_current; }
6886 friend constexpr bool
6887 operator>(const _Iterator& __x, const _Iterator& __y)
6888 requires random_access_range<_Base>
6889 { return __y < __x; }
6891 friend constexpr bool
6892 operator<=(const _Iterator& __x, const _Iterator& __y)
6893 requires random_access_range<_Base>
6894 { return !(__y < __x); }
6896 friend constexpr bool
6897 operator>=(const _Iterator& __x, const _Iterator& __y)
6898 requires random_access_range<_Base>
6899 { return !(__x < __y); }
6901 friend constexpr auto
6902 operator<=>(const _Iterator& __x, const _Iterator& __y)
6903 requires random_access_range<_Base>
6904 && three_way_comparable<iterator_t<_Base>>
6905 { return __x._M_current <=> __y._M_current; }
6907 friend constexpr _Iterator
6908 operator+(const _Iterator& __i, difference_type __n)
6909 requires random_access_range<_Base>
6916 friend constexpr _Iterator
6917 operator+(difference_type __n, const _Iterator& __i)
6918 requires random_access_range<_Base>
6925 friend constexpr _Iterator
6926 operator-(const _Iterator& __i, difference_type __n)
6927 requires random_access_range<_Base>
6934 friend constexpr difference_type
6935 operator-(const _Iterator& __x, const _Iterator& __y)
6936 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
6938 if constexpr (_S_last_elt_present)
6939 return __x._M_last_elt - __y._M_last_elt;
6941 return __x._M_current - __y._M_current;
6945 template<forward_range _Vp>
6947 class slide_view<_Vp>::_Sentinel
6949 sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();
6952 _Sentinel(sentinel_t<_Vp> __end)
6959 _Sentinel() = default;
6961 friend constexpr bool
6962 operator==(const _Iterator<false>& __x, const _Sentinel& __y)
6963 { return __x._M_last_elt == __y._M_end; }
6965 friend constexpr range_difference_t<_Vp>
6966 operator-(const _Iterator<false>& __x, const _Sentinel& __y)
6967 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6968 { return __x._M_last_elt - __y._M_end; }
6970 friend constexpr range_difference_t<_Vp>
6971 operator-(const _Sentinel& __y, const _Iterator<false>& __x)
6972 requires sized_sentinel_for<sentinel_t<_Vp>, iterator_t<_Vp>>
6973 { return __y._M_end -__x._M_last_elt; }
6980 template<typename _Range, typename _Dp>
6981 concept __can_slide_view
6982 = requires { slide_view(std::declval<_Range>(), std::declval<_Dp>()); };
6985 struct _Slide : __adaptor::_RangeAdaptor<_Slide>
6987 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
6988 requires __detail::__can_slide_view<_Range, _Dp>
6990 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
6991 { return slide_view(std::forward<_Range>(__r), __n); }
6993 using __adaptor::_RangeAdaptor<_Slide>::operator();
6994 static constexpr int _S_arity = 2;
6995 static constexpr bool _S_has_simple_extra_args = true;
6998 inline constexpr _Slide slide;
7000#endif // __cpp_lib_ranges_slide
7002#ifdef __cpp_lib_ranges_chunk_by // C++ >= 23
7003 template<forward_range _Vp,
7004 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7005 requires view<_Vp> && is_object_v<_Pred>
7006 class chunk_by_view : public view_interface<chunk_by_view<_Vp, _Pred>>
7008 _Vp _M_base = _Vp();
7009 __detail::__box<_Pred> _M_pred;
7010 __detail::_CachedPosition<_Vp> _M_cached_begin;
7012 constexpr iterator_t<_Vp>
7013 _M_find_next(iterator_t<_Vp> __current)
7015 __glibcxx_assert(_M_pred.has_value());
7016 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7017 return !bool((*_M_pred)(std::forward<_Tp>(__x), std::forward<_Up>(__y)));
7019 auto __it = ranges::adjacent_find(__current, ranges::end(_M_base), __pred);
7020 return ranges::next(__it, 1, ranges::end(_M_base));
7023 constexpr iterator_t<_Vp>
7024 _M_find_prev(iterator_t<_Vp> __current) requires bidirectional_range<_Vp>
7026 __glibcxx_assert(_M_pred.has_value());
7027 auto __pred = [this]<typename _Tp, typename _Up>(_Tp&& __x, _Up&& __y) {
7028 return !bool((*_M_pred)(std::forward<_Up>(__y), std::forward<_Tp>(__x)));
7030 auto __rbegin = std::make_reverse_iterator(__current);
7031 auto __rend = std::make_reverse_iterator(ranges::begin(_M_base));
7032 __glibcxx_assert(__rbegin != __rend);
7033 auto __it = ranges::adjacent_find(__rbegin, __rend, __pred).base();
7034 return ranges::prev(__it, 1, ranges::begin(_M_base));
7040 chunk_by_view() requires (default_initializable<_Vp>
7041 && default_initializable<_Pred>)
7045 chunk_by_view(_Vp __base, _Pred __pred)
7046 : _M_base(std::move(__base)), _M_pred(std::move(__pred))
7050 base() const & requires copy_constructible<_Vp>
7055 { return std::move(_M_base); }
7057 constexpr const _Pred&
7059 { return *_M_pred; }
7064 __glibcxx_assert(_M_pred.has_value());
7065 iterator_t<_Vp> __it;
7066 if (_M_cached_begin._M_has_value())
7067 __it = _M_cached_begin._M_get(_M_base);
7070 __it = _M_find_next(ranges::begin(_M_base));
7071 _M_cached_begin._M_set(_M_base, __it);
7073 return _Iterator(*this, ranges::begin(_M_base), __it);
7079 if constexpr (common_range<_Vp>)
7080 return _Iterator(*this, ranges::end(_M_base), ranges::end(_M_base));
7082 return default_sentinel;
7086 template<typename _Range, typename _Pred>
7087 chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
7089 template<forward_range _Vp,
7090 indirect_binary_predicate<iterator_t<_Vp>, iterator_t<_Vp>> _Pred>
7091 requires view<_Vp> && is_object_v<_Pred>
7092 class chunk_by_view<_Vp, _Pred>::_Iterator
7094 chunk_by_view* _M_parent = nullptr;
7095 iterator_t<_Vp> _M_current = iterator_t<_Vp>();
7096 iterator_t<_Vp> _M_next = iterator_t<_Vp>();
7099 _Iterator(chunk_by_view& __parent, iterator_t<_Vp> __current, iterator_t<_Vp> __next)
7100 : _M_parent(std::__addressof(__parent)), _M_current(__current), _M_next(__next)
7106 if constexpr (bidirectional_range<_Vp>)
7107 return bidirectional_iterator_tag{};
7109 return forward_iterator_tag{};
7112 friend chunk_by_view;
7115 using value_type = subrange<iterator_t<_Vp>>;
7116 using difference_type = range_difference_t<_Vp>;
7117 using iterator_category = input_iterator_tag;
7118 using iterator_concept = decltype(_S_iter_concept());
7120 _Iterator() = default;
7122 constexpr value_type
7125 __glibcxx_assert(_M_current != _M_next);
7126 return ranges::subrange(_M_current, _M_next);
7129 constexpr _Iterator&
7132 __glibcxx_assert(_M_current != _M_next);
7133 _M_current = _M_next;
7134 _M_next = _M_parent->_M_find_next(_M_current);
7146 constexpr _Iterator&
7147 operator--() requires bidirectional_range<_Vp>
7149 _M_next = _M_current;
7150 _M_current = _M_parent->_M_find_prev(_M_next);
7155 operator--(int) requires bidirectional_range<_Vp>
7162 friend constexpr bool
7163 operator==(const _Iterator& __x, const _Iterator& __y)
7164 { return __x._M_current == __y._M_current; }
7166 friend constexpr bool
7167 operator==(const _Iterator& __x, default_sentinel_t)
7168 { return __x._M_current == __x._M_next; }
7175 template<typename _Range, typename _Pred>
7176 concept __can_chunk_by_view
7177 = requires { chunk_by_view(std::declval<_Range>(), std::declval<_Pred>()); };
7180 struct _ChunkBy : __adaptor::_RangeAdaptor<_ChunkBy>
7182 template<viewable_range _Range, typename _Pred>
7183 requires __detail::__can_chunk_by_view<_Range, _Pred>
7185 operator() [[nodiscard]] (_Range&& __r, _Pred&& __pred) const
7186 { return chunk_by_view(std::forward<_Range>(__r), std::forward<_Pred>(__pred)); }
7188 using __adaptor::_RangeAdaptor<_ChunkBy>::operator();
7189 static constexpr int _S_arity = 2;
7190 static constexpr bool _S_has_simple_extra_args = true;
7193 inline constexpr _ChunkBy chunk_by;
7195#endif // __cpp_lib_ranges_chunk_by
7197#ifdef __cpp_lib_ranges_join_with // C++ >= 23
7200 template<typename _Range, typename _Pattern>
7201 concept __compatible_joinable_ranges
7202 = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
7203 && common_reference_with<range_reference_t<_Range>,
7204 range_reference_t<_Pattern>>
7205 && common_reference_with<range_rvalue_reference_t<_Range>,
7206 range_rvalue_reference_t<_Pattern>>;
7208 template<typename _Range>
7209 concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
7212 template<input_range _Vp, forward_range _Pattern>
7213 requires view<_Vp> && view<_Pattern>
7214 && input_range<range_reference_t<_Vp>>
7215 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7216 class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
7218 using _InnerRange = range_reference_t<_Vp>;
7220 _Vp _M_base = _Vp();
7221 [[no_unique_address]]
7222 __detail::__maybe_present_t<!forward_range<_Vp>,
7223 __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_outer_it;
7224 __detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;
7225 _Pattern _M_pattern = _Pattern();
7227 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
7228 template<bool _Const> using _InnerBase = range_reference_t<_Base<_Const>>;
7229 template<bool _Const> using _PatternBase = __detail::__maybe_const_t<_Const, _Pattern>;
7231 template<bool _Const> using _OuterIter = iterator_t<_Base<_Const>>;
7232 template<bool _Const> using _InnerIter = iterator_t<_InnerBase<_Const>>;
7233 template<bool _Const> using _PatternIter = iterator_t<_PatternBase<_Const>>;
7235 template<bool _Const>
7236 static constexpr bool _S_ref_is_glvalue = is_reference_v<_InnerBase<_Const>>;
7238 template<bool _Const>
7242 template<bool _Const>
7243 requires _S_ref_is_glvalue<_Const>
7244 && forward_range<_Base<_Const>>
7245 && forward_range<_InnerBase<_Const>>
7246 struct __iter_cat<_Const>
7252 using _OuterIter = join_with_view::_OuterIter<_Const>;
7253 using _InnerIter = join_with_view::_InnerIter<_Const>;
7254 using _PatternIter = join_with_view::_PatternIter<_Const>;
7255 using _OuterCat = typename iterator_traits<_OuterIter>::iterator_category;
7256 using _InnerCat = typename iterator_traits<_InnerIter>::iterator_category;
7257 using _PatternCat = typename iterator_traits<_PatternIter>::iterator_category;
7258 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7259 // 3798. Rvalue reference and iterator_category
7260 if constexpr (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>,
7261 iter_reference_t<_PatternIter>>>)
7262 return input_iterator_tag{};
7263 else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
7264 && derived_from<_InnerCat, bidirectional_iterator_tag>
7265 && derived_from<_PatternCat, bidirectional_iterator_tag>
7266 && common_range<_InnerBase<_Const>>
7267 && common_range<_PatternBase<_Const>>)
7268 return bidirectional_iterator_tag{};
7269 else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
7270 && derived_from<_InnerCat, forward_iterator_tag>
7271 && derived_from<_PatternCat, forward_iterator_tag>)
7272 return forward_iterator_tag{};
7274 return input_iterator_tag{};
7277 using iterator_category = decltype(_S_iter_cat());
7280 template<bool> struct _Iterator;
7281 template<bool> struct _Sentinel;
7284 join_with_view() requires (default_initializable<_Vp>
7285 && default_initializable<_Pattern>)
7289 join_with_view(_Vp __base, _Pattern __pattern)
7290 : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
7293 template<input_range _Range>
7294 requires constructible_from<_Vp, views::all_t<_Range>>
7295 && constructible_from<_Pattern, single_view<range_value_t<_InnerRange>>>
7297 join_with_view(_Range&& __r, range_value_t<_InnerRange> __e)
7298 : _M_base(views::all(std::forward<_Range>(__r))),
7299 _M_pattern(views::single(std::move(__e)))
7303 base() const& requires copy_constructible<_Vp>
7308 { return std::move(_M_base); }
7313 if constexpr (forward_range<_Vp>)
7315 constexpr bool __use_const = is_reference_v<_InnerRange>
7316 && __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7317 return _Iterator<__use_const>{*this, ranges::begin(_M_base)};
7321 _M_outer_it = ranges::begin(_M_base);
7322 return _Iterator<false>{*this};
7328 requires forward_range<const _Vp>
7329 && forward_range<const _Pattern>
7330 && is_reference_v<range_reference_t<const _Vp>>
7331 && input_range<range_reference_t<const _Vp>>
7332 { return _Iterator<true>{*this, ranges::begin(_M_base)}; }
7337 constexpr bool __use_const
7338 = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
7339 if constexpr (is_reference_v<_InnerRange>
7340 && forward_range<_Vp> && common_range<_Vp>
7341 && forward_range<_InnerRange> && common_range<_InnerRange>)
7342 return _Iterator<__use_const>{*this, ranges::end(_M_base)};
7344 return _Sentinel<__use_const>{*this};
7349 requires forward_range<const _Vp>
7350 && forward_range<const _Pattern>
7351 && is_reference_v<range_reference_t<const _Vp>>
7352 && input_range<range_reference_t<const _Vp>>
7354 using _InnerConstRange = range_reference_t<const _Vp>;
7355 if constexpr (forward_range<_InnerConstRange>
7356 && common_range<const _Vp>
7357 && common_range<_InnerConstRange>)
7358 return _Iterator<true>{*this, ranges::end(_M_base)};
7360 return _Sentinel<true>{*this};
7364 template<typename _Range, typename _Pattern>
7365 join_with_view(_Range&&, _Pattern&&)
7366 -> join_with_view<views::all_t<_Range>, views::all_t<_Pattern>>;
7368 template<input_range _Range>
7369 join_with_view(_Range&&, range_value_t<range_reference_t<_Range>>)
7370 -> join_with_view<views::all_t<_Range>,
7371 single_view<range_value_t<range_reference_t<_Range>>>>;
7373 template<input_range _Vp, forward_range _Pattern>
7374 requires view<_Vp> && view<_Pattern>
7375 && input_range<range_reference_t<_Vp>>
7376 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7377 template<bool _Const>
7378 class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
7380 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7381 using _Base = join_with_view::_Base<_Const>;
7382 using _InnerBase = join_with_view::_InnerBase<_Const>;
7383 using _PatternBase = join_with_view::_PatternBase<_Const>;
7385 using _OuterIter = join_with_view::_OuterIter<_Const>;
7386 using _InnerIter = join_with_view::_InnerIter<_Const>;
7387 using _PatternIter = join_with_view::_PatternIter<_Const>;
7389 static constexpr bool _S_ref_is_glvalue = join_with_view::_S_ref_is_glvalue<_Const>;
7391 _Parent* _M_parent = nullptr;
7392 [[no_unique_address]]
7393 __detail::__maybe_present_t<forward_range<_Base>, _OuterIter> _M_outer_it;
7394 variant<_PatternIter, _InnerIter> _M_inner_it;
7396 constexpr _OuterIter&
7399 if constexpr (forward_range<_Base>)
7402 return *_M_parent->_M_outer_it;
7405 constexpr const _OuterIter&
7406 _M_get_outer() const
7408 if constexpr (forward_range<_Base>)
7411 return *_M_parent->_M_outer_it;
7415 _Iterator(_Parent& __parent, _OuterIter __outer)
7416 requires forward_range<_Base>
7417 : _M_parent(std::__addressof(__parent)), _M_outer_it(std::move(__outer))
7419 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7421 auto&& __inner = _M_update_inner();
7422 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7428 _Iterator(_Parent& __parent)
7429 requires (!forward_range<_Base>)
7430 : _M_parent(std::__addressof(__parent))
7432 if (_M_get_outer() != ranges::end(_M_parent->_M_base))
7434 auto&& __inner = _M_update_inner();
7435 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7443 _OuterIter& __outer = _M_get_outer();
7444 if constexpr (_S_ref_is_glvalue)
7445 return __detail::__as_lvalue(*__outer);
7447 return _M_parent->_M_inner._M_emplace_deref(__outer);
7453 if constexpr (_S_ref_is_glvalue)
7454 return __detail::__as_lvalue(*_M_get_outer());
7456 return *_M_parent->_M_inner;
7464 if (_M_inner_it.index() == 0)
7466 if (std::get<0>(_M_inner_it) != ranges::end(_M_parent->_M_pattern))
7469 auto&& __inner = _M_update_inner();
7470 _M_inner_it.template emplace<1>(ranges::begin(__inner));
7474 auto&& __inner = _M_get_inner();
7475 if (std::get<1>(_M_inner_it) != ranges::end(__inner))
7478 if (++_M_get_outer() == ranges::end(_M_parent->_M_base))
7480 if constexpr (_S_ref_is_glvalue)
7481 _M_inner_it.template emplace<0>();
7485 _M_inner_it.template emplace<0>(ranges::begin(_M_parent->_M_pattern));
7493 if constexpr (_S_ref_is_glvalue
7494 && bidirectional_range<_Base>
7495 && __detail::__bidirectional_common<_InnerBase>
7496 && __detail::__bidirectional_common<_PatternBase>)
7497 return bidirectional_iterator_tag{};
7498 else if constexpr (_S_ref_is_glvalue
7499 && forward_range<_Base>
7500 && forward_range<_InnerBase>)
7501 return forward_iterator_tag{};
7503 return input_iterator_tag{};
7506 friend join_with_view;
7509 using iterator_concept = decltype(_S_iter_concept());
7510 // iterator_category defined in join_with_view::__iter_cat
7511 using value_type = common_type_t<iter_value_t<_InnerIter>,
7512 iter_value_t<_PatternIter>>;
7513 using difference_type = common_type_t<iter_difference_t<_OuterIter>,
7514 iter_difference_t<_InnerIter>,
7515 iter_difference_t<_PatternIter>>;
7517 _Iterator() = default;
7520 _Iterator(_Iterator<!_Const> __i)
7522 && convertible_to<iterator_t<_Vp>, _OuterIter>
7523 && convertible_to<iterator_t<_InnerRange>, _InnerIter>
7524 && convertible_to<iterator_t<_Pattern>, _PatternIter>
7525 : _M_parent(__i._M_parent),
7526 _M_outer_it(std::move(__i._M_outer_it))
7528 if (__i._M_inner_it.index() == 0)
7529 _M_inner_it.template emplace<0>(std::get<0>(std::move(__i._M_inner_it)));
7531 _M_inner_it.template emplace<1>(std::get<1>(std::move(__i._M_inner_it)));
7534 constexpr common_reference_t<iter_reference_t<_InnerIter>,
7535 iter_reference_t<_PatternIter>>
7538 if (_M_inner_it.index() == 0)
7539 return *std::get<0>(_M_inner_it);
7541 return *std::get<1>(_M_inner_it);
7544 constexpr _Iterator&
7547 if (_M_inner_it.index() == 0)
7548 ++std::get<0>(_M_inner_it);
7550 ++std::get<1>(_M_inner_it);
7561 requires _S_ref_is_glvalue
7562 && forward_iterator<_OuterIter> && forward_iterator<_InnerIter>
7564 _Iterator __tmp = *this;
7569 constexpr _Iterator&
7571 requires _S_ref_is_glvalue
7572 && bidirectional_range<_Base>
7573 && __detail::__bidirectional_common<_InnerBase>
7574 && __detail::__bidirectional_common<_PatternBase>
7576 if (_M_outer_it == ranges::end(_M_parent->_M_base))
7578 auto&& __inner = *--_M_outer_it;
7579 _M_inner_it.template emplace<1>(ranges::end(__inner));
7584 if (_M_inner_it.index() == 0)
7586 auto& __it = std::get<0>(_M_inner_it);
7587 if (__it == ranges::begin(_M_parent->_M_pattern))
7589 auto&& __inner = *--_M_outer_it;
7590 _M_inner_it.template emplace<1>(ranges::end(__inner));
7597 auto& __it = std::get<1>(_M_inner_it);
7598 auto&& __inner = *_M_outer_it;
7599 if (__it == ranges::begin(__inner))
7600 _M_inner_it.template emplace<0>(ranges::end(_M_parent->_M_pattern));
7606 if (_M_inner_it.index() == 0)
7607 --std::get<0>(_M_inner_it);
7609 --std::get<1>(_M_inner_it);
7615 requires _S_ref_is_glvalue && bidirectional_range<_Base>
7616 && __detail::__bidirectional_common<_InnerBase>
7617 && __detail::__bidirectional_common<_PatternBase>
7619 _Iterator __tmp = *this;
7624 friend constexpr bool
7625 operator==(const _Iterator& __x, const _Iterator& __y)
7626 requires _S_ref_is_glvalue
7627 && forward_range<_Base> && equality_comparable<_InnerIter>
7628 { return __x._M_outer_it == __y._M_outer_it && __x._M_inner_it ==__y._M_inner_it; }
7630 friend constexpr common_reference_t<iter_rvalue_reference_t<_InnerIter>,
7631 iter_rvalue_reference_t<_PatternIter>>
7632 iter_move(const _Iterator& __x)
7634 if (__x._M_inner_it.index() == 0)
7635 return ranges::iter_move(std::get<0>(__x._M_inner_it));
7637 return ranges::iter_move(std::get<1>(__x._M_inner_it));
7640 friend constexpr void
7641 iter_swap(const _Iterator& __x, const _Iterator& __y)
7642 requires indirectly_swappable<_InnerIter, _PatternIter>
7644 if (__x._M_inner_it.index() == 0)
7646 if (__y._M_inner_it.index() == 0)
7647 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7649 ranges::iter_swap(std::get<0>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7653 if (__y._M_inner_it.index() == 0)
7654 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<0>(__y._M_inner_it));
7656 ranges::iter_swap(std::get<1>(__x._M_inner_it), std::get<1>(__y._M_inner_it));
7661 template<input_range _Vp, forward_range _Pattern>
7662 requires view<_Vp> && view<_Pattern>
7663 && input_range<range_reference_t<_Vp>>
7664 && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
7665 template<bool _Const>
7666 class join_with_view<_Vp, _Pattern>::_Sentinel
7668 using _Parent = __detail::__maybe_const_t<_Const, join_with_view>;
7669 using _Base = join_with_view::_Base<_Const>;
7671 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
7674 _Sentinel(_Parent& __parent)
7675 : _M_end(ranges::end(__parent._M_base))
7678 friend join_with_view;
7681 _Sentinel() = default;
7684 _Sentinel(_Sentinel<!_Const> __s)
7685 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
7686 : _M_end(std::move(__s._M_end))
7689 template<bool _OtherConst>
7690 requires sentinel_for<sentinel_t<_Base>,
7691 iterator_t<__detail::__maybe_const_t<_OtherConst, _Vp>>>
7692 friend constexpr bool
7693 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
7694 { return __x._M_get_outer() == __y._M_end; }
7701 template<typename _Range, typename _Pattern>
7702 concept __can_join_with_view
7703 = requires { join_with_view(std::declval<_Range>(), std::declval<_Pattern>()); };
7704 } // namespace __detail
7706 struct _JoinWith : __adaptor::_RangeAdaptor<_JoinWith>
7708 template<viewable_range _Range, typename _Pattern>
7709 requires __detail::__can_join_with_view<_Range, _Pattern>
7711 operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
7713 return join_with_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
7716 using _RangeAdaptor<_JoinWith>::operator();
7717 static constexpr int _S_arity = 2;
7718 template<typename _Pattern>
7719 static constexpr bool _S_has_simple_extra_args
7720 = _LazySplit::_S_has_simple_extra_args<_Pattern>;
7723 inline constexpr _JoinWith join_with;
7724 } // namespace views
7725#endif // __cpp_lib_ranges_join_with
7727#ifdef __cpp_lib_ranges_repeat // C++ >= 23
7728 template<move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
7729 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7730 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7731 class repeat_view : public view_interface<repeat_view<_Tp, _Bound>>
7733 __detail::__box<_Tp> _M_value;
7734 [[no_unique_address]] _Bound _M_bound = _Bound();
7738 template<typename _Range>
7739 friend constexpr auto
7740 views::__detail::__take_of_repeat_view(_Range&&, range_difference_t<_Range>);
7742 template<typename _Range>
7743 friend constexpr auto
7744 views::__detail::__drop_of_repeat_view(_Range&&, range_difference_t<_Range>);
7747 repeat_view() requires default_initializable<_Tp> = default;
7750 repeat_view(const _Tp& __value, _Bound __bound = _Bound())
7751 requires copy_constructible<_Tp>
7752 : _M_value(__value), _M_bound(__bound)
7754 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7755 __glibcxx_assert(__bound >= 0);
7759 repeat_view(_Tp&& __value, _Bound __bound = _Bound())
7760 : _M_value(std::move(__value)), _M_bound(__bound)
7763 template<typename... _Args, typename... _BoundArgs>
7764 requires constructible_from<_Tp, _Args...>
7765 && constructible_from<_Bound, _BoundArgs...>
7767 repeat_view(piecewise_construct_t,
7768 tuple<_Args...> __args,
7769 tuple<_BoundArgs...> __bound_args = tuple<>{})
7770 : _M_value(std::make_from_tuple<_Tp>(std::move(__args))),
7771 _M_bound(std::make_from_tuple<_Bound>(std::move(__bound_args)))
7776 { return _Iterator(std::__addressof(*_M_value)); }
7779 end() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7780 { return _Iterator(std::__addressof(*_M_value), _M_bound); }
7782 constexpr unreachable_sentinel_t
7783 end() const noexcept
7784 { return unreachable_sentinel; }
7787 size() const requires (!same_as<_Bound, unreachable_sentinel_t>)
7788 { return __detail::__to_unsigned_like(_M_bound); }
7791 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7792 // 4053. Unary call to std::views::repeat does not decay the argument
7793 template<typename _Tp, typename _Bound = unreachable_sentinel_t>
7794 repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
7796 template<move_constructible _Tp, semiregular _Bound>
7797 requires is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
7798 && (__detail::__is_integer_like<_Bound> || same_as<_Bound, unreachable_sentinel_t>)
7799 class repeat_view<_Tp, _Bound>::_Iterator
7802 = __conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
7804 const _Tp* _M_value = nullptr;
7805 __index_type _M_current = __index_type();
7808 _Iterator(const _Tp* __value, __index_type __bound = __index_type())
7809 : _M_value(__value), _M_current(__bound)
7811 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7812 __glibcxx_assert(__bound >= 0);
7818 using iterator_concept = random_access_iterator_tag;
7819 using iterator_category = random_access_iterator_tag;
7820 using value_type = _Tp;
7821 using difference_type = __conditional_t<__detail::__is_signed_integer_like<__index_type>,
7823 __detail::__iota_diff_t<__index_type>>;
7825 _Iterator() = default;
7827 constexpr const _Tp&
7828 operator*() const noexcept
7829 { return *_M_value; }
7831 constexpr _Iterator&
7846 constexpr _Iterator&
7849 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7850 __glibcxx_assert(_M_current > 0);
7863 constexpr _Iterator&
7864 operator+=(difference_type __n)
7866 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7867 __glibcxx_assert(_M_current + __n >= 0);
7872 constexpr _Iterator&
7873 operator-=(difference_type __n)
7875 if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
7876 __glibcxx_assert(_M_current - __n >= 0);
7881 constexpr const _Tp&
7882 operator[](difference_type __n) const noexcept
7883 { return *(*this + __n); }
7885 friend constexpr bool
7886 operator==(const _Iterator& __x, const _Iterator& __y)
7887 { return __x._M_current == __y._M_current; }
7889 friend constexpr auto
7890 operator<=>(const _Iterator& __x, const _Iterator& __y)
7891 { return __x._M_current <=> __y._M_current; }
7893 friend constexpr _Iterator
7894 operator+(_Iterator __i, difference_type __n)
7900 friend constexpr _Iterator
7901 operator+(difference_type __n, _Iterator __i)
7902 { return __i + __n; }
7904 friend constexpr _Iterator
7905 operator-(_Iterator __i, difference_type __n)
7911 friend constexpr difference_type
7912 operator-(const _Iterator& __x, const _Iterator& __y)
7914 return (static_cast<difference_type>(__x._M_current)
7915 - static_cast<difference_type>(__y._M_current));
7923 template<typename _Tp, typename _Bound>
7924 inline constexpr bool __is_repeat_view<repeat_view<_Tp, _Bound>> = true;
7926 template<typename _Tp>
7927 concept __can_repeat_view
7928 = requires { repeat_view(std::declval<_Tp>()); };
7930 template<typename _Tp, typename _Bound>
7931 concept __can_bounded_repeat_view
7932 = requires { repeat_view(std::declval<_Tp>(), std::declval<_Bound>()); };
7937 template<typename _Tp>
7938 requires __detail::__can_repeat_view<_Tp>
7940 operator() [[nodiscard]] (_Tp&& __value) const
7942 // _GLIBCXX_RESOLVE_LIB_DEFECTS
7943 // 4054. Repeating a repeat_view should repeat the view
7944 return repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value));
7947 template<typename _Tp, typename _Bound>
7948 requires __detail::__can_bounded_repeat_view<_Tp, _Bound>
7950 operator() [[nodiscard]] (_Tp&& __value, _Bound __bound) const
7951 { return repeat_view(std::forward<_Tp>(__value), __bound); }
7954 inline constexpr _Repeat repeat;
7958 template<typename _Range>
7960 __take_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7962 using _Tp = remove_cvref_t<_Range>;
7963 static_assert(__is_repeat_view<_Tp>);
7964 if constexpr (sized_range<_Tp>)
7965 return views::repeat(*std::forward<_Range>(__r)._M_value,
7966 std::min(ranges::distance(__r), __n));
7968 return views::repeat(*std::forward<_Range>(__r)._M_value, __n);
7971 template<typename _Range>
7973 __drop_of_repeat_view(_Range&& __r, range_difference_t<_Range> __n)
7975 using _Tp = remove_cvref_t<_Range>;
7976 static_assert(__is_repeat_view<_Tp>);
7977 if constexpr (sized_range<_Tp>)
7979 auto __sz = ranges::distance(__r);
7980 return views::repeat(*std::forward<_Range>(__r)._M_value,
7981 __sz - std::min(__sz, __n));
7988#endif // __cpp_lib_ranges_repeat
7990#ifdef __cpp_lib_ranges_stride // C++ >= 23
7991 template<input_range _Vp>
7993 class stride_view : public view_interface<stride_view<_Vp>>
7996 range_difference_t<_Vp> _M_stride;
7998 template<bool _Const> using _Base = __detail::__maybe_const_t<_Const, _Vp>;
8000 template<bool _Const>
8004 template<bool _Const>
8005 requires forward_range<_Base<_Const>>
8006 struct __iter_cat<_Const>
8012 using _Cat = typename iterator_traits<iterator_t<_Base<_Const>>>::iterator_category;
8013 if constexpr (derived_from<_Cat, random_access_iterator_tag>)
8014 return random_access_iterator_tag{};
8019 using iterator_category = decltype(_S_iter_cat());
8022 template<bool> class _Iterator;
8026 stride_view(_Vp __base, range_difference_t<_Vp> __stride)
8027 : _M_base(std::move(__base)), _M_stride(__stride)
8028 { __glibcxx_assert(__stride > 0); }
8031 base() const& requires copy_constructible<_Vp>
8036 { return std::move(_M_base); }
8038 constexpr range_difference_t<_Vp>
8039 stride() const noexcept
8040 { return _M_stride; }
8043 begin() requires (!__detail::__simple_view<_Vp>)
8044 { return _Iterator<false>(this, ranges::begin(_M_base)); }
8047 begin() const requires range<const _Vp>
8048 { return _Iterator<true>(this, ranges::begin(_M_base)); }
8051 end() requires (!__detail::__simple_view<_Vp>)
8053 if constexpr (common_range<_Vp> && sized_range<_Vp> && forward_range<_Vp>)
8055 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8056 return _Iterator<false>(this, ranges::end(_M_base), __missing);
8058 else if constexpr (common_range<_Vp> && !bidirectional_range<_Vp>)
8059 return _Iterator<false>(this, ranges::end(_M_base));
8061 return default_sentinel;
8065 end() const requires range<const _Vp>
8067 if constexpr (common_range<const _Vp> && sized_range<const _Vp>
8068 && forward_range<const _Vp>)
8070 auto __missing = (_M_stride - ranges::distance(_M_base) % _M_stride) % _M_stride;
8071 return _Iterator<true>(this, ranges::end(_M_base), __missing);
8073 else if constexpr (common_range<const _Vp> && !bidirectional_range<const _Vp>)
8074 return _Iterator<true>(this, ranges::end(_M_base));
8076 return default_sentinel;
8080 size() requires sized_range<_Vp>
8082 return __detail::__to_unsigned_like
8083 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8087 size() const requires sized_range<const _Vp>
8089 return __detail::__to_unsigned_like
8090 (__detail::__div_ceil(ranges::distance(_M_base), _M_stride));
8094 template<typename _Range>
8095 stride_view(_Range&&, range_difference_t<_Range>) -> stride_view<views::all_t<_Range>>;
8097 template<typename _Vp>
8098 inline constexpr bool enable_borrowed_range<stride_view<_Vp>>
8099 = enable_borrowed_range<_Vp>;
8101 template<input_range _Vp>
8103 template<bool _Const>
8104 class stride_view<_Vp>::_Iterator : public __iter_cat<_Const>
8106 using _Parent = __detail::__maybe_const_t<_Const, stride_view>;
8107 using _Base = stride_view::_Base<_Const>;
8109 iterator_t<_Base> _M_current = iterator_t<_Base>();
8110 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
8111 range_difference_t<_Base> _M_stride = 0;
8112 range_difference_t<_Base> _M_missing = 0;
8115 _Iterator(_Parent* __parent, iterator_t<_Base> __current,
8116 range_difference_t<_Base> __missing = 0)
8117 : _M_current(std::move(__current)), _M_end(ranges::end(__parent->_M_base)),
8118 _M_stride(__parent->_M_stride), _M_missing(__missing)
8124 if constexpr (random_access_range<_Base>)
8125 return random_access_iterator_tag{};
8126 else if constexpr (bidirectional_range<_Base>)
8127 return bidirectional_iterator_tag{};
8128 else if constexpr (forward_range<_Base>)
8129 return forward_iterator_tag{};
8131 return input_iterator_tag{};
8137 using difference_type = range_difference_t<_Base>;
8138 using value_type = range_value_t<_Base>;
8139 using iterator_concept = decltype(_S_iter_concept());
8140 // iterator_category defined in stride_view::__iter_cat
8142 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
8145 _Iterator(_Iterator<!_Const> __other)
8147 && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
8148 && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
8149 : _M_current(std::move(__other._M_current)), _M_end(std::move(__other._M_end)),
8150 _M_stride(__other._M_stride), _M_missing(__other._M_missing)
8153 constexpr iterator_t<_Base>
8155 { return std::move(_M_current); }
8157 constexpr const iterator_t<_Base>&
8158 base() const & noexcept
8159 { return _M_current; }
8161 constexpr decltype(auto)
8163 { return *_M_current; }
8165 constexpr _Iterator&
8168 __glibcxx_assert(_M_current != _M_end);
8169 _M_missing = ranges::advance(_M_current, _M_stride, _M_end);
8178 operator++(int) requires forward_range<_Base>
8185 constexpr _Iterator&
8186 operator--() requires bidirectional_range<_Base>
8188 ranges::advance(_M_current, _M_missing - _M_stride);
8194 operator--(int) requires bidirectional_range<_Base>
8201 constexpr _Iterator&
8202 operator+=(difference_type __n) requires random_access_range<_Base>
8206 __glibcxx_assert(ranges::distance(_M_current, _M_end) > _M_stride * (__n - 1));
8207 _M_missing = ranges::advance(_M_current, _M_stride * __n, _M_end);
8211 ranges::advance(_M_current, _M_stride * __n + _M_missing);
8217 constexpr _Iterator&
8218 operator-=(difference_type __n) requires random_access_range<_Base>
8219 { return *this += -__n; }
8221 constexpr decltype(auto) operator[](difference_type __n) const
8222 requires random_access_range<_Base>
8223 { return *(*this + __n); }
8225 friend constexpr bool
8226 operator==(const _Iterator& __x, default_sentinel_t)
8227 { return __x._M_current == __x._M_end; }
8229 friend constexpr bool
8230 operator==(const _Iterator& __x, const _Iterator& __y)
8231 requires equality_comparable<iterator_t<_Base>>
8232 { return __x._M_current == __y._M_current; }
8234 friend constexpr bool
8235 operator<(const _Iterator& __x, const _Iterator& __y)
8236 requires random_access_range<_Base>
8237 { return __x._M_current < __y._M_current; }
8239 friend constexpr bool
8240 operator>(const _Iterator& __x, const _Iterator& __y)
8241 requires random_access_range<_Base>
8242 { return __y._M_current < __x._M_current; }
8244 friend constexpr bool
8245 operator<=(const _Iterator& __x, const _Iterator& __y)
8246 requires random_access_range<_Base>
8247 { return !(__y._M_current < __x._M_current); }
8249 friend constexpr bool
8250 operator>=(const _Iterator& __x, const _Iterator& __y)
8251 requires random_access_range<_Base>
8252 { return !(__x._M_current < __y._M_current); }
8254 friend constexpr auto
8255 operator<=>(const _Iterator& __x, const _Iterator& __y)
8256 requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>>
8257 { return __x._M_current <=> __y._M_current; }
8259 friend constexpr _Iterator
8260 operator+(const _Iterator& __i, difference_type __n)
8261 requires random_access_range<_Base>
8268 friend constexpr _Iterator
8269 operator+(difference_type __n, const _Iterator& __i)
8270 requires random_access_range<_Base>
8271 { return __i + __n; }
8273 friend constexpr _Iterator
8274 operator-(const _Iterator& __i, difference_type __n)
8275 requires random_access_range<_Base>
8282 friend constexpr difference_type
8283 operator-(const _Iterator& __x, const _Iterator& __y)
8284 requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
8286 auto __n = __x._M_current - __y._M_current;
8287 if constexpr (forward_range<_Base>)
8288 return (__n + __x._M_missing - __y._M_missing) / __x._M_stride;
8290 return -__detail::__div_ceil(-__n, __x._M_stride);
8292 return __detail::__div_ceil(__n, __x._M_stride);
8295 friend constexpr difference_type
8296 operator-(default_sentinel_t __y, const _Iterator& __x)
8297 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8298 { return __detail::__div_ceil(__x._M_end - __x._M_current, __x._M_stride); }
8300 friend constexpr difference_type
8301 operator-(const _Iterator& __x, default_sentinel_t __y)
8302 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base>>
8303 { return -(__y - __x); }
8305 friend constexpr range_rvalue_reference_t<_Base>
8306 iter_move(const _Iterator& __i)
8307 noexcept(noexcept(ranges::iter_move(__i._M_current)))
8308 { return ranges::iter_move(__i._M_current); }
8310 friend constexpr void
8311 iter_swap(const _Iterator& __x, const _Iterator& __y)
8312 noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
8313 requires indirectly_swappable<iterator_t<_Base>>
8314 { ranges::iter_swap(__x._M_current, __y._M_current); }
8321 template<typename _Range, typename _Dp>
8322 concept __can_stride_view
8323 = requires { stride_view(std::declval<_Range>(), std::declval<_Dp>()); };
8326 struct _Stride : __adaptor::_RangeAdaptor<_Stride>
8328 template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
8329 requires __detail::__can_stride_view<_Range, _Dp>
8331 operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
8332 { return stride_view(std::forward<_Range>(__r), __n); }
8334 using __adaptor::_RangeAdaptor<_Stride>::operator();
8335 static constexpr int _S_arity = 2;
8336 static constexpr bool _S_has_simple_extra_args = true;
8339 inline constexpr _Stride stride;
8341#endif // __cpp_lib_ranges_stride
8343#ifdef __cpp_lib_ranges_cartesian_product // C++ >= 23
8346 template<bool _Const, typename _First, typename... _Vs>
8347 concept __cartesian_product_is_random_access
8348 = (random_access_range<__maybe_const_t<_Const, _First>>
8350 && (random_access_range<__maybe_const_t<_Const, _Vs>>
8351 && sized_range<__maybe_const_t<_Const, _Vs>>));
8353 template<typename _Range>
8354 concept __cartesian_product_common_arg
8355 = common_range<_Range> || (sized_range<_Range> && random_access_range<_Range>);
8357 template<bool _Const, typename _First, typename... _Vs>
8358 concept __cartesian_product_is_bidirectional
8359 = (bidirectional_range<__maybe_const_t<_Const, _First>>
8361 && (bidirectional_range<__maybe_const_t<_Const, _Vs>>
8362 && __cartesian_product_common_arg<__maybe_const_t<_Const, _Vs>>));
8364 template<typename _First, typename... _Vs>
8365 concept __cartesian_product_is_common = __cartesian_product_common_arg<_First>;
8367 template<typename... _Vs>
8368 concept __cartesian_product_is_sized = (sized_range<_Vs> && ...);
8370 template<bool _Const, template<typename> class FirstSent, typename _First, typename... _Vs>
8371 concept __cartesian_is_sized_sentinel
8372 = (sized_sentinel_for<FirstSent<__maybe_const_t<_Const, _First>>,
8373 iterator_t<__maybe_const_t<_Const, _First>>>
8375 && (sized_range<__maybe_const_t<_Const, _Vs>>
8376 && sized_sentinel_for<iterator_t<__maybe_const_t<_Const, _Vs>>,
8377 iterator_t<__maybe_const_t<_Const, _Vs>>>));
8379 template<__cartesian_product_common_arg _Range>
8381 __cartesian_common_arg_end(_Range& __r)
8383 if constexpr (common_range<_Range>)
8384 return ranges::end(__r);
8386 return ranges::begin(__r) + ranges::distance(__r);
8388 } // namespace __detail
8390 template<input_range _First, forward_range... _Vs>
8391 requires (view<_First> && ... && view<_Vs>)
8392 class cartesian_product_view : public view_interface<cartesian_product_view<_First, _Vs...>>
8394 tuple<_First, _Vs...> _M_bases;
8396 template<bool> class _Iterator;
8399 _S_difference_type()
8401 // TODO: Implement the recommended practice of using the smallest
8402 // sufficiently wide type according to the maximum sizes of the
8403 // underlying ranges?
8404 return common_type_t<ptrdiff_t,
8405 range_difference_t<_First>,
8406 range_difference_t<_Vs>...>{};
8410 cartesian_product_view() = default;
8413 cartesian_product_view(_First __first, _Vs... __rest)
8414 : _M_bases(std::move(__first), std::move(__rest)...)
8417 constexpr _Iterator<false>
8418 begin() requires (!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8419 { return _Iterator<false>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8421 constexpr _Iterator<true>
8422 begin() const requires (range<const _First> && ... && range<const _Vs>)
8423 { return _Iterator<true>(*this, __detail::__tuple_transform(ranges::begin, _M_bases)); }
8425 constexpr _Iterator<false>
8426 end() requires ((!__detail::__simple_view<_First> || ... || !__detail::__simple_view<_Vs>)
8427 && __detail::__cartesian_product_is_common<_First, _Vs...>)
8429 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8430 using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
8431 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8432 auto& __first = std::get<0>(_M_bases);
8433 return _Ret{(__empty_tail
8434 ? ranges::begin(__first)
8435 : __detail::__cartesian_common_arg_end(__first)),
8436 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8437 }(make_index_sequence<sizeof...(_Vs)>{});
8439 return _Iterator<false>{*this, std::move(__its)};
8442 constexpr _Iterator<true>
8443 end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
8445 auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
8446 using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
8447 bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
8448 auto& __first = std::get<0>(_M_bases);
8449 return _Ret{(__empty_tail
8450 ? ranges::begin(__first)
8451 : __detail::__cartesian_common_arg_end(__first)),
8452 ranges::begin(std::get<1 + _Is>(_M_bases))...};
8453 }(make_index_sequence<sizeof...(_Vs)>{});
8455 return _Iterator<true>{*this, std::move(__its)};
8458 constexpr default_sentinel_t
8459 end() const noexcept
8460 { return default_sentinel; }
8463 size() requires __detail::__cartesian_product_is_sized<_First, _Vs...>
8465 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8466 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8467 auto __size = static_cast<_ST>(1);
8468#ifdef _GLIBCXX_ASSERTIONS
8469 if constexpr (integral<_ST>)
8472 = (__builtin_mul_overflow(__size,
8473 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8476 __glibcxx_assert(!__overflow);
8480 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8482 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8486 size() const requires __detail::__cartesian_product_is_sized<const _First, const _Vs...>
8488 using _ST = __detail::__make_unsigned_like_t<decltype(_S_difference_type())>;
8489 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8490 auto __size = static_cast<_ST>(1);
8491#ifdef _GLIBCXX_ASSERTIONS
8492 if constexpr (integral<_ST>)
8495 = (__builtin_mul_overflow(__size,
8496 static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))),
8499 __glibcxx_assert(!__overflow);
8503 __size = (static_cast<_ST>(ranges::size(std::get<_Is>(_M_bases))) * ...);
8505 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8509 template<typename... _Vs>
8510 cartesian_product_view(_Vs&&...) -> cartesian_product_view<views::all_t<_Vs>...>;
8512 template<input_range _First, forward_range... _Vs>
8513 requires (view<_First> && ... && view<_Vs>)
8514 template<bool _Const>
8515 class cartesian_product_view<_First, _Vs...>::_Iterator
8517 using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
8518 _Parent* _M_parent = nullptr;
8519 tuple<iterator_t<__maybe_const_t<_Const, _First>>,
8520 iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
8523 _Iterator(_Parent& __parent, decltype(_M_current) __current)
8524 : _M_parent(std::__addressof(__parent)),
8525 _M_current(std::move(__current))
8531 if constexpr (__detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>)
8532 return random_access_iterator_tag{};
8533 else if constexpr (__detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>)
8534 return bidirectional_iterator_tag{};
8535 else if constexpr (forward_range<__maybe_const_t<_Const, _First>>)
8536 return forward_iterator_tag{};
8538 return input_iterator_tag{};
8541 friend cartesian_product_view;
8544 using iterator_category = input_iterator_tag;
8545 using iterator_concept = decltype(_S_iter_concept());
8547 = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
8548 range_value_t<__maybe_const_t<_Const, _Vs>>...>;
8550 = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
8551 range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
8552 using difference_type = decltype(cartesian_product_view::_S_difference_type());
8554 _Iterator() = default;
8557 _Iterator(_Iterator<!_Const> __i)
8559 && (convertible_to<iterator_t<_First>, iterator_t<const _First>>
8560 && ... && convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>>)
8561 : _M_parent(std::__addressof(__i._M_parent)),
8562 _M_current(std::move(__i._M_current))
8568 auto __f = [](auto& __i) -> decltype(auto) {
8571 return __detail::__tuple_transform(__f, _M_current);
8574 constexpr _Iterator&
8586 operator++(int) requires forward_range<__maybe_const_t<_Const, _First>>
8593 constexpr _Iterator&
8595 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8603 requires __detail::__cartesian_product_is_bidirectional<_Const, _First, _Vs...>
8610 constexpr _Iterator&
8611 operator+=(difference_type __x)
8612 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8618 constexpr _Iterator&
8619 operator-=(difference_type __x)
8620 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8621 { return *this += -__x; }
8624 operator[](difference_type __n) const
8625 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8626 { return *((*this) + __n); }
8628 friend constexpr bool
8629 operator==(const _Iterator& __x, const _Iterator& __y)
8630 requires equality_comparable<iterator_t<__maybe_const_t<_Const, _First>>>
8631 { return __x._M_current == __y._M_current; }
8633 friend constexpr bool
8634 operator==(const _Iterator& __x, default_sentinel_t)
8636 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8637 return ((std::get<_Is>(__x._M_current)
8638 == ranges::end(std::get<_Is>(__x._M_parent->_M_bases)))
8640 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8643 friend constexpr auto
8644 operator<=>(const _Iterator& __x, const _Iterator& __y)
8645 requires __detail::__all_random_access<_Const, _First, _Vs...>
8646 { return __x._M_current <=> __y._M_current; }
8648 friend constexpr _Iterator
8649 operator+(_Iterator __x, difference_type __y)
8650 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8651 { return __x += __y; }
8653 friend constexpr _Iterator
8654 operator+(difference_type __x, _Iterator __y)
8655 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8656 { return __y += __x; }
8658 friend constexpr _Iterator
8659 operator-(_Iterator __x, difference_type __y)
8660 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8661 { return __x -= __y; }
8663 friend constexpr difference_type
8664 operator-(const _Iterator& __x, const _Iterator& __y)
8665 requires __detail::__cartesian_is_sized_sentinel<_Const, iterator_t, _First, _Vs...>
8666 { return __x._M_distance_from(__y._M_current); }
8668 friend constexpr difference_type
8669 operator-(const _Iterator& __i, default_sentinel_t)
8670 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8672 tuple __end_tuple = [&]<size_t... _Is>(index_sequence<_Is...>) {
8673 return tuple{ranges::end(std::get<0>(__i._M_parent->_M_bases)),
8674 ranges::begin(std::get<1 + _Is>(__i._M_parent->_M_bases))...};
8675 }(make_index_sequence<sizeof...(_Vs)>{});
8676 return __i._M_distance_from(__end_tuple);
8679 friend constexpr difference_type
8680 operator-(default_sentinel_t, const _Iterator& __i)
8681 requires __detail::__cartesian_is_sized_sentinel<_Const, sentinel_t, _First, _Vs...>
8682 { return -(__i - default_sentinel); }
8684 friend constexpr auto
8685 iter_move(const _Iterator& __i)
8686 { return __detail::__tuple_transform(ranges::iter_move, __i._M_current); }
8688 friend constexpr void
8689 iter_swap(const _Iterator& __l, const _Iterator& __r)
8690 requires (indirectly_swappable<iterator_t<__maybe_const_t<_Const, _First>>>
8692 && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
8694 [&]<size_t... _Is>(index_sequence<_Is...>) {
8695 (ranges::iter_swap(std::get<_Is>(__l._M_current), std::get<_Is>(__r._M_current)), ...);
8696 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8700 template<size_t _Nm = sizeof...(_Vs)>
8704 auto& __it = std::get<_Nm>(_M_current);
8706 if constexpr (_Nm > 0)
8707 if (__it == ranges::end(std::get<_Nm>(_M_parent->_M_bases)))
8709 __it = ranges::begin(std::get<_Nm>(_M_parent->_M_bases));
8714 template<size_t _Nm = sizeof...(_Vs)>
8718 auto& __it = std::get<_Nm>(_M_current);
8719 if constexpr (_Nm > 0)
8720 if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
8722 __it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
8728 template<size_t _Nm = sizeof...(_Vs)>
8730 _M_advance(difference_type __x)
8731 requires __detail::__cartesian_product_is_random_access<_Const, _First, _Vs...>
8739 // Constant time iterator advancement.
8740 auto& __r = std::get<_Nm>(_M_parent->_M_bases);
8741 auto& __it = std::get<_Nm>(_M_current);
8742 if constexpr (_Nm == 0)
8744#ifdef _GLIBCXX_ASSERTIONS
8745 if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
8747 auto __size = ranges::ssize(__r);
8748 auto __begin = ranges::begin(__r);
8749 auto __offset = __it - __begin;
8750 __glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
8757 auto __size = ranges::ssize(__r);
8758 auto __begin = ranges::begin(__r);
8759 auto __offset = __it - __begin;
8761 __x = __offset / __size;
8765 __offset = __size + __offset;
8768 __it = __begin + __offset;
8769 _M_advance<_Nm - 1>(__x);
8774 template<typename _Tuple>
8775 constexpr difference_type
8776 _M_distance_from(const _Tuple& __t) const
8778 return [&]<size_t... _Is>(index_sequence<_Is...>) {
8779 auto __sum = static_cast<difference_type>(0);
8780#ifdef _GLIBCXX_ASSERTIONS
8781 if constexpr (integral<difference_type>)
8784 = (__builtin_add_overflow(__sum, _M_scaled_distance<_Is>(__t), &__sum)
8786 __glibcxx_assert(!__overflow);
8790 __sum = (_M_scaled_distance<_Is>(__t) + ...);
8792 }(make_index_sequence<1 + sizeof...(_Vs)>{});
8795 template<size_t _Nm, typename _Tuple>
8796 constexpr difference_type
8797 _M_scaled_distance(const _Tuple& __t) const
8799 auto __dist = static_cast<difference_type>(std::get<_Nm>(_M_current)
8800 - std::get<_Nm>(__t));
8801#ifdef _GLIBCXX_ASSERTIONS
8802 if constexpr (integral<difference_type>)
8804 bool __overflow = __builtin_mul_overflow(__dist, _M_scaled_size<_Nm+1>(), &__dist);
8805 __glibcxx_assert(!__overflow);
8809 __dist *= _M_scaled_size<_Nm+1>();
8813 template<size_t _Nm>
8814 constexpr difference_type
8815 _M_scaled_size() const
8817 if constexpr (_Nm <= sizeof...(_Vs))
8819 auto __size = static_cast<difference_type>(ranges::size
8820 (std::get<_Nm>(_M_parent->_M_bases)));
8821#ifdef _GLIBCXX_ASSERTIONS
8822 if constexpr (integral<difference_type>)
8824 bool __overflow = __builtin_mul_overflow(__size, _M_scaled_size<_Nm+1>(), &__size);
8825 __glibcxx_assert(!__overflow);
8829 __size *= _M_scaled_size<_Nm+1>();
8833 return static_cast<difference_type>(1);
8841 template<typename... _Ts>
8842 concept __can_cartesian_product_view
8843 = requires { cartesian_product_view<all_t<_Ts>...>(std::declval<_Ts>()...); };
8846 struct _CartesianProduct
8848 template<typename... _Ts>
8849 requires (sizeof...(_Ts) == 0 || __detail::__can_cartesian_product_view<_Ts...>)
8851 operator() [[nodiscard]] (_Ts&&... __ts) const
8853 if constexpr (sizeof...(_Ts) == 0)
8854 return views::single(tuple{});
8856 return cartesian_product_view<all_t<_Ts>...>(std::forward<_Ts>(__ts)...);
8860 inline constexpr _CartesianProduct cartesian_product;
8862#endif // __cpp_lib_ranges_cartesian_product
8864#ifdef __cpp_lib_ranges_as_rvalue // C++ >= 23
8865 template<input_range _Vp>
8867 class as_rvalue_view : public view_interface<as_rvalue_view<_Vp>>
8869 _Vp _M_base = _Vp();
8872 as_rvalue_view() requires default_initializable<_Vp> = default;
8875 as_rvalue_view(_Vp __base)
8876 : _M_base(std::move(__base))
8880 base() const& requires copy_constructible<_Vp>
8885 { return std::move(_M_base); }
8888 begin() requires (!__detail::__simple_view<_Vp>)
8889 { return move_iterator(ranges::begin(_M_base)); }
8892 begin() const requires range<const _Vp>
8893 { return move_iterator(ranges::begin(_M_base)); }
8896 end() requires (!__detail::__simple_view<_Vp>)
8898 if constexpr (common_range<_Vp>)
8899 return move_iterator(ranges::end(_M_base));
8901 return move_sentinel(ranges::end(_M_base));
8905 end() const requires range<const _Vp>
8907 if constexpr (common_range<const _Vp>)
8908 return move_iterator(ranges::end(_M_base));
8910 return move_sentinel(ranges::end(_M_base));
8914 size() requires sized_range<_Vp>
8915 { return ranges::size(_M_base); }
8918 size() const requires sized_range<const _Vp>
8919 { return ranges::size(_M_base); }
8922 template<typename _Range>
8923 as_rvalue_view(_Range&&) -> as_rvalue_view<views::all_t<_Range>>;
8925 template<typename _Tp>
8926 inline constexpr bool enable_borrowed_range<as_rvalue_view<_Tp>>
8927 = enable_borrowed_range<_Tp>;
8933 template<typename _Tp>
8934 concept __can_as_rvalue_view = requires { as_rvalue_view(std::declval<_Tp>()); };
8937 struct _AsRvalue : __adaptor::_RangeAdaptorClosure<_AsRvalue>
8939 template<viewable_range _Range>
8940 requires __detail::__can_as_rvalue_view<_Range>
8942 operator() [[nodiscard]] (_Range&& __r) const
8944 if constexpr (same_as<range_rvalue_reference_t<_Range>,
8945 range_reference_t<_Range>>)
8946 return views::all(std::forward<_Range>(__r));
8948 return as_rvalue_view(std::forward<_Range>(__r));
8952 inline constexpr _AsRvalue as_rvalue;
8954#endif // __cpp_lib_as_rvalue
8956#ifdef __cpp_lib_ranges_enumerate // C++ >= 23
8959 template<typename _Range>
8960 concept __range_with_movable_reference = input_range<_Range>
8961 && move_constructible<range_reference_t<_Range>>
8962 && move_constructible<range_rvalue_reference_t<_Range>>;
8966 requires __detail::__range_with_movable_reference<_Vp>
8967 class enumerate_view : public view_interface<enumerate_view<_Vp>>
8969 _Vp _M_base = _Vp();
8971 template<bool _Const> class _Iterator;
8972 template<bool _Const> class _Sentinel;
8975 enumerate_view() requires default_initializable<_Vp> = default;
8978 enumerate_view(_Vp __base)
8979 : _M_base(std::move(__base))
8983 begin() requires (!__detail::__simple_view<_Vp>)
8984 { return _Iterator<false>(ranges::begin(_M_base), 0); }
8987 begin() const requires __detail::__range_with_movable_reference<const _Vp>
8988 { return _Iterator<true>(ranges::begin(_M_base), 0); }
8991 end() requires (!__detail::__simple_view<_Vp>)
8993 if constexpr (common_range<_Vp> && sized_range<_Vp>)
8994 return _Iterator<false>(ranges::end(_M_base), ranges::distance(_M_base));
8996 return _Sentinel<false>(ranges::end(_M_base));
9000 end() const requires __detail::__range_with_movable_reference<const _Vp>
9002 if constexpr (common_range<const _Vp> && sized_range<const _Vp>)
9003 return _Iterator<true>(ranges::end(_M_base), ranges::distance(_M_base));
9005 return _Sentinel<true>(ranges::end(_M_base));
9009 size() requires sized_range<_Vp>
9010 { return ranges::size(_M_base); }
9013 size() const requires sized_range<const _Vp>
9014 { return ranges::size(_M_base); }
9017 base() const & requires copy_constructible<_Vp>
9022 { return std::move(_M_base); }
9025 template<typename _Range>
9026 enumerate_view(_Range&&) -> enumerate_view<views::all_t<_Range>>;
9028 template<typename _Tp>
9029 inline constexpr bool enable_borrowed_range<enumerate_view<_Tp>>
9030 = enable_borrowed_range<_Tp>;
9033 requires __detail::__range_with_movable_reference<_Vp>
9034 template<bool _Const>
9035 class enumerate_view<_Vp>::_Iterator
9037 using _Base = __maybe_const_t<_Const, _Vp>;
9042 if constexpr (random_access_range<_Base>)
9043 return random_access_iterator_tag{};
9044 else if constexpr (bidirectional_range<_Base>)
9045 return bidirectional_iterator_tag{};
9046 else if constexpr (forward_range<_Base>)
9047 return forward_iterator_tag{};
9049 return input_iterator_tag{};
9052 friend enumerate_view;
9055 using iterator_category = input_iterator_tag;
9056 using iterator_concept = decltype(_S_iter_concept());
9057 using difference_type = range_difference_t<_Base>;
9058 using value_type = tuple<difference_type, range_value_t<_Base>>;
9061 using __reference_type = tuple<difference_type, range_reference_t<_Base>>;
9063 iterator_t<_Base> _M_current = iterator_t<_Base>();
9064 difference_type _M_pos = 0;
9067 _Iterator(iterator_t<_Base> __current, difference_type __pos)
9068 : _M_current(std::move(__current)), _M_pos(__pos)
9072 _Iterator() requires default_initializable<iterator_t<_Base>> = default;
9075 _Iterator(_Iterator<!_Const> __i)
9076 requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
9077 : _M_current(std::move(__i._M_current)), _M_pos(__i._M_pos)
9080 constexpr const iterator_t<_Base> &
9081 base() const & noexcept
9082 { return _M_current; }
9084 constexpr iterator_t<_Base>
9086 { return std::move(_M_current); }
9088 constexpr difference_type
9089 index() const noexcept
9094 { return __reference_type(_M_pos, *_M_current); }
9096 constexpr _Iterator&
9109 operator++(int) requires forward_range<_Base>
9116 constexpr _Iterator&
9117 operator--() requires bidirectional_range<_Base>
9125 operator--(int) requires bidirectional_range<_Base>
9132 constexpr _Iterator&
9133 operator+=(difference_type __n) requires random_access_range<_Base>
9140 constexpr _Iterator&
9141 operator-=(difference_type __n) requires random_access_range<_Base>
9149 operator[](difference_type __n) const requires random_access_range<_Base>
9150 { return __reference_type(_M_pos + __n, _M_current[__n]); }
9152 friend constexpr bool
9153 operator==(const _Iterator& __x, const _Iterator& __y) noexcept
9154 { return __x._M_pos == __y._M_pos; }
9156 friend constexpr strong_ordering
9157 operator<=>(const _Iterator& __x, const _Iterator& __y) noexcept
9158 { return __x._M_pos <=> __y._M_pos; }
9160 friend constexpr _Iterator
9161 operator+(const _Iterator& __x, difference_type __y)
9162 requires random_access_range<_Base>
9163 { return (auto(__x) += __y); }
9165 friend constexpr _Iterator
9166 operator+(difference_type __x, const _Iterator& __y)
9167 requires random_access_range<_Base>
9168 { return auto(__y) += __x; }
9170 friend constexpr _Iterator
9171 operator-(const _Iterator& __x, difference_type __y)
9172 requires random_access_range<_Base>
9173 { return auto(__x) -= __y; }
9175 friend constexpr difference_type
9176 operator-(const _Iterator& __x, const _Iterator& __y)
9177 { return __x._M_pos - __y._M_pos; }
9179 friend constexpr auto
9180 iter_move(const _Iterator& __i)
9181 noexcept(noexcept(ranges::iter_move(__i._M_current))
9182 && is_nothrow_move_constructible_v<range_rvalue_reference_t<_Base>>)
9184 return tuple<difference_type, range_rvalue_reference_t<_Base>>
9185 (__i._M_pos, ranges::iter_move(__i._M_current));
9190 requires __detail::__range_with_movable_reference<_Vp>
9191 template<bool _Const>
9192 class enumerate_view<_Vp>::_Sentinel
9194 using _Base = __maybe_const_t<_Const, _Vp>;
9196 sentinel_t<_Base> _M_end = sentinel_t<_Base>();
9199 _Sentinel(sentinel_t<_Base> __end)
9200 : _M_end(std::move(__end))
9203 friend enumerate_view;
9206 _Sentinel() = default;
9209 _Sentinel(_Sentinel<!_Const> __other)
9210 requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
9211 : _M_end(std::move(__other._M_end))
9214 constexpr sentinel_t<_Base>
9218 template<bool _OtherConst>
9219 requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9220 friend constexpr bool
9221 operator==(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9222 { return __x._M_current == __y._M_end; }
9224 template<bool _OtherConst>
9225 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9226 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9227 operator-(const _Iterator<_OtherConst>& __x, const _Sentinel& __y)
9228 { return __x._M_current - __y._M_end; }
9230 template<bool _OtherConst>
9231 requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const_t<_OtherConst, _Vp>>>
9232 friend constexpr range_difference_t<__maybe_const_t<_OtherConst, _Vp>>
9233 operator-(const _Sentinel& __x, const _Iterator<_OtherConst>& __y)
9234 { return __x._M_end - __y._M_current; }
9241 template<typename _Tp>
9242 concept __can_enumerate_view
9243 = requires { enumerate_view<all_t<_Tp>>(std::declval<_Tp>()); };
9246 struct _Enumerate : __adaptor::_RangeAdaptorClosure<_Enumerate>
9248 template<viewable_range _Range>
9249 requires __detail::__can_enumerate_view<_Range>
9251 operator() [[nodiscard]] (_Range&& __r) const
9252 { return enumerate_view<all_t<_Range>>(std::forward<_Range>(__r)); }
9255 inline constexpr _Enumerate enumerate;
9257#endif // __cpp_lib_ranges_enumerate
9259#ifdef __cpp_lib_ranges_as_const // C++ >= 23
9261 requires input_range<_Vp>
9262 class as_const_view : public view_interface<as_const_view<_Vp>>
9264 _Vp _M_base = _Vp();
9267 as_const_view() requires default_initializable<_Vp> = default;
9270 as_const_view(_Vp __base)
9271 noexcept(is_nothrow_move_constructible_v<_Vp>)
9272 : _M_base(std::move(__base))
9277 noexcept(is_nothrow_copy_constructible_v<_Vp>)
9278 requires copy_constructible<_Vp>
9283 noexcept(is_nothrow_move_constructible_v<_Vp>)
9284 { return std::move(_M_base); }
9287 begin() requires (!__detail::__simple_view<_Vp>)
9288 { return ranges::cbegin(_M_base); }
9291 begin() const requires range<const _Vp>
9292 { return ranges::cbegin(_M_base); }
9295 end() requires (!__detail::__simple_view<_Vp>)
9296 { return ranges::cend(_M_base); }
9299 end() const requires range<const _Vp>
9300 { return ranges::cend(_M_base); }
9303 size() requires sized_range<_Vp>
9304 { return ranges::size(_M_base); }
9307 size() const requires sized_range<const _Vp>
9308 { return ranges::size(_M_base); }
9311 template<typename _Range>
9312 as_const_view(_Range&&) -> as_const_view<views::all_t<_Range>>;
9314 template<typename _Tp>
9315 inline constexpr bool enable_borrowed_range<as_const_view<_Tp>>
9316 = enable_borrowed_range<_Tp>;
9322 template<typename _Tp>
9323 inline constexpr bool __is_ref_view = false;
9325 template<typename _Range>
9326 inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
9328 template<typename _Range>
9329 concept __can_as_const_view = requires { as_const_view(std::declval<_Range>()); };
9332 struct _AsConst : __adaptor::_RangeAdaptorClosure<_AsConst>
9334 template<viewable_range _Range>
9336 operator()(_Range&& __r) const
9337 noexcept(noexcept(as_const_view(std::declval<_Range>())))
9338 requires __detail::__can_as_const_view<_Range>
9340 using _Tp = remove_cvref_t<_Range>;
9341 using element_type = remove_reference_t<range_reference_t<_Range>>;
9342 if constexpr (constant_range<views::all_t<_Range>>)
9343 return views::all(std::forward<_Range>(__r));
9344 else if constexpr (__detail::__is_empty_view<_Tp>)
9345 return views::empty<const element_type>;
9346 else if constexpr (std::__detail::__is_span<_Tp>)
9347 return span<const element_type, _Tp::extent>(std::forward<_Range>(__r));
9348 else if constexpr (__detail::__is_ref_view<_Tp>
9349 && constant_range<const element_type>)
9350 return ref_view(static_cast<const element_type&>
9351 (std::forward<_Range>(__r).base()));
9352 else if constexpr (is_lvalue_reference_v<_Range>
9353 && constant_range<const _Tp>
9355 return ref_view(static_cast<const _Tp&>(__r));
9357 return as_const_view(std::forward<_Range>(__r));
9361 inline constexpr _AsConst as_const;
9363#endif // __cpp_lib_as_const
9364} // namespace ranges
9366 namespace views = ranges::views;
9368#if __cpp_lib_ranges_to_container // C++ >= 23
9371/// @cond undocumented
9374 template<typename _Container>
9375 constexpr bool __reservable_container
9376 = sized_range<_Container>
9377 && requires(_Container& __c, range_size_t<_Container> __n) {
9379 { __c.capacity() } -> same_as<decltype(__n)>;
9380 { __c.max_size() } -> same_as<decltype(__n)>;
9383 template<typename _Cont, typename _Range>
9384 constexpr bool __toable = requires {
9385 requires (!input_range<_Cont>
9386 || convertible_to<range_reference_t<_Range>,
9387 range_value_t<_Cont>>);
9389} // namespace __detail
9392 /// Convert a range to a container.
9394 * @tparam _Cont A container type.
9395 * @param __r A range that models the `input_range` concept.
9396 * @param __args... Arguments to pass to the container constructor.
9399 * This function converts a range to the `_Cont` type.
9401 * For example, `std::ranges::to<std::vector<int>>(some_view)`
9402 * will convert the view to `std::vector<int>`.
9404 * Additional constructor arguments for the container can be supplied after
9405 * the input range argument, e.g.
9406 * `std::ranges::to<std::vector<int, Alloc<int>>>(a_range, an_allocator)`.
9408 template<typename _Cont, input_range _Rg, typename... _Args>
9409 requires (!view<_Cont>)
9411 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9413 static_assert(!is_const_v<_Cont> && !is_volatile_v<_Cont>);
9414 static_assert(is_class_v<_Cont>);
9416 if constexpr (__detail::__toable<_Cont, _Rg>)
9418 if constexpr (constructible_from<_Cont, _Rg, _Args...>)
9419 return _Cont(std::forward<_Rg>(__r),
9420 std::forward<_Args>(__args)...);
9421 else if constexpr (constructible_from<_Cont, from_range_t, _Rg, _Args...>)
9422 return _Cont(from_range, std::forward<_Rg>(__r),
9423 std::forward<_Args>(__args)...);
9424 else if constexpr (requires { requires common_range<_Rg>;
9425 typename __iter_category_t<iterator_t<_Rg>>;
9426 requires derived_from<__iter_category_t<iterator_t<_Rg>>,
9427 input_iterator_tag>;
9428 requires constructible_from<_Cont, iterator_t<_Rg>,
9429 sentinel_t<_Rg>, _Args...>;
9431 return _Cont(ranges::begin(__r), ranges::end(__r),
9432 std::forward<_Args>(__args)...);
9435 static_assert(constructible_from<_Cont, _Args...>);
9436 _Cont __c(std::forward<_Args>(__args)...);
9437 if constexpr (sized_range<_Rg>
9438 && __detail::__reservable_container<_Cont>)
9439 __c.reserve(static_cast<range_size_t<_Cont>>(ranges::size(__r)));
9440 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9441 // 4016. container-insertable checks do not match what
9442 // container-inserter does
9443 auto __it = ranges::begin(__r);
9444 const auto __sent = ranges::end(__r);
9445 while (__it != __sent)
9447 if constexpr (requires { __c.emplace_back(*__it); })
9448 __c.emplace_back(*__it);
9449 else if constexpr (requires { __c.push_back(*__it); })
9450 __c.push_back(*__it);
9451 else if constexpr (requires { __c.emplace(__c.end(), *__it); })
9452 __c.emplace(__c.end(), *__it);
9454 __c.insert(__c.end(), *__it);
9462 static_assert(input_range<range_reference_t<_Rg>>);
9463 // _GLIBCXX_RESOLVE_LIB_DEFECTS
9464 // 3984. ranges::to's recursion branch may be ill-formed
9465 return ranges::to<_Cont>(ref_view(__r) | views::transform(
9466 []<typename _Elt>(_Elt&& __elem) {
9467 using _ValT = range_value_t<_Cont>;
9468 return ranges::to<_ValT>(std::forward<_Elt>(__elem));
9469 }), std::forward<_Args>(__args)...);
9473/// @cond undocumented
9476 template<typename _Rg>
9479 using iterator_category = input_iterator_tag;
9480 using value_type = range_value_t<_Rg>;
9481 using difference_type = ptrdiff_t;
9482 using pointer = add_pointer_t<range_reference_t<_Rg>>;
9483 using reference = range_reference_t<_Rg>;
9484 reference operator*() const;
9485 pointer operator->() const;
9486 _InputIter& operator++();
9487 _InputIter operator++(int);
9488 bool operator==(const _InputIter&) const;
9491 template<template<typename...> typename _Cont, input_range _Rg,
9494 = decltype(_Cont(std::declval<_Rg>(), std::declval<_Args>()...));
9496 template<template<typename...> typename _Cont, input_range _Rg,
9499 = decltype(_Cont(from_range, std::declval<_Rg>(),
9500 std::declval<_Args>()...));
9502 template<template<typename...> typename _Cont, input_range _Rg,
9505 = decltype(_Cont(std::declval<_InputIter<_Rg>>(),
9506 std::declval<_InputIter<_Rg>>(),
9507 std::declval<_Args>()...));
9509} // namespace __detail
9512 template<template<typename...> typename _Cont, input_range _Rg,
9515 to [[nodiscard]] (_Rg&& __r, _Args&&... __args)
9517 using __detail::_DeduceExpr1;
9518 using __detail::_DeduceExpr2;
9519 using __detail::_DeduceExpr3;
9520 if constexpr (requires { typename _DeduceExpr1<_Cont, _Rg, _Args...>; })
9521 return ranges::to<_DeduceExpr1<_Cont, _Rg, _Args...>>(
9522 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9523 else if constexpr (requires { typename _DeduceExpr2<_Cont, _Rg, _Args...>; })
9524 return ranges::to<_DeduceExpr2<_Cont, _Rg, _Args...>>(
9525 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9526 else if constexpr (requires { typename _DeduceExpr3<_Cont, _Rg, _Args...>; })
9527 return ranges::to<_DeduceExpr3<_Cont, _Rg, _Args...>>(
9528 std::forward<_Rg>(__r), std::forward<_Args>(__args)...);
9530 static_assert(false); // Cannot deduce container specialization.
9533/// @cond undocumented
9536 template<typename _Cont>
9539 template<typename _Range, typename... _Args>
9540 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9541 std::declval<_Args>()...); }
9543 operator()(_Range&& __r, _Args&&... __args) const
9545 return ranges::to<_Cont>(std::forward<_Range>(__r),
9546 std::forward<_Args>(__args)...);
9549} // namespace __detail
9552 /// ranges::to adaptor for converting a range to a container type
9554 * @tparam _Cont A container type.
9555 * @param __args... Arguments to pass to the container constructor.
9558 * This range adaptor returns a range adaptor closure object that converts
9559 * a range to the `_Cont` type.
9561 * For example, `some_view | std::ranges::to<std::vector<int>>()`
9562 * will convert the view to `std::vector<int>`.
9564 * Additional constructor arguments for the container can be supplied, e.g.
9565 * `r | std::ranges::to<std::vector<int, Alloc<int>>>(an_allocator)`.
9567 template<typename _Cont, typename... _Args>
9568 requires (!view<_Cont>)
9570 to [[nodiscard]] (_Args&&... __args)
9572 using __detail::_To;
9573 using views::__adaptor::_Partial;
9574 return _Partial<_To<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9577/// @cond undocumented
9580 template<template<typename...> typename _Cont>
9583 template<typename _Range, typename... _Args>
9584 requires requires { ranges::to<_Cont>(std::declval<_Range>(),
9585 std::declval<_Args>()...); }
9587 operator()(_Range&& __r, _Args&&... __args) const
9589 return ranges::to<_Cont>(std::forward<_Range>(__r),
9590 std::forward<_Args>(__args)...);
9593} // namespace __detail
9596 /// ranges::to adaptor for converting a range to a deduced container type.
9598 * @tparam _Cont A container template.
9599 * @param __args... Arguments to pass to the container constructor.
9602 * This range adaptor returns a range adaptor closure object that converts
9603 * a range to a specialization of the `_Cont` class template. The specific
9604 * specialization of `_Cont` to be used is deduced automatically.
9606 * For example, `some_view | std::ranges::to<std::vector>(Alloc<int>{})`
9607 * will convert the view to `std::vector<T, Alloc<T>>`, where `T` is the
9608 * view's value type, i.e. `std::ranges::range_value_t<decltype(some_view)>`.
9610 * Additional constructor arguments for the container can be supplied, e.g.
9611 * `r | std::ranges::to<std::vector>(an_allocator)`.
9613 template<template<typename...> typename _Cont, typename... _Args>
9615 to [[nodiscard]] (_Args&&... __args)
9617 using __detail::_To2;
9618 using views::__adaptor::_Partial;
9619 return _Partial<_To2<_Cont>, decay_t<_Args>...>{0, std::forward<_Args>(__args)...};
9622} // namespace ranges
9623#endif // __cpp_lib_ranges_to_container
9625#if __cpp_lib_ranges_concat // C++ >= C++26
9630 template<typename... _Rs>
9631 using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
9633 template<typename... _Rs>
9634 using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
9636 template<typename... _Rs>
9637 using __concat_rvalue_reference_t
9638 = common_reference_t<range_rvalue_reference_t<_Rs>...>;
9640 template<typename _Ref, typename _RRef, typename _It>
9641 concept __concat_indirectly_readable_impl = requires(const _It __it) {
9642 { *__it } -> convertible_to<_Ref>;
9643 { ranges::iter_move(__it) } -> convertible_to<_RRef>;
9646 template<typename... _Rs>
9647 concept __concat_indirectly_readable
9648 = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
9649 && common_reference_with<__concat_reference_t<_Rs...>&&,
9650 __concat_rvalue_reference_t<_Rs...>&&>
9651 && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
9652 __concat_value_t<_Rs...> const&>
9653 && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
9654 __concat_rvalue_reference_t<_Rs...>,
9658 template<typename... _Rs>
9659 concept __concatable = requires {
9660 typename __concat_reference_t<_Rs...>;
9661 typename __concat_value_t<_Rs...>;
9662 typename __concat_rvalue_reference_t<_Rs...>;
9663 } && __concat_indirectly_readable<_Rs...>;
9665 template<bool _Const, typename _Range, typename... _Rs>
9666 struct __all_but_last_common
9668 static inline constexpr bool value
9669 = requires { requires (common_range<__maybe_const_t<_Const, _Range>>
9670 && __all_but_last_common<_Const, _Rs...>::value); };
9673 template<bool _Const, typename _Range>
9674 struct __all_but_last_common<_Const, _Range>
9675 { static inline constexpr bool value = true; };
9677 template<bool _Const, typename... _Rs>
9678 concept __concat_is_random_access = __all_random_access<_Const, _Rs...>
9679 && __all_but_last_common<_Const, _Rs...>::value;
9681 template<bool _Const, typename... _Rs>
9682 concept __concat_is_bidirectional = __all_bidirectional<_Const, _Rs...>
9683 && __all_but_last_common<_Const, _Rs...>::value;
9685 template<typename _Range, typename... _Rs>
9686 struct __all_but_first_sized
9687 { static inline constexpr bool value = (sized_range<_Rs> && ...); };
9688 } // namespace __detail
9690 template<input_range... _Vs>
9691 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9692 class concat_view : public view_interface<concat_view<_Vs...>>
9694 tuple<_Vs...> _M_views;
9696 template<bool _Const> class _Iterator;
9699 constexpr concat_view() = default;
9702 concat_view(_Vs... __views)
9703 : _M_views(std::move(__views)...)
9706 constexpr _Iterator<false>
9707 begin() requires (!(__detail::__simple_view<_Vs> && ...))
9709 _Iterator<false> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9710 __it.template _M_satisfy<0>();
9714 constexpr _Iterator<true>
9715 begin() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9717 _Iterator<true> __it(this, in_place_index<0>, ranges::begin(std::get<0>(_M_views)));
9718 __it.template _M_satisfy<0>();
9723 end() requires (!(__detail::__simple_view<_Vs> && ...))
9725 constexpr auto __n = sizeof...(_Vs);
9726 if constexpr ((semiregular<iterator_t<_Vs>> && ...)
9727 && common_range<_Vs...[__n - 1]>)
9728 return _Iterator<false>(this, in_place_index<__n - 1>,
9729 ranges::end(std::get<__n - 1>(_M_views)));
9731 return default_sentinel;
9735 end() const requires (range<const _Vs> && ...) && __detail::__concatable<const _Vs...>
9737 constexpr auto __n = sizeof...(_Vs);
9738 if constexpr ((semiregular<iterator_t<const _Vs>> && ...)
9739 && common_range<const _Vs...[__n - 1]>)
9740 return _Iterator<true>(this, in_place_index<__n - 1>,
9741 ranges::end(std::get<__n - 1>(_M_views)));
9743 return default_sentinel;
9747 size() requires (sized_range<_Vs>&&...)
9749 return std::apply([](auto... __sizes) {
9750 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9751 return (_CT(__sizes) + ...);
9752 }, __detail::__tuple_transform(ranges::size, _M_views));
9756 size() const requires (sized_range<const _Vs>&&...)
9758 return std::apply([](auto... __sizes) {
9759 using _CT = __detail::__make_unsigned_like_t<common_type_t<decltype(__sizes)...>>;
9760 return (_CT(__sizes) + ...);
9761 }, __detail::__tuple_transform(ranges::size, _M_views));
9765 template<typename... _Rs>
9766 concat_view(_Rs&&...) -> concat_view<views::all_t<_Rs>...>;
9770 template<bool _Const, typename... _Vs>
9771 struct __concat_view_iter_cat
9774 template<bool _Const, typename... _Vs>
9775 requires __detail::__all_forward<_Const, _Vs...>
9776 struct __concat_view_iter_cat<_Const, _Vs...>
9781 if constexpr (!is_reference_v<__concat_reference_t<__maybe_const_t<_Const, _Vs>...>>)
9782 return input_iterator_tag{};
9784 return []<typename... _Cats>(_Cats... __cats) {
9785 if constexpr ((derived_from<_Cats, random_access_iterator_tag> && ...)
9786 && __concat_is_random_access<_Const, _Vs...>)
9787 return random_access_iterator_tag{};
9788 else if constexpr ((derived_from<_Cats, bidirectional_iterator_tag> && ...)
9789 && __concat_is_bidirectional<_Const, _Vs...>)
9790 return bidirectional_iterator_tag{};
9791 else if constexpr ((derived_from<_Cats, forward_iterator_tag> && ...))
9792 return forward_iterator_tag{};
9794 return input_iterator_tag{};
9795 }(typename iterator_traits<iterator_t<__maybe_const_t<_Const, _Vs>>>
9796 ::iterator_category{}...);
9801 template<input_range... _Vs>
9802 requires (view<_Vs> && ...) && (sizeof...(_Vs) > 0) && __detail::__concatable<_Vs...>
9803 template<bool _Const>
9804 class concat_view<_Vs...>::_Iterator
9805 : public __detail::__concat_view_iter_cat<_Const, _Vs...>
9810 if constexpr (__detail::__concat_is_random_access<_Const, _Vs...>)
9811 return random_access_iterator_tag{};
9812 else if constexpr (__detail::__concat_is_bidirectional<_Const, _Vs...>)
9813 return bidirectional_iterator_tag{};
9814 else if constexpr (__detail::__all_forward<_Const, _Vs...>)
9815 return forward_iterator_tag{};
9817 return input_iterator_tag{};
9821 friend _Iterator<!_Const>;
9824 // iterator_category defined in __concat_view_iter_cat
9825 using iterator_concept = decltype(_S_iter_concept());
9826 using value_type = __detail::__concat_value_t<__maybe_const_t<_Const, _Vs>...>;
9827 using difference_type = common_type_t<range_difference_t<__maybe_const_t<_Const, _Vs>>...>;
9830 using __base_iter = variant<iterator_t<__maybe_const_t<_Const, _Vs>>...>;
9832 __maybe_const_t<_Const, concat_view>* _M_parent = nullptr;
9835 template<size_t _Nm>
9839 if constexpr (_Nm < (sizeof...(_Vs) - 1))
9841 if (std::get<_Nm>(_M_it) == ranges::end(std::get<_Nm>(_M_parent->_M_views)))
9843 _M_it.template emplace<_Nm + 1>(ranges::begin
9844 (std::get<_Nm + 1>(_M_parent->_M_views)));
9845 _M_satisfy<_Nm + 1>();
9850 template<size_t _Nm>
9854 if constexpr (_Nm == 0)
9855 --std::get<0>(_M_it);
9858 if (std::get<_Nm>(_M_it) == ranges::begin(std::get<_Nm>(_M_parent->_M_views)))
9860 _M_it.template emplace<_Nm - 1>(ranges::end
9861 (std::get<_Nm - 1>(_M_parent->_M_views)));
9865 --std::get<_Nm>(_M_it);
9869 template<size_t _Nm>
9871 _M_advance_fwd(difference_type __offset, difference_type __steps)
9873 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9874 if constexpr (_Nm == sizeof...(_Vs) - 1)
9875 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9878 auto __n_size = ranges::distance(std::get<_Nm>(_M_parent->_M_views));
9879 if (__offset + __steps < __n_size)
9880 std::get<_Nm>(_M_it) += static_cast<_Dt>(__steps);
9883 _M_it.template emplace<_Nm + 1>(ranges::begin
9884 (std::get<_Nm + 1>(_M_parent->_M_views)));
9885 _M_advance_fwd<_Nm + 1>(0, __offset + __steps - __n_size);
9890 template<size_t _Nm>
9892 _M_advance_bwd(difference_type __offset, difference_type __steps)
9894 using _Dt = iter_difference_t<variant_alternative_t<_Nm, __base_iter>>;
9895 if constexpr (_Nm == 0)
9896 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9898 if (__offset >= __steps)
9899 std::get<_Nm>(_M_it) -= static_cast<_Dt>(__steps);
9902 auto __prev_size = ranges::distance(std::get<_Nm - 1>(_M_parent->_M_views));
9903 _M_it.template emplace<_Nm - 1>(ranges::end
9904 (std::get<_Nm - 1>(_M_parent->_M_views)));
9905 _M_advance_bwd<_Nm - 1>(__prev_size, __steps - __offset);
9910 // Invoke the function object __f, which has a call operator with a size_t
9911 // template parameter (corresponding to an index into the pack of views),
9912 // using the runtime value of __index as the template argument.
9913 template<typename _Fp>
9914 static constexpr auto
9915 _S_invoke_with_runtime_index(_Fp&& __f, size_t __index)
9917 return [&__f, __index]<size_t _Idx>(this auto&& __self) {
9918 if (_Idx == __index)
9919 return __f.template operator()<_Idx>();
9920 if constexpr (_Idx + 1 < sizeof...(_Vs))
9921 return __self.template operator()<_Idx + 1>();
9922 }.template operator()<0>();
9925 template<typename _Fp>
9927 _M_invoke_with_runtime_index(_Fp&& __f)
9928 { return _S_invoke_with_runtime_index(std::forward<_Fp>(__f), _M_it.index()); }
9930 template<typename... _Args>
9932 _Iterator(__maybe_const_t<_Const, concat_view>* __parent, _Args&&... __args)
9933 requires constructible_from<__base_iter, _Args&&...>
9934 : _M_parent(__parent), _M_it(std::forward<_Args>(__args)...)
9938 _Iterator() = default;
9941 _Iterator(_Iterator<!_Const> __it)
9942 requires _Const && (convertible_to<iterator_t<_Vs>, iterator_t<const _Vs>> && ...)
9943 : _M_parent(__it._M_parent)
9945 _M_invoke_with_runtime_index([this, &__it]<size_t _Idx>() {
9946 _M_it.template emplace<_Idx>(std::get<_Idx>(std::move(__it._M_it)));
9950 constexpr decltype(auto)
9953 __glibcxx_assert(!_M_it.valueless_by_exception());
9954 using reference = __detail::__concat_reference_t<__maybe_const_t<_Const, _Vs>...>;
9955 return std::visit([](auto&& __it) -> reference { return *__it; }, _M_it);
9958 constexpr _Iterator&
9961 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9962 ++std::get<_Idx>(_M_it);
9974 requires __detail::__all_forward<_Const, _Vs...>
9981 constexpr _Iterator&
9983 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
9985 __glibcxx_assert(!_M_it.valueless_by_exception());
9986 _M_invoke_with_runtime_index([this]<size_t _Idx>() {
9994 requires __detail::__concat_is_bidirectional<_Const, _Vs...>
10001 constexpr _Iterator&
10002 operator+=(difference_type __n)
10003 requires __detail::__concat_is_random_access<_Const, _Vs...>
10005 __glibcxx_assert(!_M_it.valueless_by_exception());
10006 _M_invoke_with_runtime_index([this, __n]<size_t _Idx>() {
10007 auto __begin = ranges::begin(std::get<_Idx>(_M_parent->_M_views));
10009 _M_advance_fwd<_Idx>(std::get<_Idx>(_M_it) - __begin, __n);
10011 _M_advance_bwd<_Idx>(std::get<_Idx>(_M_it) - __begin, -__n);
10016 constexpr _Iterator&
10017 operator-=(difference_type __n)
10018 requires __detail::__concat_is_random_access<_Const, _Vs...>
10024 constexpr decltype(auto)
10025 operator[](difference_type __n) const
10026 requires __detail::__concat_is_random_access<_Const, _Vs...>
10027 { return *((*this) + __n); }
10029 friend constexpr bool
10030 operator==(const _Iterator& __x, const _Iterator& __y)
10031 requires (equality_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10033 __glibcxx_assert(!__x._M_it.valueless_by_exception());
10034 __glibcxx_assert(!__y._M_it.valueless_by_exception());
10035 return __x._M_it == __y._M_it;
10038 friend constexpr bool
10039 operator==(const _Iterator& __it, default_sentinel_t)
10041 __glibcxx_assert(!__it._M_it.valueless_by_exception());
10042 constexpr auto __last_idx = sizeof...(_Vs) - 1;
10043 return (__it._M_it.index() == __last_idx
10044 && (std::get<__last_idx>(__it._M_it)
10045 == ranges::end(std::get<__last_idx>(__it._M_parent->_M_views))));
10048 friend constexpr bool
10049 operator<(const _Iterator& __x, const _Iterator& __y)
10050 requires __detail::__all_random_access<_Const, _Vs...>
10051 { return __x._M_it < __y._M_it; }
10053 friend constexpr bool
10054 operator>(const _Iterator& __x, const _Iterator& __y)
10055 requires __detail::__all_random_access<_Const, _Vs...>
10056 { return __x._M_it > __y._M_it; }
10058 friend constexpr bool
10059 operator<=(const _Iterator& __x, const _Iterator& __y)
10060 requires __detail::__all_random_access<_Const, _Vs...>
10061 { return __x._M_it <= __y._M_it; }
10063 friend constexpr bool
10064 operator>=(const _Iterator& __x, const _Iterator& __y)
10065 requires __detail::__all_random_access<_Const, _Vs...>
10066 { return __x._M_it >= __y._M_it; }
10068 friend constexpr auto
10069 operator<=>(const _Iterator& __x, const _Iterator& __y)
10070 requires __detail::__all_random_access<_Const, _Vs...>
10071 && (three_way_comparable<iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10072 { return __x._M_it <=> __y._M_it; }
10074 friend constexpr _Iterator
10075 operator+(const _Iterator& __it, difference_type __n)
10076 requires __detail::__concat_is_random_access<_Const, _Vs...>
10077 { return auto(__it) += __n; }
10079 friend constexpr _Iterator
10080 operator+(difference_type __n, const _Iterator& __it)
10081 requires __detail::__concat_is_random_access<_Const, _Vs...>
10082 { return __it + __n; }
10084 friend constexpr _Iterator
10085 operator-(const _Iterator& __it, difference_type __n)
10086 requires __detail::__concat_is_random_access<_Const, _Vs...>
10087 { return auto(__it) -= __n; }
10089 friend constexpr difference_type
10090 operator-(const _Iterator& __x, const _Iterator& __y)
10091 requires __detail::__concat_is_random_access<_Const, _Vs...>
10093 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10094 return _S_invoke_with_runtime_index([&]<size_t _Iy>() -> difference_type {
10095 if constexpr (_Ix > _Iy)
10097 auto __dy = ranges::distance(std::get<_Iy>(__y._M_it),
10098 ranges::end(std::get<_Iy>(__y._M_parent
10100 auto __dx = ranges::distance(ranges::begin(std::get<_Ix>(__x._M_parent
10102 std::get<_Ix>(__x._M_it));
10103 difference_type __s = 0;
10104 [&]<size_t _Idx = _Iy + 1>(this auto&& __self) {
10105 if constexpr (_Idx < _Ix)
10107 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10108 __self.template operator()<_Idx + 1>();
10111 return __dy + __s + __dx;
10113 else if constexpr (_Ix < _Iy)
10114 return -(__y - __x);
10116 return std::get<_Ix>(__x._M_it) - std::get<_Iy>(__y._M_it);
10117 }, __y._M_it.index());
10118 }, __x._M_it.index());
10121 friend constexpr difference_type
10122 operator-(const _Iterator& __x, default_sentinel_t)
10123 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10124 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10125 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10127 return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> difference_type {
10128 auto __dx = ranges::distance(std::get<_Ix>(__x._M_it),
10129 ranges::end(std::get<_Ix>(__x._M_parent->_M_views)));
10130 difference_type __s = 0;
10131 [&]<size_t _Idx = _Ix + 1>(this auto&& __self) {
10132 if constexpr (_Idx < sizeof...(_Vs))
10134 __s += ranges::size(std::get<_Idx>(__x._M_parent->_M_views));
10135 __self.template operator()<_Idx + 1>();
10138 return -(__dx + __s);
10139 }, __x._M_it.index());
10142 friend constexpr difference_type
10143 operator-(default_sentinel_t, const _Iterator& __x)
10144 requires (sized_sentinel_for<sentinel_t<__maybe_const_t<_Const, _Vs>>,
10145 iterator_t<__maybe_const_t<_Const, _Vs>>> && ...)
10146 && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value
10147 { return -(__x - default_sentinel); }
10149 friend constexpr decltype(auto)
10150 iter_move(const _Iterator& __it)
10152 using _Res = __detail::__concat_rvalue_reference_t<__maybe_const_t<_Const, _Vs>...>;
10153 return std::visit([](const auto& __i) -> _Res {
10154 return ranges::iter_move(__i);
10158 friend constexpr void
10159 iter_swap(const _Iterator& __x, const _Iterator& __y)
10160 requires swappable_with<iter_reference_t<_Iterator>, iter_reference_t<_Iterator>>
10161 && (... && indirectly_swappable<iterator_t<__maybe_const_t<_Const, _Vs>>>)
10163 std::visit([&]<typename _Tp, typename _Up>(const _Tp& __it1, const _Up& __it2) {
10164 if constexpr (is_same_v<_Tp, _Up>)
10165 ranges::iter_swap(__it1, __it2);
10167 ranges::swap(*__it1, *__it2);
10168 }, __x._M_it, __y._M_it);
10176 template<typename... _Ts>
10177 concept __can_concat_view = requires { concat_view(std::declval<_Ts>()...); };
10182 template<typename... _Ts>
10183 requires __detail::__can_concat_view<_Ts...>
10185 operator() [[nodiscard]] (_Ts&&... __ts) const
10187 if constexpr (sizeof...(_Ts) == 1)
10188 return views::all(std::forward<_Ts>(__ts)...);
10190 return concat_view(std::forward<_Ts>(__ts)...);
10194 inline constexpr _Concat concat;
10197} // namespace ranges
10198#endif // __cpp_lib_ranges_concat
10200_GLIBCXX_END_NAMESPACE_VERSION
10202#endif // library concepts
10204#endif /* _GLIBCXX_RANGES */